Run VirtualMachineService only for Microdroid
Other VMs don't (actually shouldn't) make use of it. There's no need to
run the service.
Bug: 381124535
Test: N/A
Change-Id: Icfe96573a5bd178b01de4752080ece10d7f5d30c
diff --git a/android/virtmgr/src/aidl.rs b/android/virtmgr/src/aidl.rs
index 9a733b6..55de0af 100644
--- a/android/virtmgr/src/aidl.rs
+++ b/android/virtmgr/src/aidl.rs
@@ -445,20 +445,25 @@
let context = EarlyVmContext::new(cid, temp_dir.clone())
.context(format!("Can't create early vm contexts for {cid}"))
.or_service_specific_exception(-1)?;
- let service = VirtualMachineService::new_binder(self.state.clone(), cid).as_binder();
- // Start VM service listening for connections from the new CID on port=CID.
- let port = cid;
- let (vm_server, _) = RpcServer::new_vsock(service, cid, port)
- .context(format!("Could not start RpcServer on port {port}"))
- .or_service_specific_exception(-1)?;
- vm_server.start();
- Ok((VmContext::new(Strong::new(Box::new(context)), vm_server), cid, temp_dir))
+ if requires_vm_service(config) {
+ // Start VM service listening for connections from the new CID on port=CID.
+ let service = VirtualMachineService::new_binder(self.state.clone(), cid).as_binder();
+ let port = cid;
+ let (vm_server, _) = RpcServer::new_vsock(service, cid, port)
+ .context(format!("Could not start RpcServer on port {port}"))
+ .or_service_specific_exception(-1)?;
+ vm_server.start();
+ Ok((VmContext::new(Strong::new(Box::new(context)), Some(vm_server)), cid, temp_dir))
+ } else {
+ Ok((VmContext::new(Strong::new(Box::new(context)), None), cid, temp_dir))
+ }
}
fn create_vm_context(
&self,
requester_debug_pid: pid_t,
+ config: &VirtualMachineConfig,
) -> binder::Result<(VmContext, Cid, PathBuf)> {
const NUM_ATTEMPTS: usize = 5;
@@ -466,6 +471,12 @@
let vm_context = GLOBAL_SERVICE.allocateGlobalVmContext(requester_debug_pid)?;
let cid = vm_context.getCid()? as Cid;
let temp_dir: PathBuf = vm_context.getTemporaryDirectory()?.into();
+
+ // We don't need to start the VM service for custom VMs.
+ if !requires_vm_service(config) {
+ return Ok((VmContext::new(vm_context, None), cid, temp_dir));
+ }
+
let service = VirtualMachineService::new_binder(self.state.clone(), cid).as_binder();
// Start VM service listening for connections from the new CID on port=CID.
@@ -473,7 +484,7 @@
match RpcServer::new_vsock(service, cid, port) {
Ok((vm_server, _)) => {
vm_server.start();
- return Ok((VmContext::new(vm_context, vm_server), cid, temp_dir));
+ return Ok((VmContext::new(vm_context, Some(vm_server)), cid, temp_dir));
}
Err(err) => {
warn!("Could not start RpcServer on port {}: {}", port, err);
@@ -509,7 +520,7 @@
let (vm_context, cid, temporary_directory) = if cfg!(early) {
self.create_early_vm_context(config)?
} else {
- self.create_vm_context(requester_debug_pid)?
+ self.create_vm_context(requester_debug_pid, config)?
};
if is_custom_config(config) {
@@ -820,6 +831,17 @@
}
}
+/// Returns whether a VM config requires VirtualMachineService running on the host. Only Microdroid
+/// VM (i.e. AppConfig) requires it. However, a few Microdroid tests use RawConfig for Microdroid
+/// VM. To handle the exceptional case, we use name as a second criteria; if the name is
+/// "microdroid" we run VirtualMachineService
+fn requires_vm_service(config: &VirtualMachineConfig) -> bool {
+ match config {
+ VirtualMachineConfig::AppConfig(_) => true,
+ VirtualMachineConfig::RawConfig(config) => config.name == "microdroid",
+ }
+}
+
fn extract_vendor_hashtree_digest(config: &VirtualMachineConfig) -> Result<Option<Vec<u8>>> {
let VirtualMachineConfig::AppConfig(config) = config else {
return Ok(None);
diff --git a/android/virtmgr/src/crosvm.rs b/android/virtmgr/src/crosvm.rs
index 46f4e80..1ccabec 100644
--- a/android/virtmgr/src/crosvm.rs
+++ b/android/virtmgr/src/crosvm.rs
@@ -360,12 +360,15 @@
#[allow(dead_code)] // Keeps the global context alive
pub(crate) global_context: Strong<dyn IGlobalVmContext>,
#[allow(dead_code)] // Keeps the server alive
- vm_server: RpcServer,
+ vm_server: Option<RpcServer>,
}
impl VmContext {
/// Construct new VmContext.
- pub fn new(global_context: Strong<dyn IGlobalVmContext>, vm_server: RpcServer) -> VmContext {
+ pub fn new(
+ global_context: Strong<dyn IGlobalVmContext>,
+ vm_server: Option<RpcServer>,
+ ) -> VmContext {
VmContext { global_context, vm_server }
}
}
@@ -655,7 +658,9 @@
// Now that the VM has been killed, shut down the VirtualMachineService
// server to eagerly free up the server threads.
- self.vm_context.vm_server.shutdown()?;
+ if let Some(vm_server) = &self.vm_context.vm_server {
+ vm_server.shutdown()?;
+ }
Ok(())
}
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
index fefedc9..630df87 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
@@ -405,6 +405,7 @@
VIRT_APEX + "bin/vm run",
"--console " + CONSOLE_PATH,
"--log " + LOG_PATH,
+ "--name " + "microdroid", // to still be seen as microdroid vm
configPath);
PipedInputStream pis = new PipedInputStream();