Virtualizationservice makes payload disk image
with given APK, idsig, and config file.
To exercise the new execution mode, 'vm run-app' sub command is added.
$ vm <apk_path> <idsig_path> <config_path>
For example,
$ vm /data/local/tmp/MyApp.apk /data/local/tmp/MyApp.apk.idsig \
assets/config.json
Bug: 190503456
Test: MicrodroidHostTestCases, VirtualizationTestCases
Change-Id: Iceec9b34e9785a1ae36452bfc2653c3c045f4dfa
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index ce9a080..3f1660e 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -16,26 +16,35 @@
use crate::composite::make_composite_image;
use crate::crosvm::{CrosvmConfig, DiskFile, VmInstance};
+use crate::payload;
use crate::{Cid, FIRST_GUEST_CID};
+
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::IVirtualizationService;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::DiskImage::DiskImage;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualMachine::{
BnVirtualMachine, IVirtualMachine,
};
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualMachineCallback::IVirtualMachineCallback;
-use android_system_virtualizationservice::aidl::android::system::virtualizationservice::VirtualMachineConfig::VirtualMachineConfig;
+use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
+ VirtualMachineAppConfig::VirtualMachineAppConfig,
+ VirtualMachineConfig::VirtualMachineConfig,
+ VirtualMachineRawConfig::VirtualMachineRawConfig,
+};
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::VirtualMachineDebugInfo::VirtualMachineDebugInfo;
use android_system_virtualizationservice::binder::{
self, BinderFeatures, ExceptionCode, Interface, ParcelFileDescriptor, Status, Strong, ThreadState,
};
+use anyhow::Error;
use disk::QcowFile;
use log::{debug, error, warn};
+use microdroid_payload_config::VmPayloadConfig;
use std::convert::TryInto;
use std::ffi::CString;
use std::fs::{File, create_dir};
use std::os::unix::io::AsRawFd;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex, Weak};
+use vmconfig::VmConfig;
pub const BINDER_SERVICE_IDENTIFIER: &str = "android.system.virtualizationservice";
@@ -92,6 +101,22 @@
)
})?;
+ let mut opt_raw_config = None;
+ let config = match config {
+ VirtualMachineConfig::AppConfig(config) => {
+ let raw_config = load_app_config(config, &temporary_directory).map_err(|e| {
+ error!("Failed to load app config from {}: {}", &config.configPath, e);
+ new_binder_exception(
+ ExceptionCode::SERVICE_SPECIFIC,
+ format!("Failed to load app config from {}: {}", &config.configPath, e),
+ )
+ })?;
+ opt_raw_config.replace(raw_config);
+ opt_raw_config.as_ref().unwrap()
+ }
+ VirtualMachineConfig::RawConfig(config) => config,
+ };
+
// Assemble disk images if needed.
let disks = config
.disks
@@ -256,6 +281,34 @@
Ok(DiskFile { image, writable: disk.writable })
}
+fn load_app_config(
+ config: &VirtualMachineAppConfig,
+ temporary_directory: &Path,
+) -> Result<VirtualMachineRawConfig, Error> {
+ let apk_file = config.apk.as_ref().unwrap().as_ref();
+ let idsig_file = config.idsig.as_ref().unwrap().as_ref();
+ let config_path = &config.configPath;
+
+ let mut apk_zip = zip::ZipArchive::new(apk_file)?;
+ let config_file = apk_zip.by_name(config_path)?;
+ let vm_payload_config: VmPayloadConfig = serde_json::from_reader(config_file)?;
+
+ let os_name = &vm_payload_config.os.name;
+ let vm_config_path = PathBuf::from(format!("/apex/com.android.virt/etc/{}.json", os_name));
+ let vm_config_file = File::open(vm_config_path)?;
+ let mut vm_config = VmConfig::load(&vm_config_file)?;
+
+ vm_config.disks.push(payload::make_disk_image(
+ format!("/proc/self/fd/{}", apk_file.as_raw_fd()).into(),
+ format!("/proc/self/fd/{}", idsig_file.as_raw_fd()).into(),
+ config_path,
+ &vm_payload_config.apexes,
+ temporary_directory,
+ )?);
+
+ vm_config.to_parcelable()
+}
+
/// Generates a unique filename to use for a composite disk image.
fn make_composite_image_filenames(
temporary_directory: &Path,