Conditionally use sdcardfs.

In preparation of sdcardfs going away on devices launching with R,
conditionally use it.

Bug: 146419093
Test: cuttlefish with sdcardfs, cuttlefish without sdcardfs but with
FUSE
Change-Id: I2c1d4b428dcb43c3fd274dde84d5088984161993
diff --git a/Utils.cpp b/Utils.cpp
index 67c48ad..0375765 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -1017,9 +1017,6 @@
     std::string pass_through_path(
             StringPrintf("%s/%s", pre_pass_through_path.c_str(), relative_upper_path.c_str()));
 
-    std::string sdcardfs_path(
-            StringPrintf("/mnt/runtime/full/%s", relative_upper_path.c_str()));
-
     // Create directories.
     auto result = PrepareDir(pre_fuse_path, 0700, AID_ROOT, AID_ROOT);
     if (result != android::OK) {
@@ -1081,8 +1078,16 @@
         return -errno;
     }
 
-    LOG(INFO) << "Bind mounting " << sdcardfs_path << " to " << pass_through_path;
-    return BindMount(sdcardfs_path, pass_through_path);
+    if (IsFilesystemSupported("sdcardfs")) {
+        std::string sdcardfs_path(
+                StringPrintf("/mnt/runtime/full/%s", relative_upper_path.c_str()));
+
+        LOG(INFO) << "Bind mounting " << sdcardfs_path << " to " << pass_through_path;
+        return BindMount(sdcardfs_path, pass_through_path);
+    } else {
+        LOG(INFO) << "Bind mounting " << absolute_lower_path << " to " << pass_through_path;
+        return BindMount(absolute_lower_path, pass_through_path);
+    }
 }
 
 status_t UnmountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
diff --git a/model/EmulatedVolume.cpp b/model/EmulatedVolume.cpp
index aef7b77..d7b22e3 100644
--- a/model/EmulatedVolume.cpp
+++ b/model/EmulatedVolume.cpp
@@ -48,6 +48,7 @@
     mRawPath = rawPath;
     mLabel = "emulated";
     mFuseMounted = false;
+    mUseSdcardFs = IsFilesystemSupported("sdcardfs");
 }
 
 EmulatedVolume::EmulatedVolume(const std::string& rawPath, dev_t device, const std::string& fsUuid,
@@ -57,6 +58,7 @@
     mRawPath = rawPath;
     mLabel = fsUuid;
     mFuseMounted = false;
+    mUseSdcardFs = IsFilesystemSupported("sdcardfs");
 }
 
 EmulatedVolume::~EmulatedVolume() {}
@@ -71,18 +73,23 @@
     }
 }
 
