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
This commit is contained in:
David Anderson 2019-08-20 16:31:46 -07:00
parent 370226e662
commit 251ec05f01
2 changed files with 19 additions and 13 deletions

View File

@ -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) {

View File

@ -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;
}