From 2b2f423ef694a03f4fd429b1d3fa221619131df4 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 29 Oct 2018 18:48:56 -0700 Subject: recovery: Fix mounting /system with dynamic partitions. When using dynamic partitions, the blk_device field in fstab_rec must be translated to a /dev/block/dm-N node with fs_mgr_update_logical_partition. However, init will not have created these nodes to begin with since CreateLogicalPartitions is not called in recovery. This patch addresses both issues. Note that flashing system through fastbootd will not work while /system is mounted. Bug: 118634720 Test: manual test Change-Id: I06c83309d09eab6b65245b1ed10c51d05398f23e --- recovery_main.cpp | 9 +++++++-- roots.cpp | 25 +++++++++++++++++++++++++ roots.h | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/recovery_main.cpp b/recovery_main.cpp index 78350944c..19ef4f3d0 100644 --- a/recovery_main.cpp +++ b/recovery_main.cpp @@ -478,8 +478,13 @@ int main(int argc, char** argv) { break; case Device::ENTER_FASTBOOT: - LOG(INFO) << "Entering fastboot"; - fastboot = true; + if (logical_partitions_mapped()) { + ui->Print("Partitions may be mounted - rebooting to enter fastboot."); + android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,fastboot"); + } else { + LOG(INFO) << "Entering fastboot"; + fastboot = true; + } break; case Device::ENTER_RECOVERY: diff --git a/roots.cpp b/roots.cpp index c29771af6..dc347848a 100644 --- a/roots.cpp +++ b/roots.cpp @@ -38,10 +38,12 @@ #include #include #include +#include #include "otautil/mounts.h" static struct fstab* fstab = nullptr; +static bool did_map_logical_partitions = false; extern struct selabel_handle* sehandle; @@ -117,6 +119,25 @@ int ensure_path_mounted_at(const char* path, const char* mount_point) { mount_point = v->mount_point; } + // If we can't acquire the block device for a logical partition, it likely + // was never created. In that case we try to create it. + if (fs_mgr_is_logical(v) && !fs_mgr_update_logical_partition(v)) { + if (did_map_logical_partitions) { + LOG(ERROR) << "Failed to find block device for partition"; + return -1; + } + std::string super_name = fs_mgr_get_super_partition_name(); + if (!android::fs_mgr::CreateLogicalPartitions(super_name)) { + LOG(ERROR) << "Failed to create logical partitions"; + return -1; + } + did_map_logical_partitions = true; + if (!fs_mgr_update_logical_partition(v)) { + LOG(ERROR) << "Failed to find block device for partition"; + return -1; + } + } + const MountedVolume* mv = find_mounted_volume_by_mount_point(mount_point); if (mv != nullptr) { // Volume is already mounted. @@ -387,3 +408,7 @@ int setup_install_mounts() { } return 0; } + +bool logical_partitions_mapped() { + return did_map_logical_partitions; +} diff --git a/roots.h b/roots.h index 46bb77e02..702af8de5 100644 --- a/roots.h +++ b/roots.h @@ -53,4 +53,6 @@ int format_volume(const char* volume, const char* directory); // mounted (/tmp and /cache) are mounted. Returns 0 on success. int setup_install_mounts(); +bool logical_partitions_mapped(); + #endif // RECOVERY_ROOTS_H_ -- cgit v1.2.3