Merge "init: Look for partition only on a boot device if using boot_part_uuid" into main
diff --git a/init/block_dev_initializer.cpp b/init/block_dev_initializer.cpp
index 4ca5b8f..7f83037 100644
--- a/init/block_dev_initializer.cpp
+++ b/init/block_dev_initializer.cpp
@@ -140,11 +140,43 @@
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);
diff --git a/init/devices.cpp b/init/devices.cpp
index 0b1e13d..4de1e20 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -224,6 +224,17 @@
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;
diff --git a/init/devices.h b/init/devices.h
index cac52bc..8b6cf6c 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -141,6 +141,8 @@
// `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;