diff --git a/microdroid/vm_payload/src/vm_payload_service.rs b/microdroid/vm_payload/src/vm_payload_service.rs index b0dd8912..098d2464 100644 --- a/microdroid/vm_payload/src/vm_payload_service.rs +++ b/microdroid/vm_payload/src/vm_payload_service.rs @@ -15,12 +15,12 @@ //! This module handles the interaction with virtual machine payload service. use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{ - IVmPayloadService, VM_PAYLOAD_SERVICE_NAME, VM_APK_CONTENTS_PATH}; + IVmPayloadService, VM_PAYLOAD_SERVICE_SOCKET_NAME, VM_APK_CONTENTS_PATH}; use anyhow::{Context, Result}; -use binder::{wait_for_interface, Strong, unstable_api::{AIBinder, new_spibinder}}; +use binder::{Strong, unstable_api::{AIBinder, new_spibinder}}; use lazy_static::lazy_static; use log::{error, info, Level}; -use rpcbinder::run_vsock_rpc_server; +use rpcbinder::{get_unix_domain_rpc_interface, run_vsock_rpc_server}; use std::ffi::CString; use std::os::raw::{c_char, c_void}; @@ -203,6 +203,6 @@ fn try_get_dice_attestation_cdi() -> Result> { } fn get_vm_payload_service() -> Result> { - wait_for_interface(VM_PAYLOAD_SERVICE_NAME) - .context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_NAME)) + get_unix_domain_rpc_interface(VM_PAYLOAD_SERVICE_SOCKET_NAME) + .context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_SOCKET_NAME)) } diff --git a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl index 4823bb83..f8e7d347 100644 --- a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl +++ b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl @@ -21,8 +21,8 @@ package android.system.virtualization.payload; * Microdroid Manager for execution. */ interface IVmPayloadService { - /** Name of the service IVmPayloadService. */ - const String VM_PAYLOAD_SERVICE_NAME = "virtual_machine_payload_service"; + /** Socket name of the service IVmPayloadService. */ + const String VM_PAYLOAD_SERVICE_SOCKET_NAME = "vm_payload_service"; /** Path to the APK contents path. */ const String VM_APK_CONTENTS_PATH = "/mnt/apk"; diff --git a/microdroid_manager/microdroid_manager.rc b/microdroid_manager/microdroid_manager.rc index 74a219d1..cfa70bda 100644 --- a/microdroid_manager/microdroid_manager.rc +++ b/microdroid_manager/microdroid_manager.rc @@ -6,3 +6,4 @@ service microdroid_manager /system/bin/microdroid_manager oneshot # SYS_BOOT is required to exec kexecload from microdroid_manager capabilities AUDIT_CONTROL SYS_ADMIN SYS_BOOT + socket vm_payload_service stream 0666 system system diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs index 73c36aac..4b4f996d 100644 --- a/microdroid_manager/src/main.rs +++ b/microdroid_manager/src/main.rs @@ -31,7 +31,7 @@ use android_system_virtualmachineservice::aidl::android::system::virtualmachines use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::VM_APK_CONTENTS_PATH; use anyhow::{anyhow, bail, ensure, Context, Error, Result}; use apkverify::{get_public_key_der, verify, V4Signature}; -use binder::{ProcessState, Strong}; +use binder::Strong; use diced_utils::cbor::{encode_header, encode_number}; use glob::glob; use itertools::sorted; @@ -397,7 +397,6 @@ fn try_run_payload(service: &Strong) -> Result wait_for_property_true(APK_MOUNT_DONE_PROP).context("Failed waiting for APK mount done")?; register_vm_payload_service(allow_restricted_apis, service.clone(), dice)?; - ProcessState::start_thread_pool(); system_properties::write("dev.bootcomplete", "1").context("set dev.bootcomplete")?; exec_task(task, service).context("Failed to run payload") diff --git a/microdroid_manager/src/vm_payload_service.rs b/microdroid_manager/src/vm_payload_service.rs index 159bf67d..fcfc79df 100644 --- a/microdroid_manager/src/vm_payload_service.rs +++ b/microdroid_manager/src/vm_payload_service.rs @@ -16,13 +16,17 @@ use crate::dice::DiceContext; use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{ - BnVmPayloadService, IVmPayloadService, VM_PAYLOAD_SERVICE_NAME}; + BnVmPayloadService, IVmPayloadService, VM_PAYLOAD_SERVICE_SOCKET_NAME}; use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService; -use anyhow::{Context, Result}; -use binder::{Interface, BinderFeatures, ExceptionCode, Status, Strong, add_service}; -use log::error; +use anyhow::{bail, Result}; +use binder::{Interface, BinderFeatures, ExceptionCode, Status, Strong}; +use log::{error, info}; use openssl::hkdf::hkdf; use openssl::md::Md; +use rpcbinder::run_init_unix_domain_rpc_server; +use std::sync::mpsc; +use std::thread; +use std::time::Duration; /// Implementation of `IVmPayloadService`. struct VmPayloadService { @@ -97,8 +101,29 @@ pub(crate) fn register_vm_payload_service( VmPayloadService::new(allow_restricted_apis, vm_service, dice), BinderFeatures::default(), ); - add_service(VM_PAYLOAD_SERVICE_NAME, vm_payload_binder.as_binder()) - .with_context(|| format!("Failed to register service {}", VM_PAYLOAD_SERVICE_NAME))?; - log::info!("{} is running", VM_PAYLOAD_SERVICE_NAME); - Ok(()) + let (sender, receiver) = mpsc::channel(); + thread::spawn(move || { + let retval = run_init_unix_domain_rpc_server( + vm_payload_binder.as_binder(), + VM_PAYLOAD_SERVICE_SOCKET_NAME, + || { + sender.send(()).unwrap(); + }, + ); + if retval { + info!( + "The RPC server at '{}' has shut down gracefully.", + VM_PAYLOAD_SERVICE_SOCKET_NAME + ); + } else { + error!("Premature termination of the RPC server '{}'.", VM_PAYLOAD_SERVICE_SOCKET_NAME); + } + }); + match receiver.recv_timeout(Duration::from_millis(200)) { + Ok(()) => { + info!("The RPC server '{}' is running.", VM_PAYLOAD_SERVICE_SOCKET_NAME); + Ok(()) + } + _ => bail!("Failed to register service '{}'", VM_PAYLOAD_SERVICE_SOCKET_NAME), + } }