init: Don't look for logical partitions via uevents.

When using AVB, init's first stage regenerates uevent to find the paths
of block devices for verified partitions. If it can't find them all, it
will panic, causing the device to boot to recovery.

This does not work with logical partitions, since devices for those
partitions are created later in the first stage. In fact, they cannot be
created until uevent regeneration completes, since logical partitions are
are created by finding the "super" partition.

To address this we exclude logical partitions (as marked in fstab) from
the device finding process. Note that partitions moved from GPT to liblp
will no longer appear in by_name_symlink_map_.

Bug: 79173901
Test: AVB 2.0 device boots after deleting the vendor partition,
      creating a super partition, and flashing it with a dynamic
      vendor partition.

Change-Id: I19371b05912240480dc50864a2c04131258a7103
This commit is contained in:
David Anderson 2018-07-18 17:02:07 -07:00
parent 9555f3dcf6
commit ab8414dd6c

View file

@ -456,12 +456,19 @@ FirstStageMountVBootV2::FirstStageMountVBootV2() : avb_handle_(nullptr) {
bool FirstStageMountVBootV2::GetDmVerityDevices() {
need_dm_verity_ = false;
std::set<std::string> logical_partitions;
// fstab_rec->blk_device has A/B suffix.
for (auto fstab_rec : mount_fstab_recs_) {
if (fs_mgr_is_avb(fstab_rec)) {
need_dm_verity_ = true;
}
required_devices_partition_names_.emplace(basename(fstab_rec->blk_device));
if (fs_mgr_is_logical(fstab_rec)) {
// Don't try to find logical partitions via uevent regeneration.
logical_partitions.emplace(basename(fstab_rec->blk_device));
} else {
required_devices_partition_names_.emplace(basename(fstab_rec->blk_device));
}
}
// libavb verifies AVB metadata on all verified partitions at once.
@ -476,11 +483,15 @@ bool FirstStageMountVBootV2::GetDmVerityDevices() {
std::vector<std::string> partitions = android::base::Split(device_tree_vbmeta_parts_, ",");
std::string ab_suffix = fs_mgr_get_slot_suffix();
for (const auto& partition : partitions) {
std::string partition_name = partition + ab_suffix;
if (logical_partitions.count(partition_name)) {
continue;
}
// required_devices_partition_names_ is of type std::set so it's not an issue
// to emplace a partition twice. e.g., /vendor might be in both places:
// - device_tree_vbmeta_parts_ = "vbmeta,boot,system,vendor"
// - mount_fstab_recs_: /vendor_a
required_devices_partition_names_.emplace(partition + ab_suffix);
required_devices_partition_names_.emplace(partition_name);
}
}
return true;