Add VirtualMachineService skeleton code
VirtualMachineService (the name isn't yet fixed) is a binder service
between virt service and guest VMs. Guest VMs can notify that it's ready
over VirtualMachineService.
Bug: 191845268
Test: atest MicrodroidHostTestCases
Change-Id: I80c529f104fe184a1bdbee25805c7871392336d5
diff --git a/microdroid_manager/Android.bp b/microdroid_manager/Android.bp
index a082beb..95a7014 100644
--- a/microdroid_manager/Android.bp
+++ b/microdroid_manager/Android.bp
@@ -9,8 +9,12 @@
edition: "2018",
prefer_rlib: true,
rustlibs: [
+ "android.system.virtualizationservice-rust",
+ "android.system.virtualmachineservice-rust",
"libanyhow",
"libapkverify",
+ "libbinder_rpc_unstable_bindgen",
+ "libbinder_rs",
"libkernlog",
"liblibc",
"liblog_rust",
@@ -22,6 +26,9 @@
"libserde_json",
"libvsock",
],
+ shared_libs: [
+ "libbinder_rpc_unstable",
+ ],
init_rc: ["microdroid_manager.rc"],
}
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index d7e256b..2fb7fdd 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -19,6 +19,8 @@
use anyhow::{anyhow, bail, Context, Result};
use apkverify::verify;
+use binder::unstable_api::{new_spibinder, AIBinder};
+use binder::{FromIBinder, Strong};
use log::{error, info, warn};
use microdroid_payload_config::{Task, TaskType, VmPayloadConfig};
use rustutils::system_properties::PropertyWatcher;
@@ -30,9 +32,35 @@
use std::time::Duration;
use vsock::VsockStream;
+use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
+
const WAIT_TIMEOUT: Duration = Duration::from_secs(10);
const DM_MOUNTED_APK_PATH: &str = "/dev/block/mapper/microdroid-apk";
+/// The CID representing the host VM
+const VMADDR_CID_HOST: u32 = 2;
+
+/// Port number that virtualizationservice listens on connections from the guest VMs for the
+/// VirtualMachineService binder service
+/// Sync with virtualizationservice/src/aidl.rs
+const PORT_VM_BINDER_SERVICE: u32 = 5000;
+
+fn get_vms_rpc_binder() -> Result<Strong<dyn IVirtualMachineService>> {
+ // SAFETY: AIBinder returned by RpcClient has correct reference count, and the ownership can be
+ // safely taken by new_spibinder.
+ let ibinder = unsafe {
+ new_spibinder(binder_rpc_unstable_bindgen::RpcClient(
+ VMADDR_CID_HOST,
+ PORT_VM_BINDER_SERVICE,
+ ) as *mut AIBinder)
+ };
+ if let Some(ibinder) = ibinder {
+ <dyn IVirtualMachineService>::try_from(ibinder).context("Cannot connect to RPC service")
+ } else {
+ bail!("Invalid raw AIBinder")
+ }
+}
+
fn main() -> Result<()> {
kernlog::init()?;
info!("started.");
@@ -44,6 +72,11 @@
return Err(err);
}
+ // TODO(b/191845268): microdroid_manager should use this binder to communicate with the host
+ if let Err(err) = get_vms_rpc_binder() {
+ error!("cannot connect to VirtualMachineService: {}", err);
+ }
+
if !metadata.payload_config_path.is_empty() {
let config = load_config(Path::new(&metadata.payload_config_path))?;