From 519d3f8b368ae87d12814480066a8eb3c8f63216 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 16 Oct 2024 09:23:06 -0700 Subject: [PATCH 1/3] fs_mgr: Add getter for androidboot.boot_part_uuid In order to make booting from some media types (like USB) more robust, the bootloader will be extended to support passing the partition UUID that it loaded the kernel from. It can pass this via kernel commandline or via bootconfig. Add a way to get this. Bug: 316324155 Test: Use the getter in a future change Change-Id: Iab04742c0f2666db18dc48bcaaa2869eba405748 --- fs_mgr/libfstab/fstab.cpp | 16 ++++++++++++++++ fs_mgr/libfstab/include/fstab/fstab.h | 10 ++++++++++ 2 files changed, 26 insertions(+) diff --git a/fs_mgr/libfstab/fstab.cpp b/fs_mgr/libfstab/fstab.cpp index 6e4cae18f..43547eaf4 100644 --- a/fs_mgr/libfstab/fstab.cpp +++ b/fs_mgr/libfstab/fstab.cpp @@ -950,6 +950,22 @@ std::set GetBootDevices() { return ExtraBootDevices(fstab); } +std::string GetBootPartUuid() { + std::string boot_part_uuid; + + if (GetBootconfig("androidboot.boot_part_uuid", &boot_part_uuid)) { + return boot_part_uuid; + } + + ImportKernelCmdline([&](std::string key, std::string value) { + if (key == "androidboot.boot_part_uuid") { + boot_part_uuid = value; + } + }); + + return boot_part_uuid; +} + std::string GetVerityDeviceName(const FstabEntry& entry) { std::string base_device; if (entry.mount_point == "/") { diff --git a/fs_mgr/libfstab/include/fstab/fstab.h b/fs_mgr/libfstab/include/fstab/fstab.h index 070dd9178..0ff3188d4 100644 --- a/fs_mgr/libfstab/include/fstab/fstab.h +++ b/fs_mgr/libfstab/include/fstab/fstab.h @@ -126,6 +126,16 @@ void TransformFstabForDsu(Fstab* fstab, const std::string& dsu_slot, std::set GetBootDevices(); +// Get the Partition UUID the kernel loaded from if the bootloader passed it. +// +// If the kernel's Partition UUID is provided then we can use this to help +// identify which block device contains the filesystems we care about. +// +// NOTE: Nothing secures a UUID other than the convention that two disks +// aren't supposed to both have the same UUID. We still need other mechanisms +// to ensure we've got the right disk. +std::string GetBootPartUuid(); + // Return the name of the dm-verity device for the given fstab entry. This does // not check whether the device is valid or exists; it merely returns the // expected name. From e53e50e3fa8e73b86163806d6f8eeb9eadf28bb7 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 16 Oct 2024 13:51:44 -0700 Subject: [PATCH 2/3] init: Add partition_uuid to Uevent As of commit upstream Linux kernel commit 74f4a8dc0dd8 ("block: add partition uuid into uevent as "PARTUUID""), it's easy to include the partition UUID in the Uevent structure. Add it in so that other parts of the init code can make decisions based on the partition UUID. If this code is run on older kernels we'll never see the partition UUID and it will be left blank. Bug: 316324155 Test: Run w/ a newer kernel and see partition_uuid populated. Change-Id: I48a52aa006c05023f7f1cc5cc0ab5c1f1ec37455 --- init/uevent.h | 1 + init/uevent_listener.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/init/uevent.h b/init/uevent.h index dc35fd968..c8ca52aaf 100644 --- a/init/uevent.h +++ b/init/uevent.h @@ -28,6 +28,7 @@ struct Uevent { std::string subsystem; std::string firmware; std::string partition_name; + std::string partition_uuid; std::string device_name; std::string modalias; int partition_num; diff --git a/init/uevent_listener.cpp b/init/uevent_listener.cpp index 5da67777d..97f3de640 100644 --- a/init/uevent_listener.cpp +++ b/init/uevent_listener.cpp @@ -66,6 +66,9 @@ static void ParseEvent(const char* msg, Uevent* uevent) { } else if (!strncmp(msg, "PARTNAME=", 9)) { msg += 9; uevent->partition_name = msg; + } else if (!strncmp(msg, "PARTUUID=", 9)) { + msg += 9; + uevent->partition_uuid = msg; } else if (!strncmp(msg, "DEVNAME=", 8)) { msg += 8; uevent->device_name = msg; @@ -82,7 +85,7 @@ static void ParseEvent(const char* msg, Uevent* uevent) { if (LOG_UEVENTS) { LOG(INFO) << "event { '" << uevent->action << "', '" << uevent->path << "', '" << uevent->subsystem << "', '" << uevent->firmware << "', " << uevent->major - << ", " << uevent->minor << " }"; + << ", " << uevent->minor << ", " << uevent->partition_uuid << " }"; } } From 9f760f8d4185d231ef2d085d2a7664046250d7e5 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 15 Oct 2024 14:22:02 -0700 Subject: [PATCH 3/3] init: Reorder GetBlockDeviceSymlinks() so FindDmDevice() is first By moving FindDmDevice() it's easier to unify the code with the IsBootDevice() function. In this case the order doesn't matter since anything with the uevent path "/devices/virtual/block/dm-" (the only devices FindDmDevice() looks at) won't match any of the other sections of the if/then/else test. Bug: 316324155 Test: Build & boot Change-Id: I819eb60aa5077f0eb2c2f2783b152e43a52ba8b7 --- init/devices.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/init/devices.cpp b/init/devices.cpp index f2bb9d276..0af843f10 100644 --- a/init/devices.cpp +++ b/init/devices.cpp @@ -376,7 +376,13 @@ std::vector DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uev std::string partition; std::string uuid; - if (FindPlatformDevice(uevent.path, &device)) { + if (FindDmDevice(uevent, &partition, &uuid)) { + std::vector symlinks = {"/dev/block/mapper/" + partition}; + if (!uuid.empty()) { + symlinks.emplace_back("/dev/block/mapper/by-uuid/" + uuid); + } + return symlinks; + } else if (FindPlatformDevice(uevent.path, &device)) { // Skip /devices/platform or /devices/ if present static constexpr std::string_view devices_platform_prefix = "/devices/platform/"; static constexpr std::string_view devices_prefix = "/devices/"; @@ -392,12 +398,6 @@ std::vector DeviceHandler::GetBlockDeviceSymlinks(const Uevent& uev type = "pci"; } else if (FindVbdDevicePrefix(uevent.path, &device)) { type = "vbd"; - } else if (FindDmDevice(uevent, &partition, &uuid)) { - std::vector symlinks = {"/dev/block/mapper/" + partition}; - if (!uuid.empty()) { - symlinks.emplace_back("/dev/block/mapper/by-uuid/" + uuid); - } - return symlinks; } else { return {}; }