remount: Refactor fs_mgr_overlayfs_scratch_device().
This splits fs_mgr_overlayfs_scratch_device into two new methods. The
first, GetScratchStrategy, returns an enum detailing exactly how the
device will find space for scratch:
- via system_<other>,
- via super_<other>, or
- via a dynamic partition.
The second method, GetScratchDevice, uses the strategy to either return
the underlying block device, or look up a dynamic partition.
fs_mgr_overlayfs_scratch_device will be removed completely in a separate
patch.
Bug: 134949511
Test: adb remount and adb_remount_test.sh
Change-Id: Ic7e3815ada4adaf5fd7c19b84dc22249f3dcc881
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 05f3311..2337065 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -815,26 +815,72 @@
return "auto";
}
-std::string fs_mgr_overlayfs_scratch_device() {
- if (!scratch_device_cache.empty()) return scratch_device_cache;
+enum class ScratchStrategy {
+ kNone,
+ // DAP device, use logical partitions.
+ kDynamicPartition,
+ // Retrofit DAP device, use super_<other>.
+ kSuperOther,
+ // Pre-DAP device, uses the other slot.
+ kSystemOther
+};
- // Is this a multiple super device (retrofit)?
+static ScratchStrategy GetScratchStrategy(std::string* backing_device) {
auto slot_number = fs_mgr_overlayfs_slot_number();
auto super_device = fs_mgr_overlayfs_super_device(slot_number);
auto path = fs_mgr_overlayfs_super_device(slot_number == 0);
- if (super_device == path) {
- // Create from within single super device;
- auto& dm = DeviceMapper::Instance();
- const auto partition_name = android::base::Basename(kScratchMountPoint);
- if (!dm.GetDmDevicePathByName(partition_name, &path)) {
- // non-DAP A/B device?
- if (fs_mgr_access(super_device)) return "";
- auto other_slot = fs_mgr_get_other_slot_suffix();
- if (other_slot.empty()) return "";
- path = kPhysicalDevice + "system" + other_slot;
+ if (super_device != path) {
+ // Note: we do not check access() here, since in first-stage init we
+ // wouldn't have registed by-name symlinks for the device as it's
+ // normally not needed. The access checks elsewhere in this function
+ // are safe because system/super are always required.
+ *backing_device = path;
+ return ScratchStrategy::kSuperOther;
+ }
+ if (fs_mgr_access(super_device)) {
+ *backing_device = super_device;
+ return ScratchStrategy::kDynamicPartition;
+ }
+
+ auto other_slot = fs_mgr_get_other_slot_suffix();
+ if (!other_slot.empty()) {
+ path = kPhysicalDevice + "system" + other_slot;
+ if (fs_mgr_access(path)) {
+ *backing_device = path;
+ return ScratchStrategy::kSystemOther;
}
}
- return scratch_device_cache = path;
+ return ScratchStrategy::kNone;
+}
+
+// Return the scratch device if it exists.
+static std::string GetScratchDevice() {
+ std::string device;
+ ScratchStrategy strategy = GetScratchStrategy(&device);
+
+ switch (strategy) {
+ case ScratchStrategy::kSuperOther:
+ case ScratchStrategy::kSystemOther:
+ return device;
+ case ScratchStrategy::kDynamicPartition: {
+ auto& dm = DeviceMapper::Instance();
+ auto partition_name = android::base::Basename(kScratchMountPoint);
+ if (dm.GetState(partition_name) != DmDeviceState::INVALID &&
+ dm.GetDmDevicePathByName(partition_name, &device)) {
+ return device;
+ }
+ return "";
+ }
+ default:
+ return "";
+ }
+}
+
+std::string fs_mgr_overlayfs_scratch_device() {
+ if (!scratch_device_cache.empty()) return scratch_device_cache;
+
+ scratch_device_cache = GetScratchDevice();
+ return scratch_device_cache;
}
bool fs_mgr_overlayfs_make_scratch(const std::string& scratch_device, const std::string& mnt_type) {