Exclusive exec() path, format after partition.

Sadly setexeccon() is process global, so we need to carefully ensure
that all exec() are mutually exclusive to avoid transitioning into
unwanted domains.  Also, because we have several threads floating
around, we need to guard all our FDs with O_CLOEXEC.

Format all newly created volumes immediately after partitioning,
but silence all events emitted from those volumes to prevent the
framework from getting all excited.  Unify all notify events under a
single codepath to make them easy to silence.

Sent SIGINT before escalating to SIGTERM when unmounting.

Bug: 19993667
Change-Id: Idc6c806afc7919a004a93e2240b42884f6b52d6b
diff --git a/Ext4.cpp b/Ext4.cpp
index 7316234..a208eb5 100644
--- a/Ext4.cpp
+++ b/Ext4.cpp
@@ -48,14 +48,11 @@
 #include "Utils.h"
 #include "VoldUtil.h"
 
-#define RESIZE2FS_PATH "/system/bin/resize2fs"
-
 using android::base::StringPrintf;
 
+static const char* kResizefsPath = "/system/bin/resize2fs";
 static const char* kMkfsPath = "/system/bin/make_ext4fs";
-
 static const char* kFsckPath = "/system/bin/e2fsck";
-static const char* kFsckLogFile = "/dev/fscklogs/log";
 
 int Ext4::check(const char *fsPath, const char *mountPoint) {
     // The following is shamelessly borrowed from fs_mgr.c, so it should be
@@ -68,11 +65,6 @@
     int ret;
     long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
     char *tmpmnt_opts = (char*) "nomblk_io_submit,errors=remount-ro";
-    char *e2fsck_argv[] = {
-        (char*) kFsckPath,
-        (char*) "-y",
-        blk_device
-    };
 
     /*
      * First try to mount and unmount the filesystem.  We do this because
@@ -112,23 +104,13 @@
     } else {
         ALOGD("Running %s on %s\n", kFsckPath, blk_device);
 
-        // Ext4 devices are currently always trusted
-        if (setexeccon(android::vold::sFsckContext)) {
-            LOG(ERROR) << "Failed to setexeccon()";
-            errno = EPERM;
-            return -1;
-        }
-        ret = android_fork_execvp(ARRAY_SIZE(e2fsck_argv), e2fsck_argv,
-                                    &status, false, true);
-        if (setexeccon(NULL)) {
-            abort();
-        }
+        std::vector<std::string> cmd;
+        cmd.push_back(kFsckPath);
+        cmd.push_back("-y");
+        cmd.push_back(blk_device);
 
-        if (ret < 0) {
-            /* No need to check for error in fork, we can't really handle it now */
-            ALOGW("Failed trying to run %s\n", kFsckPath);
-            return -1;
-        }
+        // Ext4 devices are currently always trusted
+        return android::vold::ForkExecvp(cmd, android::vold::sFsckContext);
     }
 
     return 0;
@@ -157,51 +139,16 @@
 }
 
 int Ext4::resize(const char *fspath, unsigned int numSectors) {
-    const char *args[4];
-    char* size_str;
-    int rc;
-    int status;
+    std::vector<std::string> cmd;
+    cmd.push_back(kResizefsPath);
+    cmd.push_back("-f");
+    cmd.push_back(fspath);
+    cmd.push_back(StringPrintf("%u", numSectors));
 
-    args[0] = RESIZE2FS_PATH;
-    args[1] = "-f";
-    args[2] = fspath;
-    if (asprintf(&size_str, "%ds", numSectors) < 0)
-    {
-      SLOGE("Filesystem (ext4) resize failed to set size");
-      return -1;
-    }
-    args[3] = size_str;
-    rc = android_fork_execvp(ARRAY_SIZE(args), (char **)args, &status, false,
-            true);
-    free(size_str);
-    if (rc != 0) {
-        SLOGE("Filesystem (ext4) resize failed due to logwrap error");
-        errno = EIO;
-        return -1;
-    }
-
-    if (!WIFEXITED(status)) {
-        SLOGE("Filesystem (ext4) resize did not exit properly");
-        errno = EIO;
-        return -1;
-    }
-
-    status = WEXITSTATUS(status);
-
-    if (status == 0) {
-        SLOGI("Filesystem (ext4) resized OK");
-        return 0;
-    } else {
-        SLOGE("Resize (ext4) failed (unknown exit code %d)", status);
-        errno = EIO;
-        return -1;
-    }
-    return 0;
+    return android::vold::ForkExecvp(cmd);
 }
 
 int Ext4::format(const char *fsPath, unsigned int numSectors, const char *mountpoint) {
-    int status;
-
     std::vector<std::string> cmd;
     cmd.push_back(kMkfsPath);
     cmd.push_back("-J");
@@ -214,30 +161,9 @@
         cmd.push_back(StringPrintf("%u", numSectors * 512));
     }
 
+    // Always generate a real UUID
+    cmd.push_back("-u");
     cmd.push_back(fsPath);
 
-    int rc = android::vold::ForkExecvp(cmd, &status, false, true);
-    if (rc != 0) {
-        SLOGE("Filesystem (ext4) format failed due to logwrap error");
-        errno = EIO;
-        return -1;
-    }
-
-    if (!WIFEXITED(status)) {
-        SLOGE("Filesystem (ext4) format did not exit properly");
-        errno = EIO;
-        return -1;
-    }
-
-    status = WEXITSTATUS(status);
-
-    if (status == 0) {
-        SLOGI("Filesystem (ext4) formatted OK");
-        return 0;
-    } else {
-        SLOGE("Format (ext4) failed (unknown exit code %d)", status);
-        errno = EIO;
-        return -1;
-    }
-    return 0;
+    return android::vold::ForkExecvp(cmd);
 }