fs_mgr_overlayfs: Make all string constants constexpr

According to https://abseil.io/tips/140, string constants should be
constexpr char array or string_view object. This avoids subtle bugs due
to the toolchain shuffling object initialization order between/within
compilation units.

string_view has bad interoperability between C APIs as many of those
functions require string values to be null-terminated. Thus we can only
rely on good old c-string constants.

This change groups all string constants together and change them all to
constexpr char array for consistent style.
Also remove some duplicated method definition.

Test: adb-remount-test
Change-Id: I1ed57e6dc24ce3750e72c5538c388a6872cd2b40
diff --git a/fs_mgr/fs_mgr_overlayfs_control.cpp b/fs_mgr/fs_mgr_overlayfs_control.cpp
index 69a2ac0..c9a8997 100644
--- a/fs_mgr/fs_mgr_overlayfs_control.cpp
+++ b/fs_mgr/fs_mgr_overlayfs_control.cpp
@@ -71,15 +71,18 @@
 
 constexpr char kDataScratchSizeMbProp[] = "fs_mgr.overlayfs.data_scratch_size_mb";
 
+constexpr char kPhysicalDevice[] = "/dev/block/by-name/";
+constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata";
+
+constexpr char kMkF2fs[] = "/system/bin/make_f2fs";
+constexpr char kMkExt4[] = "/system/bin/mke2fs";
+
 // Return true if everything is mounted, but before adb is started.  Right
 // after 'trigger load_persist_props_action' is done.
 static bool fs_mgr_boot_completed() {
     return android::base::GetBoolProperty("ro.persistent_properties.ready", false);
 }
 
