OSDN Git Service

Updates for expanded storage.
authorJeff Sharkey <jsharkey@android.com>
Mon, 6 Apr 2015 21:08:45 +0000 (14:08 -0700)
committerJeff Sharkey <jsharkey@android.com>
Tue, 7 Apr 2015 00:41:30 +0000 (17:41 -0700)
Mount private volumes at /mnt/expand, which is where we have new
SELinux policy waiting for us.  Also ensure that foundational
directories are ready when mounting.

Create local fs_prepare_dir() wrapper that sets SELinux context
based on path, avoiding the need for a later restorecon.

Use UUID as directory name for public volumes.  Wait a few seconds
before issuing first signal when force unmounting.

Bug: 19993667
Change-Id: If22595380faaae321705b06c87d877419620da48

PrivateVolume.cpp
PublicVolume.cpp
Utils.cpp
Utils.h

index 42eea64..f652c6b 100644 (file)
@@ -43,7 +43,6 @@ PrivateVolume::PrivateVolume(dev_t device, const std::string& keyRaw) :
         VolumeBase(Type::kPrivate), mRawDevice(device), mKeyRaw(keyRaw) {
     setId(StringPrintf("private:%u,%u", major(device), minor(device)));
     mRawDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str());
-    mPath = StringPrintf("/mnt/secure/%s", getId().c_str());
 }
 
 PrivateVolume::~PrivateVolume() {
@@ -101,16 +100,17 @@ status_t PrivateVolume::doMount() {
         return -EIO;
     }
 
-    if (Ext4::check(mDmDevPath.c_str(), mPath.c_str())) {
-        PLOG(ERROR) << getId() << " failed filesystem check";
-        return -EIO;
-    }
-
+    mPath = StringPrintf("/mnt/expand/%s", mFsUuid.c_str());
     setPath(mPath);
 
-    if (fs_prepare_dir(mPath.c_str(), 0700, AID_ROOT, AID_ROOT)) {
+    if (PrepareDir(mPath, 0700, AID_ROOT, AID_ROOT)) {
         PLOG(ERROR) << getId() << " failed to create mount point " << mPath;
-        return -errno;
+        return -EIO;
+    }
+
+    if (Ext4::check(mDmDevPath.c_str(), mPath.c_str())) {
+        PLOG(ERROR) << getId() << " failed filesystem check";
+        return -EIO;
     }
 
     if (Ext4::doMount(mDmDevPath.c_str(), mPath.c_str(), false, false, true)) {
@@ -118,6 +118,16 @@ status_t PrivateVolume::doMount() {
         return -EIO;
     }
 
+    // Verify that common directories are ready to roll
+    if (PrepareDir(mPath + "/app", 0771, AID_SYSTEM, AID_SYSTEM) ||
+            PrepareDir(mPath + "/user", 0711, AID_SYSTEM, AID_SYSTEM) ||
+            PrepareDir(mPath + "/media", 0770, AID_MEDIA_RW, AID_MEDIA_RW) ||
+            PrepareDir(mPath + "/local", 0751, AID_ROOT, AID_ROOT) ||
+            PrepareDir(mPath + "/local/tmp", 0771, AID_SHELL, AID_SHELL)) {
+        PLOG(ERROR) << getId() << " failed to prepare";
+        return -EIO;
+    }
+
     return OK;
 }
 
index ffcfc67..6192e7a 100644 (file)
@@ -110,7 +110,7 @@ status_t PublicVolume::doMount() {
     // Use UUID as stable name, if available
     std::string stableName = getId();
     if (!mFsUuid.empty()) {
-        stableName = "public:" + mFsUuid;
+        stableName = mFsUuid;
     }
 
     mRawPath = StringPrintf("/mnt/media_rw/%s", stableName.c_str());
index 2b02f91..1937c28 100644 (file)
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -85,26 +85,53 @@ status_t DestroyDeviceNode(const std::string& path) {
     }
 }
 
+status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid) {
+    const char* cpath = path.c_str();
+
+    char* secontext = nullptr;
+    if (sehandle) {
+        if (!selabel_lookup(sehandle, &secontext, cpath, S_IFDIR)) {
+            setfscreatecon(secontext);
+        }
+    }
+
+    int res = fs_prepare_dir(cpath, mode, uid, gid);
+
+    if (secontext) {
+        setfscreatecon(nullptr);
+        freecon(secontext);
+    }
+
+    if (res == 0) {
+        return OK;
+    } else {
+        return -errno;
+    }
+}
+
 status_t ForceUnmount(const std::string& path) {
     const char* cpath = path.c_str();
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
         return OK;
     }
-    PLOG(WARNING) << "Failed to unmount " << path << "; sending SIGTERM";
-    Process::killProcessesWithOpenFiles(cpath, SIGTERM);
+    PLOG(WARNING) << "Failed to unmount " << path;
+
     sleep(5);
+    Process::killProcessesWithOpenFiles(cpath, SIGTERM);
 
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
         return OK;
     }
-    PLOG(WARNING) << "Failed to unmount " << path << "; sending SIGKILL";
-    Process::killProcessesWithOpenFiles(cpath, SIGKILL);
+    PLOG(WARNING) << "Failed to unmount " << path;
+
     sleep(5);
+    Process::killProcessesWithOpenFiles(cpath, SIGKILL);
 
     if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) {
         return OK;
     }
-    PLOG(ERROR) << "Failed to unmount " << path << "; giving up";
+    PLOG(ERROR) << "Failed to unmount " << path;
+
     return -errno;
 }
 
diff --git a/Utils.h b/Utils.h
index 9e366e6..a6e1747 100644 (file)
--- a/Utils.h
+++ b/Utils.h
@@ -43,6 +43,9 @@ extern security_context_t sFsckUntrustedContext;
 status_t CreateDeviceNode(const std::string& path, dev_t dev);
 status_t DestroyDeviceNode(const std::string& path);
 
+/* fs_prepare_dir wrapper that creates with SELinux context */
+status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
+
 /* Really unmounts the path, killing active processes along the way */
 status_t ForceUnmount(const std::string& path);