Support for conditionally mounting /vendor partition in Microdroid
first_stage_init will only mount the /vendor partition in Microdroid if
the androidboot.microdroid.mount_vendor=1 is provided in the kernel
cmdline.
Bug: 285855433
Test: atest MicrodroidTestApp
Change-Id: I5b840b5474bc52ec2696a0ba6ead0476acddfb1a
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index e1d383a..e871da2 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -257,8 +257,8 @@
return BootMode::NORMAL_MODE;
}
-static std::unique_ptr<FirstStageMount> CreateFirstStageMount() {
- auto ret = FirstStageMount::Create();
+static std::unique_ptr<FirstStageMount> CreateFirstStageMount(const std::string& cmdline) {
+ auto ret = FirstStageMount::Create(cmdline);
if (ret.ok()) {
return std::move(*ret);
} else {
@@ -396,7 +396,7 @@
bool created_devices = false;
if (want_console == FirstStageConsoleParam::CONSOLE_ON_FAILURE) {
if (!IsRecoveryMode()) {
- fsm = CreateFirstStageMount();
+ fsm = CreateFirstStageMount(cmdline);
if (fsm) {
created_devices = fsm->DoCreateDevices();
if (!created_devices) {
@@ -456,7 +456,7 @@
LOG(INFO) << "First stage mount skipped (recovery mode)";
} else {
if (!fsm) {
- fsm = CreateFirstStageMount();
+ fsm = CreateFirstStageMount(cmdline);
}
if (!fsm) {
LOG(FATAL) << "FirstStageMount not available";
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 4961f6a..d0f68a8 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -138,7 +138,7 @@
return is_android_dt_value_expected("vbmeta/compatible", "android,vbmeta");
}
-static Result<Fstab> ReadFirstStageFstab() {
+static Result<Fstab> ReadFirstStageFstabAndroid() {
Fstab fstab;
if (!ReadFstabFromDt(&fstab)) {
if (ReadDefaultFstab(&fstab)) {
@@ -154,6 +154,24 @@
return fstab;
}
+// Note: this is a temporary solution to avoid blocking devs that depend on /vendor partition in
+// Microdroid. For the proper solution the /vendor fstab should probably be defined in the DT.
+// TODO(b/285855430): refactor this
+// TODO(b/285855436): verify key microdroid-vendor was signed with.
+// TODO(b/285855436): should be mounted on top of dm-verity device.
+static Result<Fstab> ReadFirstStageFstabMicrodroid(const std::string& cmdline) {
+ Fstab fstab;
+ if (!ReadDefaultFstab(&fstab)) {
+ return Error() << "failed to read fstab";
+ }
+ if (cmdline.find("androidboot.microdroid.mount_vendor=1") == std::string::npos) {
+ // We weren't asked to mount /vendor partition, filter it out from the fstab.
+ auto predicate = [](const auto& entry) { return entry.mount_point == "/vendor"; };
+ fstab.erase(std::remove_if(fstab.begin(), fstab.end(), predicate), fstab.end());
+ }
+ return fstab;
+}
+
static bool GetRootEntry(FstabEntry* root_entry) {
Fstab proc_mounts;
if (!ReadFstabFromFile("/proc/mounts", &proc_mounts)) {
@@ -206,10 +224,13 @@
return rollbacked;
}
-// Class Definitions
-// -----------------
-Result<std::unique_ptr<FirstStageMount>> FirstStageMount::Create() {
- auto fstab = ReadFirstStageFstab();
+Result<std::unique_ptr<FirstStageMount>> FirstStageMount::Create(const std::string& cmdline) {
+ Result<Fstab> fstab;
+ if (IsMicrodroid()) {
+ fstab = ReadFirstStageFstabMicrodroid(cmdline);
+ } else {
+ fstab = ReadFirstStageFstabAndroid();
+ }
if (!fstab.ok()) {
return fstab.error();
}
@@ -784,7 +805,7 @@
return;
}
- auto fstab = ReadFirstStageFstab();
+ auto fstab = ReadFirstStageFstabAndroid();
if (!fstab.ok()) {
LOG(ERROR) << fstab.error();
return;
diff --git a/init/first_stage_mount.h b/init/first_stage_mount.h
index ab14966..54501d8 100644
--- a/init/first_stage_mount.h
+++ b/init/first_stage_mount.h
@@ -28,7 +28,7 @@
virtual ~FirstStageMount() = default;
// The factory method to create a FirstStageMount instance.
- static Result<std::unique_ptr<FirstStageMount>> Create();
+ static Result<std::unique_ptr<FirstStageMount>> Create(const std::string& cmdline);
// Creates devices and logical partitions from storage devices
virtual bool DoCreateDevices() = 0;
// Mounts fstab entries read from device tree.