-constexpr auto kPhysicalDevice = "/dev/block/by-name/";
-constexpr char kScratchImageMetadata[] = "/metadata/gsi/remount/lp_metadata";
-
 // Note: this is meant only for recovery/first-stage init.
 static bool ScratchIsOnData() {
     // The scratch partition of DSU is managed by gsid.
@@ -131,7 +134,7 @@
 }
 
 std::string fs_mgr_overlayfs_setup_dir(const std::string& dir) {
-    auto top = dir + kOverlayTopDir;
+    auto top = dir + "/" + kOverlayTopDir;
 
     AutoSetFsCreateCon createcon(kOverlayfsFileContext);
     if (!createcon.Ok()) {
@@ -290,7 +293,7 @@
 
 bool fs_mgr_overlayfs_teardown_one(const std::string& overlay, const std::string& mount_point,
                                    bool* change, bool* should_destroy_scratch = nullptr) {
-    const auto top = overlay + kOverlayTopDir;
+    const auto top = overlay + "/" + kOverlayTopDir;
 
     if (!fs_mgr_access(top)) {
         if (should_destroy_scratch) *should_destroy_scratch = true;
@@ -300,7 +303,7 @@
     auto cleanup_all = mount_point.empty();
     const auto partition_name = android::base::Basename(mount_point);
     const auto oldpath = top + (cleanup_all ? "" : ("/" + partition_name));
-    const auto newpath = cleanup_all ? overlay + "/." + (kOverlayTopDir + 1) + ".teardown"
+    const auto newpath = cleanup_all ? overlay + "/." + kOverlayTopDir + ".teardown"
                                      : top + "/." + partition_name + ".teardown";
     auto ret = fs_mgr_rm_all(newpath);
     if (!rename(oldpath.c_str(), newpath.c_str())) {
@@ -346,72 +349,6 @@
     return ret;
 }
 
-// Mount kScratchMountPoint
-bool MountScratch(const std::string& device_path, bool readonly = false) {
-    if (readonly) {
-        if (!fs_mgr_access(device_path)) {
-            LOG(ERROR) << "Path does not exist: " << device_path;
-            return false;
-        }
-    } else if (!fs_mgr_rw_access(device_path)) {
-        LOG(ERROR) << "Path does not exist or is not readwrite: " << device_path;
-        return false;
-    }
-
-    std::vector<const char*> filesystem_candidates;
-    if (fs_mgr_is_f2fs(device_path)) {
-        filesystem_candidates = {"f2fs", "ext4"};
-    } else if (fs_mgr_is_ext4(device_path)) {
-        filesystem_candidates = {"ext4", "f2fs"};
-    } else {
-        LOG(ERROR) << "Scratch partition is not f2fs or ext4";
-        return false;
-    }
-
-    AutoSetFsCreateCon createcon(kOverlayfsFileContext);
-    if (!createcon.Ok()) {
-        return false;
-    }
-    if (mkdir(kScratchMountPoint, 0755) && (errno != EEXIST)) {
-        PERROR << "create " << kScratchMountPoint;
-        return false;
-    }
-
-    FstabEntry entry;
-    entry.blk_device = device_path;
-    entry.mount_point = kScratchMountPoint;
-    entry.flags = MS_NOATIME | MS_RDONLY;
-    if (!readonly) {
-        entry.flags &= ~MS_RDONLY;
-        entry.flags |= MS_SYNCHRONOUS;
-        entry.fs_options = "nodiscard";
-        fs_mgr_set_blk_ro(device_path, false);
-    }
-    // check_fs requires apex runtime library
-    if (fs_mgr_overlayfs_already_mounted("/data", false)) {
-        entry.fs_mgr_flags.check = true;
-    }
-    bool mounted = false;
-    for (auto fs_type : filesystem_candidates) {
-        entry.fs_type = fs_type;
-        if (fs_mgr_do_mount_one(entry) == 0) {
-            mounted = true;
-            break;
-        }
-    }
-    if (!createcon.Restore()) {
-        return false;
-    }
-    if (!mounted) {
-        rmdir(kScratchMountPoint);
-        return false;
-    }
-    return true;
-}
-
-const std::string kMkF2fs("/system/bin/make_f2fs");
-const std::string kMkExt4("/system/bin/mke2fs");
-
 // Note: The scratch partition of DSU is managed by gsid, and should be initialized during
 // first-stage-mount. Just check if the DM device for DSU scratch partition is created or not.
 static std::string GetDsuScratchDevice() {
@@ -456,14 +393,14 @@
     // thus do not rely on fsck to correct problems that could creep in.
     auto fs_type = ""s;
     auto command = ""s;
-    if (!access(kMkF2fs.c_str(), X_OK) && fs_mgr_filesystem_available("f2fs")) {
+    if (!access(kMkF2fs, X_OK) && fs_mgr_filesystem_available("f2fs")) {
         fs_type = "f2fs";
-        command = kMkF2fs + " -w ";
+        command = kMkF2fs + " -w "s;
         command += std::to_string(getpagesize());
         command += " -f -d1 -l" + android::base::Basename(kScratchMountPoint);
-    } else if (!access(kMkExt4.c_str(), X_OK) && fs_mgr_filesystem_available("ext4")) {
+    } else if (!access(kMkExt4, X_OK) && fs_mgr_filesystem_available("ext4")) {
         fs_type = "ext4";
-        command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M " + kScratchMountPoint;
+        command = kMkExt4 + " -F -b 4096 -t ext4 -m 0 -O has_journal -M "s + kScratchMountPoint;
     } else {
         LERROR << "No supported mkfs command or filesystem driver available, supported filesystems "
                   "are: f2fs, ext4";
@@ -697,7 +634,7 @@
     // If the partition exists, assume first that it can be mounted.
     if (partition_exists) {
         if (MountScratch(scratch_device)) {
-            if (fs_mgr_access(std::string(kScratchMountPoint) + kOverlayTopDir) ||
+            if (fs_mgr_access(kScratchMountPoint + "/"s + kOverlayTopDir) ||
                 fs_mgr_filesystem_has_space(kScratchMountPoint)) {
                 return true;
             }
@@ -717,32 +654,6 @@
     return MountScratch(scratch_device);
 }
 
-// NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed().
-// Setup is allowed only if teardown is also allowed.
-bool OverlayfsSetupAllowed(bool verbose = false) {
-    if (!kAllowOverlayfs) {
-        if (verbose) {
-            LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds";
-        }
-        return false;
-    }
-    // Check mandatory kernel patches.
-    if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) {
-        if (verbose) {
-            LOG(ERROR) << "Kernel does not support overlayfs";
-        }
-        return false;
-    }
-    // in recovery or fastbootd, not allowed!
-    if (fs_mgr_in_recovery()) {
-        if (verbose) {
-            LOG(ERROR) << "Unsupported overlayfs setup from recovery";
-        }
-        return false;
-    }
-    return true;
-}
-
 constexpr bool OverlayfsTeardownAllowed() {
     // Never allow on non-debuggable build.
     return kAllowOverlayfs;
diff --git a/fs_mgr/fs_mgr_overlayfs_mount.cpp b/fs_mgr/fs_mgr_overlayfs_mount.cpp
index c057c2b..e380f84 100644
--- a/fs_mgr/fs_mgr_overlayfs_mount.cpp
+++ b/fs_mgr/fs_mgr_overlayfs_mount.cpp
@@ -62,13 +62,16 @@
 
 constexpr char kPreferCacheBackingStorageProp[] = "fs_mgr.overlayfs.prefer_cache_backing_storage";
 
+constexpr char kCacheMountPoint[] = "/cache";
+constexpr char kPhysicalDevice[] = "/dev/block/by-name/";
+
+constexpr char kLowerdirOption[] = "lowerdir=";
+constexpr char kUpperdirOption[] = "upperdir=";
+
 bool fs_mgr_access(const std::string& path) {
     return access(path.c_str(), F_OK) == 0;
 }
 
-const auto kLowerdirOption = "lowerdir=";
-const auto kUpperdirOption = "upperdir=";
-
 bool fs_mgr_in_recovery() {
     // Check the existence of recovery binary instead of using the compile time
     // __ANDROID_RECOVERY__ macro.
@@ -89,8 +92,6 @@
     return android::gsi::IsGsiRunning();
 }
 
-const auto kCacheMountPoint = "/cache";
-
 static bool IsABDevice() {
     return !android::base::GetProperty("ro.boot.slot_suffix", "").empty();
 }
@@ -141,8 +142,6 @@
            (static_cast<uint64_t>(vst.f_bfree) * vst.f_frsize) >= kSizeThreshold;
 }
 
-const auto kPhysicalDevice = "/dev/block/by-name/";
-
 static bool fs_mgr_update_blk_device(FstabEntry* entry) {
     if (entry->fs_mgr_flags.logical) {
         fs_mgr_update_logical_partition(entry);
@@ -155,7 +154,7 @@
     }
 
     // special case for system-as-root (taimen and others)
-    auto blk_device = std::string(kPhysicalDevice) + "system";
+    auto blk_device = kPhysicalDevice + "system"s;
     if (!fs_mgr_access(blk_device)) {
         blk_device += fs_mgr_get_slot_suffix();
         if (!fs_mgr_access(blk_device)) {
@@ -237,7 +236,7 @@
     if (!fs_mgr_is_dir(mount_point)) return "";
     const auto base = android::base::Basename(mount_point) + "/";
     for (const auto& overlay_mount_point : OverlayMountPoints()) {
-        auto dir = overlay_mount_point + kOverlayTopDir + "/" + base;
+        auto dir = overlay_mount_point + "/" + kOverlayTopDir + "/" + base;
         auto upper = dir + kUpperName;
         if (!fs_mgr_is_dir(upper)) continue;
         auto work = dir + kWorkName;
@@ -527,7 +526,7 @@
 }
 
 // Mount kScratchMountPoint
-static bool MountScratch(const std::string& device_path, bool readonly = false) {
+bool MountScratch(const std::string& device_path, bool readonly) {
     if (readonly) {
         if (!fs_mgr_access(device_path)) {
             LOG(ERROR) << "Path does not exist: " << device_path;
@@ -589,9 +588,6 @@
     return true;
 }
 
-const std::string kMkF2fs("/system/bin/make_f2fs");
-const std::string kMkExt4("/system/bin/mke2fs");
-
 // Note: The scratch partition of DSU is managed by gsid, and should be initialized during
 // first-stage-mount. Just check if the DM device for DSU scratch partition is created or not.
 static std::string GetDsuScratchDevice() {
@@ -633,7 +629,7 @@
 
 // NOTE: OverlayfsSetupAllowed() must be "stricter" than OverlayfsTeardownAllowed().
 // Setup is allowed only if teardown is also allowed.
-bool OverlayfsSetupAllowed(bool verbose = false) {
+bool OverlayfsSetupAllowed(bool verbose) {
     if (!kAllowOverlayfs) {
         if (verbose) {
             LOG(ERROR) << "Overlayfs remounts can only be used in debuggable builds";
@@ -737,7 +733,7 @@
     if (!MountScratch(scratch_device, true /* readonly */)) {
         return;
     }
-    auto has_overlayfs_dir = fs_mgr_access(std::string(kScratchMountPoint) + kOverlayTopDir);
+    auto has_overlayfs_dir = fs_mgr_access(kScratchMountPoint + "/"s + kOverlayTopDir);
     fs_mgr_overlayfs_umount_scratch();
     if (has_overlayfs_dir) {
         MountScratch(scratch_device);
diff --git a/fs_mgr/fs_mgr_overlayfs_mount.h b/fs_mgr/fs_mgr_overlayfs_mount.h
index ae3ea84..d9a93d4 100644
--- a/fs_mgr/fs_mgr_overlayfs_mount.h
+++ b/fs_mgr/fs_mgr_overlayfs_mount.h
@@ -20,9 +20,12 @@
 
 #include <fstab/fstab.h>
 
-bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true);
-bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry);
-android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);
+constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
+
+constexpr char kScratchMountPoint[] = "/mnt/scratch";
+constexpr char kOverlayTopDir[] = "overlay";
+constexpr char kUpperName[] = "upper";
+constexpr char kWorkName[] = "work";
 
 #if ALLOW_ADBD_DISABLE_VERITY
 constexpr bool kAllowOverlayfs = true;
@@ -45,18 +48,16 @@
     bool restored_ = false;
 };
 
-constexpr auto kScratchMountPoint = "/mnt/scratch";
-constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
-
-constexpr auto kUpperName = "upper";
-constexpr auto kWorkName = "work";
-constexpr auto kOverlayTopDir = "/overlay";
-
 bool fs_mgr_is_dsu_running();
 bool fs_mgr_in_recovery();
 bool fs_mgr_access(const std::string& path);
 bool fs_mgr_rw_access(const std::string& path);
 bool fs_mgr_filesystem_has_space(const std::string& mount_point);
 const std::string fs_mgr_mount_point(const std::string& mount_point);
+bool OverlayfsSetupAllowed(bool verbose = false);
+bool MountScratch(const std::string& device_path, bool readonly = false);
 bool fs_mgr_overlayfs_umount_scratch();
 std::vector<const std::string> OverlayMountPoints();
+bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true);
+bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry);
+android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);