Add a way to add a vendor disk image when launching Microdroid VM
This is a first patch in a series that adds support for "pluggable"
vendor images in Microdroid VMs.
In this patch virtmanager passes the vendor disk image to crosvm
invocation to make it available to guest Micrdroid.
Only callers with USE_CUSTOM_VIRTUAL_MACHINE permission can configure
the vendor image used in Microdroid.
Bug: 285855433
Test: presubmit
Test: vm run-microdroid --vendor /data/local/tmp/test_microdroid_vendor_image.img
Change-Id: I376468d6ef7dd675856f40b1361ca5d8a96cefb5
diff --git a/tests/vendor_images/Android.bp b/tests/vendor_images/Android.bp
new file mode 100644
index 0000000..ce88b02
--- /dev/null
+++ b/tests/vendor_images/Android.bp
@@ -0,0 +1,8 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_filesystem {
+ name: "test_microdroid_vendor_image",
+ type: "ext4",
+}
diff --git a/virtualizationmanager/src/aidl.rs b/virtualizationmanager/src/aidl.rs
index dd74d55..446641a 100644
--- a/virtualizationmanager/src/aidl.rs
+++ b/virtualizationmanager/src/aidl.rs
@@ -20,7 +20,7 @@
use crate::composite::make_composite_image;
use crate::crosvm::{CrosvmConfig, DiskFile, PayloadState, VmContext, VmInstance, VmState};
use crate::debug_config::DebugConfig;
-use crate::payload::{add_microdroid_payload_images, add_microdroid_system_images};
+use crate::payload::{add_microdroid_payload_images, add_microdroid_system_images, add_microdroid_vendor_image};
use crate::selinux::{getfilecon, SeContext};
use android_os_permissions_aidl::aidl::android::os::IPermissionController;
use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::{
@@ -620,6 +620,10 @@
}
vm_config.taskProfiles = custom_config.taskProfiles.clone();
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)
+ }
}
if config.memoryMib > 0 {
diff --git a/virtualizationmanager/src/payload.rs b/virtualizationmanager/src/payload.rs
index 33659d4..c11834d 100644
--- a/virtualizationmanager/src/payload.rs
+++ b/virtualizationmanager/src/payload.rs
@@ -398,6 +398,18 @@
.collect()
}
+pub fn add_microdroid_vendor_image(vendor_image: File, vm_config: &mut VirtualMachineRawConfig) {
+ vm_config.disks.push(DiskImage {
+ image: None,
+ writable: false,
+ partitions: vec![Partition {
+ label: "microdroid-vendor".to_owned(),
+ image: Some(ParcelFileDescriptor::new(vendor_image)),
+ writable: false,
+ }],
+ })
+}
+
pub fn add_microdroid_system_images(
config: &VirtualMachineAppConfig,
instance_file: File,
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
index 6a0bf7c..2b762c4 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
@@ -105,6 +105,9 @@
* List of task profile names to apply for the VM
*/
String[] taskProfiles;
+
+ /** A disk image containing vendor specific modules. */
+ @nullable ParcelFileDescriptor vendorImage;
}
/** Configuration parameters guarded by android.permission.USE_CUSTOM_VIRTUAL_MACHINE */
diff --git a/vm/src/main.rs b/vm/src/main.rs
index 0800f57..d7c2c4d 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -115,6 +115,10 @@
/// Path to custom kernel image to use when booting Microdroid.
#[clap(long)]
kernel: Option<PathBuf>,
+
+ /// Path to disk image containing vendor-specific modules.
+ #[clap(long)]
+ vendor: Option<PathBuf>,
},
/// Run a virtual machine with Microdroid inside
RunMicrodroid {
@@ -179,6 +183,10 @@
/// Path to custom kernel image to use when booting Microdroid.
#[clap(long)]
kernel: Option<PathBuf>,
+
+ /// Path to disk image containing vendor-specific modules.
+ #[clap(long)]
+ vendor: Option<PathBuf>,
},
/// Run a virtual machine
Run {
@@ -299,6 +307,7 @@
extra_idsigs,
gdb,
kernel,
+ vendor,
} => command_run_app(
name,
get_service()?.as_ref(),
@@ -320,6 +329,7 @@
&extra_idsigs,
gdb,
kernel.as_deref(),
+ vendor.as_deref(),
),
Opt::RunMicrodroid {
name,
@@ -336,6 +346,7 @@
task_profiles,
gdb,
kernel,
+ vendor,
} => command_run_microdroid(
name,
get_service()?.as_ref(),
@@ -352,6 +363,7 @@
task_profiles,
gdb,
kernel.as_deref(),
+ vendor.as_deref(),
),
Opt::Run { name, config, cpu_topology, task_profiles, console, console_in, log, gdb } => {
command_run(
diff --git a/vm/src/run.rs b/vm/src/run.rs
index 84072ca..64da2d9 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -65,6 +65,7 @@
extra_idsigs: &[PathBuf],
gdb: Option<NonZeroU16>,
kernel: Option<&Path>,
+ vendor: Option<&Path>,
) -> Result<(), Error> {
let apk_file = File::open(apk).context("Failed to open APK file")?;
@@ -122,6 +123,8 @@
let kernel = kernel.map(|p| open_parcel_file(p, false)).transpose()?;
+ let vendor = vendor.map(|p| open_parcel_file(p, false)).transpose()?;
+
let extra_idsig_files: Result<Vec<File>, _> = extra_idsigs.iter().map(File::open).collect();
let extra_idsig_fds = extra_idsig_files?.into_iter().map(ParcelFileDescriptor::new).collect();
@@ -144,6 +147,7 @@
customKernelImage: kernel,
gdbPort: gdb.map(u16::from).unwrap_or(0) as i32, // 0 means no gdb
taskProfiles: task_profiles,
+ vendorImage: vendor,
};
let config = VirtualMachineConfig::AppConfig(VirtualMachineAppConfig {
@@ -203,6 +207,7 @@
task_profiles: Vec<String>,
gdb: Option<NonZeroU16>,
kernel: Option<&Path>,
+ vendor: Option<&Path>,
) -> Result<(), Error> {
let apk = find_empty_payload_apk_path()?;
println!("found path {}", apk.display());
@@ -236,6 +241,7 @@
&extra_sig,
gdb,
kernel,
+ vendor,
)
}