From 251ec05f017fb81628dd1995fb587913063702e4 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 20 Aug 2019 16:31:46 -0700 Subject: [PATCH] liblp: Support sdcards in PartitionOpener. Before ImageManager was introduced, gsid avoided using PartitionOpener when writing to external media. PartitionOpener couldn't interact with non-boot devices, because it prepends /dev/block/by-name. We hacked around this in both gsid and in first-stage init, which manually detects the problem and prepends /dev/block instead. After the ImageManager refactoring, sdcard support broke in gsid, because it started relying on PartitionOpener. Let's fix this by allowing /dev/block for mmcblk* names in PartitionOpener. Bug: 139204329 Test: fiemap_image_test gtest Change-Id: Ic1cbdbe0a18fc09522ee38cc62b35fd8193ce250 --- fs_mgr/liblp/partition_opener.cpp | 16 +++++++++++++++- init/first_stage_mount.cpp | 16 ++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/fs_mgr/liblp/partition_opener.cpp b/fs_mgr/liblp/partition_opener.cpp index f1e8fc20c..1d4db8525 100644 --- a/fs_mgr/liblp/partition_opener.cpp +++ b/fs_mgr/liblp/partition_opener.cpp @@ -41,7 +41,21 @@ std::string GetPartitionAbsolutePath(const std::string& path) { if (android::base::StartsWith(path, "/")) { return path; } - return "/dev/block/by-name/" + path; + + auto by_name = "/dev/block/by-name/" + path; + if (access(by_name.c_str(), F_OK) != 0) { + // If the by-name symlink doesn't exist, as a special case we allow + // certain devices to be used as partition names. This can happen if a + // Dynamic System Update is installed to an sdcard, which won't be in + // the boot device list. + // + // We whitelist because most devices in /dev/block are not valid for + // storing fiemaps. + if (android::base::StartsWith(path, "mmcblk")) { + return "/dev/block/" + path; + } + } + return by_name; } bool GetBlockDeviceInfo(const std::string& block_device, BlockDeviceInfo* device_info) { diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp index 1a5ed2847..dffd6af00 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -602,19 +602,11 @@ void FirstStageMount::UseGsiIfPresent() { return; } - // Find the name of the super partition for the GSI. It will either be - // "userdata", or a block device such as an sdcard. There are no by-name - // partitions other than userdata that we support installing GSIs to. + // Find the super name. PartitionOpener will ensure this translates to the + // correct block device path. auto super = GetMetadataSuperBlockDevice(*metadata.get()); - std::string super_name = android::fs_mgr::GetBlockDevicePartitionName(*super); - std::string super_path; - if (super_name == "userdata") { - super_path = "/dev/block/by-name/" + super_name; - } else { - super_path = "/dev/block/" + super_name; - } - - if (!android::fs_mgr::CreateLogicalPartitions(*metadata.get(), super_path)) { + auto super_name = android::fs_mgr::GetBlockDevicePartitionName(*super); + if (!android::fs_mgr::CreateLogicalPartitions(*metadata.get(), super_name)) { LOG(ERROR) << "GSI partition layout could not be instantiated"; return; }