Merge changes from topic "derive-microdroid-vendor-dice-node" into main am: 13db31040f

Original change: https://android-review.googlesource.com/c/platform/system/core/+/2986255

Change-Id: I0a67cf4f1dd6eeea3a3f6ffec3b5320d291dadf6
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Nikita Ioffe 2024-03-14 11:39:58 +00:00 committed by Automerger Merge Worker
commit 4b91a6bc26
4 changed files with 71 additions and 6 deletions

View file

@ -463,7 +463,7 @@ cc_binary {
name: "init_first_stage.microdroid",
defaults: [
"avf_build_flags_cc",
"init_first_stage_defaults"
"init_first_stage_defaults",
],
cflags: ["-DMICRODROID=1"],
installable: false,

View file

@ -132,11 +132,19 @@ bool BlockDevInitializer::InitDevices(std::set<std::string> devices) {
bool BlockDevInitializer::InitDmDevice(const std::string& device) {
const std::string device_name(basename(device.c_str()));
const std::string syspath = "/sys/block/" + device_name;
return InitDevice(syspath, device_name);
}
bool BlockDevInitializer::InitPlatformDevice(const std::string& dev_name) {
return InitDevice("/sys/devices/platform", dev_name);
}
bool BlockDevInitializer::InitDevice(const std::string& syspath, const std::string& device_name) {
bool found = false;
auto uevent_callback = [&device_name, &device, this, &found](const Uevent& uevent) {
auto uevent_callback = [&device_name, this, &found](const Uevent& uevent) {
if (uevent.device_name == device_name) {
LOG(VERBOSE) << "Creating device-mapper device : " << device;
LOG(VERBOSE) << "Creating device : " << device_name;
device_handler_->HandleUevent(uevent);
found = true;
return ListenerAction::kStop;
@ -146,13 +154,13 @@ bool BlockDevInitializer::InitDmDevice(const std::string& device) {
uevent_listener_.RegenerateUeventsForPath(syspath, uevent_callback);
if (!found) {
LOG(INFO) << "dm device '" << device << "' not found in /sys, waiting for its uevent";
LOG(INFO) << "device '" << device_name << "' not found in /sys, waiting for its uevent";
Timer t;
uevent_listener_.Poll(uevent_callback, 10s);
LOG(INFO) << "wait for dm device '" << device << "' returned after " << t;
LOG(INFO) << "wait for device '" << device_name << "' returned after " << t;
}
if (!found) {
LOG(ERROR) << "dm device '" << device << "' not found after polling timeout";
LOG(ERROR) << "device '" << device_name << "' not found after polling timeout";
return false;
}
return true;

View file

@ -24,6 +24,7 @@
namespace android {
namespace init {
// TODO: should this be renamed to FirstStageDevInitialize?
class BlockDevInitializer final {
public:
BlockDevInitializer();
@ -32,11 +33,13 @@ class BlockDevInitializer final {
bool InitDmUser(const std::string& name);
bool InitDevices(std::set<std::string> devices);
bool InitDmDevice(const std::string& device);
bool InitPlatformDevice(const std::string& device);
private:
ListenerAction HandleUevent(const Uevent& uevent, std::set<std::string>* devices);
bool InitMiscDevice(const std::string& name);
bool InitDevice(const std::string& syspath, const std::string& device);
std::unique_ptr<DeviceHandler> device_handler_;
UeventListener uevent_listener_;

View file

@ -16,6 +16,7 @@
#include "first_stage_mount.h"
#include <signal.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <unistd.h>
@ -33,6 +34,7 @@
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android/avf_cc_flags.h>
#include <fs_avb/fs_avb.h>
#include <fs_mgr.h>
#include <fs_mgr_dm_linear.h>
@ -272,6 +274,11 @@ bool FirstStageMountVBootV2::DoFirstStageMount() {
return true;
}
// TODO: should this be in a library in packages/modules/Virtualization first_stage_init links?
static bool IsMicrodroidStrictBoot() {
return access("/proc/device-tree/chosen/avf,strict-boot", F_OK) == 0;
}
bool FirstStageMountVBootV2::InitDevices() {
std::set<std::string> devices;
GetSuperDeviceName(&devices);
@ -283,6 +290,14 @@ bool FirstStageMountVBootV2::InitDevices() {
return false;
}
if (IsMicrodroid() && android::virtualization::IsOpenDiceChangesFlagEnabled()) {
if (IsMicrodroidStrictBoot()) {
if (!block_dev_init_.InitPlatformDevice("open-dice0")) {
return false;
}
}
}
if (IsDmLinearEnabled()) {
auto super_symlink = "/dev/block/by-name/"s + super_partition_name_;
if (!android::base::Realpath(super_symlink, &super_path_)) {
@ -527,9 +542,48 @@ bool FirstStageMountVBootV2::TrySwitchSystemAsRoot() {
return true;
}
static bool MaybeDeriveMicrodroidVendorDiceNode(Fstab* fstab) {
std::optional<std::string> microdroid_vendor_block_dev;
for (auto entry = fstab->begin(); entry != fstab->end(); entry++) {
if (entry->mount_point == "/vendor") {
microdroid_vendor_block_dev.emplace(entry->blk_device);
break;
}
}
if (!microdroid_vendor_block_dev.has_value()) {
LOG(VERBOSE) << "No microdroid vendor partition to mount";
return true;
}
// clang-format off
const std::array<const char*, 7> args = {
"/system/bin/derive_microdroid_vendor_dice_node",
"--dice-driver", "/dev/open-dice0",
"--microdroid-vendor-disk-image", microdroid_vendor_block_dev->data(),
"--output", "/microdroid_resources/dice_chain.raw",
};
// clang-format-on
// ForkExecveAndWaitForCompletion calls waitpid to wait for the fork-ed process to finish.
// The first_stage_console adds SA_NOCLDWAIT flag to the SIGCHLD handler, which means that
// waitpid will always return -ECHLD. Here we re-register a default handler, so that waitpid
// works.
LOG(INFO) << "Deriving dice node for microdroid vendor partition";
signal(SIGCHLD, SIG_DFL);
if (!ForkExecveAndWaitForCompletion(args[0], (char**)args.data())) {
LOG(ERROR) << "Failed to derive microdroid vendor dice node";
return false;
}
return true;
}
bool FirstStageMountVBootV2::MountPartitions() {
if (!TrySwitchSystemAsRoot()) return false;
if (IsMicrodroid() && android::virtualization::IsOpenDiceChangesFlagEnabled()) {
if (!MaybeDeriveMicrodroidVendorDiceNode(&fstab_)) {
return false;
}
}
if (!SkipMountingPartitions(&fstab_, true /* verbose */)) return false;
for (auto current = fstab_.begin(); current != fstab_.end();) {