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
This commit is contained in:
David Anderson 2019-12-10 21:07:51 -08:00
parent f4ddee0f32
commit 864021fbf6

View file

@ -815,26 +815,72 @@ std::string fs_mgr_overlayfs_scratch_mount_type() {
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) {