Add a step to derive microdroid vendor dice node
The derivation happens in the derive_microdroid_vendor_dice_node binary which first_stage_init forks and execvs. Since the derivation requires talking to the dice driver, its initialisation is also moved to the first stage init. The derivation happens before the microdroid vendor partition is verified & mounted. This should be safe because the first_stage_init will fail the boot if the verification of the microdroid vendor partition fails. Bug: 287593065 Test: run microdroid with and without vendor partition Test: atest MicrodroidTests Change-Id: I0d83772eb98a56c315617e66ec64bd03639cfde6
This commit is contained in:
parent
fe7b83faea
commit
1e114e677b
4 changed files with 71 additions and 6 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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();) {
|
||||
|
|
Loading…
Reference in a new issue