Merge "init: Look for partition only on a boot device if using boot_part_uuid" into main

This commit is contained in:
Treehugger Robot 2024-11-07 16:59:48 +00:00 committed by Gerrit Code Review
commit c43fd51571
3 changed files with 46 additions and 1 deletions

View file

@ -140,11 +140,43 @@ ListenerAction BlockDevInitializer::HandleUevent(const Uevent& uevent,
LOG(VERBOSE) << __PRETTY_FUNCTION__ << ": found partition: " << name;
devices->erase(iter);
// Remove the partition from the list of partitions we're waiting for.
//
// Partitions that we're waiting for here are expected to be on the boot
// device, so only remove from the list if they're on the boot device.
// This prevents us from being confused if there are multiple disks (some
// perhaps connected via USB) that have matching partition names.
//
// ...but...
//
// Some products (especialy emulators) don't seem to set up boot_devices
// or possibly not all the partitions that we need to wait for are on the
// specified boot device. Thus, only require partitions to be on the boot
// device in "strict" mode, which should be used on newer systems.
if (device_handler_->IsBootDevice(uevent) || !device_handler_->IsBootDeviceStrict()) {
devices->erase(iter);
}
device_handler_->HandleUevent(uevent);
return devices->empty() ? ListenerAction::kStop : ListenerAction::kContinue;
}
// Wait for partitions that are expected to be on the "boot device" to initialize.
//
// Wait (for up to 10 seconds) for partitions passed in `devices` to show up.
// All block devices found while waiting will be initialized, which includes
// creating symlinks for them in /dev/block. Once all `devices` are found we'll
// return success (true). If any devices aren't found we'll return failure
// (false). As devices are found they will be removed from `devices`.
//
// The contents of `devices` is the names of the partitions. This can be:
// - The `partition_name` reported by a uevent, or the final component in the
// `path` reported by a uevent if the `partition_name` is blank.
// - The result of DeviceHandler::GetPartitionNameForDevice() on the
// `device_name` reported by a uevent.
//
// NOTE: on newer systems partitions _must_ be on the "boot device". See
// comments inside HandleUevent().
bool BlockDevInitializer::InitDevices(std::set<std::string> devices) {
auto uevent_callback = [&, this](const Uevent& uevent) -> ListenerAction {
return HandleUevent(uevent, &devices);

View file

@ -224,6 +224,17 @@ BlockDeviceInfo DeviceHandler::GetBlockDeviceInfo(const std::string& uevent_path
return info;
}
bool DeviceHandler::IsBootDeviceStrict() const {
// When using the newer "boot_part_uuid" to specify the boot device then
// we require all core system partitions to be on the boot device.
return !boot_part_uuid_.empty();
}
bool DeviceHandler::IsBootDevice(const Uevent& uevent) const {
auto device = GetBlockDeviceInfo(uevent.path);
return device.is_boot_device;
}
std::string DeviceHandler::GetPartitionNameForDevice(const std::string& query_device) {
static const auto partition_map = [] {
std::vector<std::pair<std::string, std::string>> partition_map;

View file

@ -141,6 +141,8 @@ class DeviceHandler : public UeventHandler {
// `androidboot.partition_map=vdb,metadata;vdc,userdata` maps `vdb` to `metadata` and `vdc` to
// `userdata`.
static std::string GetPartitionNameForDevice(const std::string& device);
bool IsBootDeviceStrict() const;
bool IsBootDevice(const Uevent& uevent) const;
private:
void ColdbootDone() override;