-static status_t mountFuseBindMounts(int userId, const std::string& label) {
-    // TODO(b/134706060) we don't actually want to mount the "write" view by
-    // default, since it gives write access to all OBB dirs.
-    std::string androidSource(
-            StringPrintf("/mnt/runtime/default/%s/%d/Android", label.c_str(), userId));
+status_t EmulatedVolume::mountFuseBindMounts() {
+    std::string androidSource;
+    std::string label = getLabel();
+    int userId = getMountUserId();
+
+    if (mUseSdcardFs) {
+        androidSource = StringPrintf("/mnt/runtime/default/%s/%d/Android", label.c_str(), userId);
+    } else {
+        androidSource = StringPrintf("/%s/%d/Android", mRawPath.c_str(), userId);
+    }
     std::string androidTarget(
             StringPrintf("/mnt/user/%d/%s/%d/Android", userId, label.c_str(), userId));
 
     if (access(androidSource.c_str(), F_OK) != 0) {
         // Android path may not exist yet if users has just been created; create it on
         // the lower fs.
-        if (fs_prepare_dir(androidSource.c_str(), 0771, AID_ROOT, AID_ROOT) != 0) {
+        if (fs_prepare_dir(androidSource.c_str(), 0771, AID_MEDIA_RW, AID_MEDIA_RW) != 0) {
             PLOG(ERROR) << "Failed to create " << androidSource;
             return -errno;
         }
@@ -97,7 +104,10 @@
     return OK;
 }
 
-static status_t unmountFuseBindMounts(int userId, const std::string& label) {
+status_t EmulatedVolume::unmountFuseBindMounts() {
+    std::string label = getLabel();
+    int userId = getMountUserId();
+
     std::string androidTarget(
             StringPrintf("/mnt/user/%d/%s/%d/Android", userId, label.c_str(), userId));
 
@@ -137,7 +147,7 @@
 
     // Mount sdcardfs regardless of FUSE, since we need it to bind-mount on top of the
     // FUSE volume for various reasons.
-    if (getMountUserId() == 0) {
+    if (mUseSdcardFs && getMountUserId() == 0) {
         LOG(INFO) << "Executing sdcardfs";
         int sdcardFsPid;
         if (!(sdcardFsPid = fork())) {
@@ -203,7 +213,7 @@
         }
 
         // Only do the bind-mounts when we know for sure the FUSE daemon can resolve the path.
-        return mountFuseBindMounts(user_id, label);
+        return mountFuseBindMounts();
     }
 
     return OK;
@@ -231,7 +241,7 @@
         // Ignoring unmount return status because we do want to try to unmount
         // the rest cleanly.
 
-        unmountFuseBindMounts(userId, label);
+        unmountFuseBindMounts();
         if (UnmountUserFuse(userId, getInternalPath(), label) != OK) {
             PLOG(INFO) << "UnmountUserFuse failed on emulated fuse volume";
             return -errno;
@@ -239,7 +249,7 @@
 
         mFuseMounted = false;
     }
-    if (getMountUserId() != 0) {
+    if (getMountUserId() != 0 || !mUseSdcardFs) {
         // For sdcardfs, only unmount for user 0, since user 0 will always be running
         // and the paths don't change for different users.
         return OK;
diff --git a/model/EmulatedVolume.h b/model/EmulatedVolume.h
index 131761c..4f76a60 100644
--- a/model/EmulatedVolume.h
+++ b/model/EmulatedVolume.h
@@ -46,6 +46,9 @@
     status_t doUnmount() override;
 
   private:
+    status_t mountFuseBindMounts();
+    status_t unmountFuseBindMounts();
+
     std::string getLabel();
     std::string mRawPath;
     std::string mLabel;
@@ -58,6 +61,9 @@
     /* Whether we mounted FUSE for this volume */
     bool mFuseMounted;
 
+    /* Whether to use sdcardfs for this volume */
+    bool mUseSdcardFs;
+
     DISALLOW_COPY_AND_ASSIGN(EmulatedVolume);
 };
 
diff --git a/model/PublicVolume.cpp b/model/PublicVolume.cpp
index 78f150d..b246c95 100644
--- a/model/PublicVolume.cpp
+++ b/model/PublicVolume.cpp
@@ -51,6 +51,7 @@
     setId(StringPrintf("public:%u,%u", major(device), minor(device)));
     mDevPath = StringPrintf("/dev/block/vold/%s", getId().c_str());
     mFuseMounted = false;
+    mUseSdcardFs = IsFilesystemSupported("sdcardfs");
 }
 
 PublicVolume::~PublicVolume() {}
@@ -161,67 +162,69 @@
         return OK;
     }
 
-    if (fs_prepare_dir(mSdcardFsDefault.c_str(), 0700, AID_ROOT, AID_ROOT) ||
-        fs_prepare_dir(mSdcardFsRead.c_str(), 0700, AID_ROOT, AID_ROOT) ||
-        fs_prepare_dir(mSdcardFsWrite.c_str(), 0700, AID_ROOT, AID_ROOT) ||
-        fs_prepare_dir(mSdcardFsFull.c_str(), 0700, AID_ROOT, AID_ROOT)) {
-        PLOG(ERROR) << getId() << " failed to create sdcardfs mount points";
-        return -errno;
-    }
-
-    dev_t before = GetDevice(mSdcardFsFull);
-
-    int sdcardFsPid;
-    if (!(sdcardFsPid = fork())) {
-        if (getMountFlags() & MountFlags::kPrimary) {
-            // clang-format off
-            if (execl(kSdcardFsPath, kSdcardFsPath,
-                    "-u", "1023", // AID_MEDIA_RW
-                    "-g", "1023", // AID_MEDIA_RW
-                    "-U", std::to_string(getMountUserId()).c_str(),
-                    "-w",
-                    mRawPath.c_str(),
-                    stableName.c_str(),
-                    NULL)) {
-                // clang-format on
-                PLOG(ERROR) << "Failed to exec";
-            }
-        } else {
-            // clang-format off
-            if (execl(kSdcardFsPath, kSdcardFsPath,
-                    "-u", "1023", // AID_MEDIA_RW
-                    "-g", "1023", // AID_MEDIA_RW
-                    "-U", std::to_string(getMountUserId()).c_str(),
-                    mRawPath.c_str(),
-                    stableName.c_str(),
-                    NULL)) {
-                // clang-format on
-                PLOG(ERROR) << "Failed to exec";
-            }
+    if (mUseSdcardFs) {
+        if (fs_prepare_dir(mSdcardFsDefault.c_str(), 0700, AID_ROOT, AID_ROOT) ||
+            fs_prepare_dir(mSdcardFsRead.c_str(), 0700, AID_ROOT, AID_ROOT) ||
+            fs_prepare_dir(mSdcardFsWrite.c_str(), 0700, AID_ROOT, AID_ROOT) ||
+            fs_prepare_dir(mSdcardFsFull.c_str(), 0700, AID_ROOT, AID_ROOT)) {
+            PLOG(ERROR) << getId() << " failed to create sdcardfs mount points";
+            return -errno;
         }
 
-        LOG(ERROR) << "sdcardfs exiting";
-        _exit(1);
-    }
+        dev_t before = GetDevice(mSdcardFsFull);
 
-    if (sdcardFsPid == -1) {
-        PLOG(ERROR) << getId() << " failed to fork";
-        return -errno;
-    }
+        int sdcardFsPid;
+        if (!(sdcardFsPid = fork())) {
+            if (getMountFlags() & MountFlags::kPrimary) {
+                // clang-format off
+                if (execl(kSdcardFsPath, kSdcardFsPath,
+                        "-u", "1023", // AID_MEDIA_RW
+                        "-g", "1023", // AID_MEDIA_RW
+                        "-U", std::to_string(getMountUserId()).c_str(),
+                        "-w",
+                        mRawPath.c_str(),
+                        stableName.c_str(),
+                        NULL)) {
+                    // clang-format on
+                    PLOG(ERROR) << "Failed to exec";
+                }
+            } else {
+                // clang-format off
+                if (execl(kSdcardFsPath, kSdcardFsPath,
+                        "-u", "1023", // AID_MEDIA_RW
+                        "-g", "1023", // AID_MEDIA_RW
+                        "-U", std::to_string(getMountUserId()).c_str(),
+                        mRawPath.c_str(),
+                        stableName.c_str(),
+                        NULL)) {
+                    // clang-format on
+                    PLOG(ERROR) << "Failed to exec";
+                }
+            }
 
-    nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME);
-    while (before == GetDevice(mSdcardFsFull)) {
-        LOG(DEBUG) << "Waiting for sdcardfs to spin up...";
-        usleep(50000);  // 50ms
-
-        nsecs_t now = systemTime(SYSTEM_TIME_BOOTTIME);
-        if (nanoseconds_to_milliseconds(now - start) > 5000) {
-            LOG(WARNING) << "Timed out while waiting for sdcardfs to spin up";
-            return -ETIMEDOUT;
+            LOG(ERROR) << "sdcardfs exiting";
+            _exit(1);
         }
+
+        if (sdcardFsPid == -1) {
+            PLOG(ERROR) << getId() << " failed to fork";
+            return -errno;
+        }
+
+        nsecs_t start = systemTime(SYSTEM_TIME_BOOTTIME);
+        while (before == GetDevice(mSdcardFsFull)) {
+            LOG(DEBUG) << "Waiting for sdcardfs to spin up...";
+            usleep(50000);  // 50ms
+
+            nsecs_t now = systemTime(SYSTEM_TIME_BOOTTIME);
+            if (nanoseconds_to_milliseconds(now - start) > 5000) {
+                LOG(WARNING) << "Timed out while waiting for sdcardfs to spin up";
+                return -ETIMEDOUT;
+            }
+        }
+        /* sdcardfs will have exited already. The filesystem will still be running */
+        TEMP_FAILURE_RETRY(waitpid(sdcardFsPid, nullptr, 0));
     }
-    /* sdcardfs will have exited already. The filesystem will still be running */
-    TEMP_FAILURE_RETRY(waitpid(sdcardFsPid, nullptr, 0));
 
     bool isFuse = base::GetBoolProperty(kPropFuse, false);
     if (isFuse) {
@@ -275,22 +278,24 @@
 
     ForceUnmount(kAsecPath);
 
-    ForceUnmount(mSdcardFsDefault);
-    ForceUnmount(mSdcardFsRead);
-    ForceUnmount(mSdcardFsWrite);
-    ForceUnmount(mSdcardFsFull);
+    if (mUseSdcardFs) {
+        ForceUnmount(mSdcardFsDefault);
+        ForceUnmount(mSdcardFsRead);
+        ForceUnmount(mSdcardFsWrite);
+        ForceUnmount(mSdcardFsFull);
+
+        rmdir(mSdcardFsDefault.c_str());
+        rmdir(mSdcardFsRead.c_str());
+        rmdir(mSdcardFsWrite.c_str());
+        rmdir(mSdcardFsFull.c_str());
+
+        mSdcardFsDefault.clear();
+        mSdcardFsRead.clear();
+        mSdcardFsWrite.clear();
+        mSdcardFsFull.clear();
+    }
     ForceUnmount(mRawPath);
-
-    rmdir(mSdcardFsDefault.c_str());
-    rmdir(mSdcardFsRead.c_str());
-    rmdir(mSdcardFsWrite.c_str());
-    rmdir(mSdcardFsFull.c_str());
     rmdir(mRawPath.c_str());
-
-    mSdcardFsDefault.clear();
-    mSdcardFsRead.clear();
-    mSdcardFsWrite.clear();
-    mSdcardFsFull.clear();
     mRawPath.clear();
 
     return OK;
diff --git a/model/PublicVolume.h b/model/PublicVolume.h
index dd76373..3156b53 100644
--- a/model/PublicVolume.h
+++ b/model/PublicVolume.h
@@ -68,6 +68,9 @@
     /* Whether we mounted FUSE for this volume */
     bool mFuseMounted;
 
+    /* Whether to use sdcardfs for this volume */
+    bool mUseSdcardFs;
+
     /* Filesystem type */
     std::string mFsType;
     /* Filesystem UUID */