Propagate to Microdroid whether it should mount vendor partition
This is implemented by setting passing the
androidboot.microdroid.mount_vendor=1 to the cmdline of the Microdroid
kernel. The first_stage_init will parse the cmdline, and mount the
/vendor partition if it sees the value.
Bug: 285855433
Test: atest virtualizationmanager_device_test
Test: atest MicrodroidTestApp
Change-Id: I61b658a5c740488ff0591f00b2fee66b64b63c46
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 5440695..2d3f084 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -23,6 +23,10 @@
"apex",
"linkerconfig",
"second_stage_resources",
+
+ // Ideally we should only create the /vendor for Microdroid VMs that will mount /vendor, but
+ // for the time being we will just create it unconditionally.
+ "vendor",
]
microdroid_symlinks = [
diff --git a/microdroid/bootconfig.x86_64 b/microdroid/bootconfig.x86_64
index 6076889..eed9212 100644
--- a/microdroid/bootconfig.x86_64
+++ b/microdroid/bootconfig.x86_64
@@ -1 +1 @@
-androidboot.boot_devices = pci0000:00/0000:00:04.0,pci0000:00/0000:00:05.0,pci0000:00/0000:00:06.0
+androidboot.boot_devices = pci0000:00/0000:00:04.0,pci0000:00/0000:00:05.0,pci0000:00/0000:00:06.0,pci0000:00/0000:00:07.0
diff --git a/microdroid/fstab.microdroid b/microdroid/fstab.microdroid
index 9478c7c..da000b9 100644
--- a/microdroid/fstab.microdroid
+++ b/microdroid/fstab.microdroid
@@ -1 +1,7 @@
system /system ext4 noatime,ro,errors=panic wait,slotselect,avb=vbmeta,first_stage_mount,logical
+# This is a temporary solution to unblock other devs that depend on /vendor partition in Microdroid
+# The /vendor partition will only be mounted if the kernel cmdline contains
+# androidboot.microdroid.mount_vendor=1.
+# TODO(b/285855430): this should probably be defined in the DT
+# TODO(b/285855436): should be mounted on top of dm-verity device
+/dev/block/by-name/microdroid-vendor /vendor ext4 noatime,ro,errors=panic wait,first_stage_mount
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 4cebd4c..a3b56f9 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -1941,8 +1941,10 @@
.isEqualTo(OsConstants.S_IRUSR | OsConstants.S_IXUSR);
}
- // Taken from bionic/libs/kernel/uapi/linux/mounth.h.
+ // Taken from bionic/libc/kernel/uapi/linux/mount.h
+ private static final int MS_RDONLY = 1;
private static final int MS_NOEXEC = 8;
+ private static final int MS_NOATIME = 1024;
@Test
@CddTest(requirements = {"9.17/C-1-5"})
@@ -2040,6 +2042,36 @@
.contains("android.permission.USE_CUSTOM_VIRTUAL_MACHINE permission");
}
+ @Test
+ public void bootsWithVendorPartition() throws Exception {
+ assumeSupportedDevice();
+
+ grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
+
+ File vendorDiskImage =
+ new File("/data/local/tmp/cts/microdroid/test_microdroid_vendor_image.img");
+ VirtualMachineConfig config =
+ newVmConfigBuilder()
+ .setPayloadBinaryName("MicrodroidTestNativeLib.so")
+ .setVendorDiskImage(vendorDiskImage)
+ .setDebugLevel(DEBUG_LEVEL_FULL)
+ .build();
+
+ VirtualMachine vm = forceCreateNewVirtualMachine("test_boot_with_vendor", config);
+
+ TestResults testResults =
+ runVmTestService(
+ TAG,
+ vm,
+ (ts, tr) -> {
+ tr.mMountFlags = ts.getMountFlags("/vendor");
+ });
+
+ assertThat(testResults.mException).isNull();
+ int expectedFlags = MS_NOATIME | MS_RDONLY;
+ assertThat(testResults.mMountFlags & expectedFlags).isEqualTo(expectedFlags);
+ }
+
private static class VmShareServiceConnection implements ServiceConnection {
private final CountDownLatch mLatch = new CountDownLatch(1);
diff --git a/tests/vendor_images/Android.bp b/tests/vendor_images/Android.bp
index ce88b02..09c657c 100644
--- a/tests/vendor_images/Android.bp
+++ b/tests/vendor_images/Android.bp
@@ -5,4 +5,5 @@
android_filesystem {
name: "test_microdroid_vendor_image",
type: "ext4",
+ file_contexts: ":microdroid_vendor_file_contexts.gen",
}
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index 446641a..d0a8e85 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -579,6 +579,15 @@
Ok(DiskFile { image, writable: disk.writable })
}
+fn append_kernel_param(param: &str, vm_config: &mut VirtualMachineRawConfig) {
+ if let Some(ref mut params) = vm_config.params {
+ params.push(' ');
+ params.push_str(param)
+ } else {
+ vm_config.params = Some(param.to_owned())
+ }
+}
+
fn load_app_config(
config: &VirtualMachineAppConfig,
debug_config: &DebugConfig,
@@ -622,7 +631,8 @@
vm_config.gdbPort = custom_config.gdbPort;
if let Some(file) = custom_config.vendorImage.as_ref() {
- add_microdroid_vendor_image(clone_file(file)?, &mut vm_config)
+ add_microdroid_vendor_image(clone_file(file)?, &mut vm_config);
+ append_kernel_param("androidboot.microdroid.mount_vendor=1", &mut vm_config)
}
}
@@ -1353,4 +1363,19 @@
assert!(modified_orig == modified_new, "idsig file was updated unnecessarily");
Ok(())
}
+
+ #[test]
+ fn test_append_kernel_param_first_param() {
+ let mut vm_config = VirtualMachineRawConfig { ..Default::default() };
+ append_kernel_param("foo=1", &mut vm_config);
+ assert_eq!(vm_config.params, Some("foo=1".to_owned()))
+ }
+
+ #[test]
+ fn test_append_kernel_param() {
+ let mut vm_config =
+ VirtualMachineRawConfig { params: Some("foo=5".to_owned()), ..Default::default() };
+ append_kernel_param("bar=42", &mut vm_config);
+ assert_eq!(vm_config.params, Some("foo=5 bar=42".to_owned()))
+ }
}