Pass VM config by FD rather than filename.
Bug: 184131756
Test: atest VirtualizationTestCases
Change-Id: Iba739bc8de941b68a88090438743d9f54ba0380c
diff --git a/virtmanager/aidl/android/system/virtmanager/IVirtManager.aidl b/virtmanager/aidl/android/system/virtmanager/IVirtManager.aidl
index ab03c18..c2fc719 100644
--- a/virtmanager/aidl/android/system/virtmanager/IVirtManager.aidl
+++ b/virtmanager/aidl/android/system/virtmanager/IVirtManager.aidl
@@ -23,7 +23,8 @@
* Start the VM with the given config file, and return a handle to it. If `logFd` is provided
* then console logs from the VM will be sent to it.
*/
- IVirtualMachine startVm(String configPath, in @nullable ParcelFileDescriptor logFd);
+ IVirtualMachine startVm(
+ in ParcelFileDescriptor configFd, in @nullable ParcelFileDescriptor logFd);
/**
* Get a list of all currently running VMs. This method is only intended for debug purposes,
diff --git a/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl b/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl
index d877a56..9003bc3 100644
--- a/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl
+++ b/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl
@@ -19,10 +19,4 @@
parcelable VirtualMachineDebugInfo {
/** The CID assigned to the VM. */
int cid;
-
- /**
- * The filename of the config file used to start the VM. This may have changed since it was
- * read so it shouldn't be trusted; it is only stored for debugging purposes.
- */
- String configPath;
}
diff --git a/virtmanager/src/aidl.rs b/virtmanager/src/aidl.rs
index 8c963d2..ff8ab30 100644
--- a/virtmanager/src/aidl.rs
+++ b/virtmanager/src/aidl.rs
@@ -50,7 +50,7 @@
/// Returns a binder `IVirtualMachine` object referring to it, as a handle for the client.
fn startVm(
&self,
- config_path: &str,
+ config_fd: &ParcelFileDescriptor,
log_fd: Option<&ParcelFileDescriptor>,
) -> binder::Result<Strong<dyn IVirtualMachine>> {
let state = &mut *self.state.lock().unwrap();
@@ -58,7 +58,7 @@
let log_fd = log_fd
.map(|fd| fd.as_ref().try_clone().map_err(|_| StatusCode::UNKNOWN_ERROR))
.transpose()?;
- let instance = Arc::new(start_vm(config_path, cid, log_fd)?);
+ let instance = Arc::new(start_vm(config_fd.as_ref(), cid, log_fd)?);
// TODO(qwandor): keep track of which CIDs are currently in use so that we can reuse them.
state.next_cid = state.next_cid.checked_add(1).ok_or(StatusCode::UNKNOWN_ERROR)?;
state.add_vm(Arc::downgrade(&instance));
@@ -74,13 +74,8 @@
let state = &mut *self.state.lock().unwrap();
let vms = state.vms();
- let cids = vms
- .into_iter()
- .map(|vm| VirtualMachineDebugInfo {
- cid: vm.cid as i32,
- configPath: vm.config_path.clone(),
- })
- .collect();
+ let cids =
+ vms.into_iter().map(|vm| VirtualMachineDebugInfo { cid: vm.cid as i32 }).collect();
Ok(cids)
}
@@ -193,13 +188,13 @@
/// Start a new VM instance from the given VM config filename. This assumes the VM is not already
/// running.
-fn start_vm(config_path: &str, cid: Cid, log_fd: Option<File>) -> binder::Result<VmInstance> {
- let config = VmConfig::load(config_path).map_err(|e| {
- error!("Failed to load VM config {}: {:?}", config_path, e);
+fn start_vm(config_file: &File, cid: Cid, log_fd: Option<File>) -> binder::Result<VmInstance> {
+ let config = VmConfig::load(config_file).map_err(|e| {
+ error!("Failed to load VM config from {:?}: {:?}", config_file, e);
StatusCode::BAD_VALUE
})?;
- Ok(VmInstance::start(&config, cid, config_path, log_fd).map_err(|e| {
- error!("Failed to start VM {}: {:?}", config_path, e);
+ Ok(VmInstance::start(&config, cid, log_fd).map_err(|e| {
+ error!("Failed to start VM from {:?}: {:?}", config_file, e);
StatusCode::UNKNOWN_ERROR
})?)
}
diff --git a/virtmanager/src/config.rs b/virtmanager/src/config.rs
index d8cb06f..0b12c0b 100644
--- a/virtmanager/src/config.rs
+++ b/virtmanager/src/config.rs
@@ -14,7 +14,7 @@
//! Function and types for VM configuration.
-use anyhow::{bail, Context, Error};
+use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io::BufReader;
@@ -51,8 +51,7 @@
}
/// Load the configuration for a VM from the given JSON file.
- pub fn load(path: &str) -> Result<VmConfig, Error> {
- let file = File::open(path).with_context(|| format!("Failed to open {}", path))?;
+ pub fn load(file: &File) -> Result<VmConfig, Error> {
let buffered = BufReader::new(file);
Ok(serde_json::from_reader(buffered)?)
}
diff --git a/virtmanager/src/crosvm.rs b/virtmanager/src/crosvm.rs
index 814a1a7..c865357 100644
--- a/virtmanager/src/crosvm.rs
+++ b/virtmanager/src/crosvm.rs
@@ -30,27 +30,19 @@
child: Child,
/// The CID assigned to the VM for vsock communication.
pub cid: Cid,
- /// The filename of the config file that was used to start the VM. This may have changed since
- /// it was read so it shouldn't be trusted; it is only stored for debugging purposes.
- pub config_path: String,
}
impl VmInstance {
/// Create a new `VmInstance` for the given process.
- fn new(child: Child, cid: Cid, config_path: &str) -> VmInstance {
- VmInstance { child, cid, config_path: config_path.to_owned() }
+ fn new(child: Child, cid: Cid) -> VmInstance {
+ VmInstance { child, cid }
}
/// Start an instance of `crosvm` to manage a new VM. The `crosvm` instance will be killed when
/// the `VmInstance` is dropped.
- pub fn start(
- config: &VmConfig,
- cid: Cid,
- config_path: &str,
- log_fd: Option<File>,
- ) -> Result<VmInstance, Error> {
+ pub fn start(config: &VmConfig, cid: Cid, log_fd: Option<File>) -> Result<VmInstance, Error> {
let child = run_vm(config, cid, log_fd)?;
- Ok(VmInstance::new(child, cid, config_path))
+ Ok(VmInstance::new(child, cid))
}
}