Remove cid parameter from VirtualMachineService
Cid parameter has been passed just to identify the guest VMs. This makes
the server identify itself, with incoming vsock address.
Bug: 199259751
Test: atest MicrodroidHostTestCases ComposHostTestCases
Change-Id: I8dacfec80574fe765b96139cdecb6f3192728577
diff --git a/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl b/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
index fba83c8..8611898 100644
--- a/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
+++ b/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
@@ -31,19 +31,16 @@
/**
* Notifies that the payload has started.
- * TODO(b/191845268): remove cid parameter
*/
- void notifyPayloadStarted(int cid);
+ void notifyPayloadStarted();
/**
* Notifies that the payload is ready to serve.
- * TODO(b/191845268): remove cid parameter
*/
- void notifyPayloadReady(int cid);
+ void notifyPayloadReady();
/**
* Notifies that the payload has finished.
- * TODO(b/191845268): remove cid parameter
*/
- void notifyPayloadFinished(int cid, int exitCode);
+ void notifyPayloadFinished(int exitCode);
}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index fa6ee40..2f901b4 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -55,8 +55,10 @@
use std::fs::{create_dir, File, OpenOptions};
use std::io::{Error, ErrorKind, Write};
use std::num::NonZeroU32;
+use std::os::raw;
use std::os::unix::io::{FromRawFd, IntoRawFd};
use std::path::{Path, PathBuf};
+use std::ptr::null_mut;
use std::sync::{Arc, Mutex, Weak};
use vmconfig::VmConfig;
use vsock::{SockAddr, VsockListener, VsockStream};
@@ -345,15 +347,18 @@
});
// binder server for vm
- let state = service.state.clone(); // reference to state (not the state itself) is copied
+ let mut state = service.state.clone(); // reference to state (not the state itself) is copied
std::thread::spawn(move || {
- let mut service = VirtualMachineService::new_binder(state).as_binder();
+ let state_ptr = &mut state as *mut _ as *mut raw::c_void;
+
debug!("virtual machine service is starting as an RPC service.");
- // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
- // Plus the binder objects are threadsafe.
+ // SAFETY: factory function is only ever called by RunRpcServerWithFactory, within the
+ // lifetime of the state, with context taking the pointer value above (so a properly
+ // aligned non-null pointer to an initialized instance).
let retval = unsafe {
- binder_rpc_unstable_bindgen::RunRpcServer(
- service.as_native_mut() as *mut binder_rpc_unstable_bindgen::AIBinder,
+ binder_rpc_unstable_bindgen::RunRpcServerWithFactory(
+ Some(VirtualMachineService::factory),
+ state_ptr,
VM_BINDER_SERVICE_PORT as u32,
)
};
@@ -846,13 +851,14 @@
#[derive(Debug, Default)]
struct VirtualMachineService {
state: Arc<Mutex<State>>,
+ cid: Cid,
}
impl Interface for VirtualMachineService {}
impl IVirtualMachineService for VirtualMachineService {
- fn notifyPayloadStarted(&self, cid: i32) -> binder::Result<()> {
- let cid = cid as Cid;
+ fn notifyPayloadStarted(&self) -> binder::Result<()> {
+ let cid = self.cid;
if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
info!("VM having CID {} started payload", cid);
vm.update_payload_state(PayloadState::Started)
@@ -869,8 +875,8 @@
}
}
- fn notifyPayloadReady(&self, cid: i32) -> binder::Result<()> {
- let cid = cid as Cid;
+ fn notifyPayloadReady(&self) -> binder::Result<()> {
+ let cid = self.cid;
if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
info!("VM having CID {} payload is ready", cid);
vm.update_payload_state(PayloadState::Ready)
@@ -886,8 +892,8 @@
}
}
- fn notifyPayloadFinished(&self, cid: i32, exit_code: i32) -> binder::Result<()> {
- let cid = cid as Cid;
+ fn notifyPayloadFinished(&self, exit_code: i32) -> binder::Result<()> {
+ let cid = self.cid;
if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
info!("VM having CID {} finished payload", cid);
vm.update_payload_state(PayloadState::Finished)
@@ -905,9 +911,26 @@
}
impl VirtualMachineService {
- fn new_binder(state: Arc<Mutex<State>>) -> Strong<dyn IVirtualMachineService> {
+ // SAFETY: Service ownership is held by state, and the binder objects are threadsafe.
+ pub unsafe extern "C" fn factory(
+ cid: Cid,
+ context: *mut raw::c_void,
+ ) -> *mut binder_rpc_unstable_bindgen::AIBinder {
+ let state_ptr = context as *mut Arc<Mutex<State>>;
+ let state = state_ptr.as_ref().unwrap();
+ if let Some(vm) = state.lock().unwrap().get_vm(cid) {
+ let mut vm_service = vm.vm_service.lock().unwrap();
+ let service = vm_service.get_or_insert_with(|| Self::new_binder(state.clone(), cid));
+ service.as_binder().as_native_mut() as *mut binder_rpc_unstable_bindgen::AIBinder
+ } else {
+ error!("connection from cid={} is not from a guest VM", cid);
+ null_mut()
+ }
+ }
+
+ fn new_binder(state: Arc<Mutex<State>>, cid: Cid) -> Strong<dyn IVirtualMachineService> {
BnVirtualMachineService::new_binder(
- VirtualMachineService { state },
+ VirtualMachineService { state, cid },
BinderFeatures::default(),
)
}
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
index 4844657..8a5a7dd 100644
--- a/virtualizationservice/src/crosvm.rs
+++ b/virtualizationservice/src/crosvm.rs
@@ -29,6 +29,8 @@
use std::sync::{Arc, Mutex};
use std::thread;
use vsock::VsockStream;
+use android_system_virtualmachineservice::binder::Strong;
+use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
const CROSVM_PATH: &str = "/apex/com.android.virt/bin/crosvm";
@@ -132,6 +134,8 @@
pub callbacks: VirtualMachineCallbacks,
/// Input/output stream of the payload run in the VM.
pub stream: Mutex<Option<VsockStream>>,
+ /// VirtualMachineService binder object for the VM.
+ pub vm_service: Mutex<Option<Strong<dyn IVirtualMachineService>>>,
/// The latest lifecycle state which the payload reported itself to be in.
payload_state: Mutex<PayloadState>,
}
@@ -158,6 +162,7 @@
requester_debug_pid,
callbacks: Default::default(),
stream: Mutex::new(None),
+ vm_service: Mutex::new(None),
payload_state: Mutex::new(PayloadState::Starting),
})
}