Merge "Add a skeleton virtualizationmaintenance service" into main
diff --git a/virtualizationservice/Android.bp b/virtualizationservice/Android.bp
index 843873b..38a9ec5 100644
--- a/virtualizationservice/Android.bp
+++ b/virtualizationservice/Android.bp
@@ -23,6 +23,7 @@
rustlibs: [
"android.hardware.security.rkp-V3-rust",
"android.system.virtualizationcommon-rust",
+ "android.system.virtualizationmaintenance-rust",
"android.system.virtualizationservice-rust",
"android.system.virtualizationservice_internal-rust",
"android.system.virtualmachineservice-rust",
diff --git a/virtualizationservice/aidl/Android.bp b/virtualizationservice/aidl/Android.bp
index 8ca375a..66de092 100644
--- a/virtualizationservice/aidl/Android.bp
+++ b/virtualizationservice/aidl/Android.bp
@@ -55,6 +55,23 @@
}
aidl_interface {
+ name: "android.system.virtualizationmaintenance",
+ srcs: ["android/system/virtualizationmaintenance/**/*.aidl"],
+ unstable: true,
+ backend: {
+ java: {
+ sdk_version: "module_current",
+ },
+ rust: {
+ enabled: true,
+ apex_available: [
+ "com.android.virt",
+ ],
+ },
+ },
+}
+
+aidl_interface {
name: "android.system.virtualmachineservice",
srcs: ["android/system/virtualmachineservice/**/*.aidl"],
imports: [
diff --git a/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationMaintenance.aidl b/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationMaintenance.aidl
new file mode 100644
index 0000000..161673a
--- /dev/null
+++ b/virtualizationservice/aidl/android/system/virtualizationmaintenance/IVirtualizationMaintenance.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualizationmaintenance;
+
+interface IVirtualizationMaintenance {
+ void appRemoved(int userId, int appId);
+
+ void userRemoved(int userId);
+
+ // TODO: Something for daily reconciliation
+}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index c7ae5f0..c7a33ba 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -59,7 +59,9 @@
IGlobalVmContext::{BnGlobalVmContext, IGlobalVmContext},
IVfioHandler::VfioDev::VfioDev,
IVfioHandler::{BpVfioHandler, IVfioHandler},
- IVirtualizationServiceInternal::IVirtualizationServiceInternal,
+ IVirtualizationServiceInternal::{
+ BnVirtualizationServiceInternal, IVirtualizationServiceInternal,
+ },
};
use virtualmachineservice::IVirtualMachineService::VM_TOMBSTONES_SERVICE_PORT;
use vsock::{VsockListener, VsockStream};
@@ -67,8 +69,6 @@
/// The unique ID of a VM used (together with a port number) for vsock communication.
pub type Cid = u32;
-pub const BINDER_SERVICE_IDENTIFIER: &str = "android.system.virtualizationservice";
-
/// Directory in which to write disk image files used while running VMs.
pub const TEMPORARY_DIRECTORY: &str = "/data/misc/virtualizationservice";
@@ -165,7 +165,7 @@
}
impl VirtualizationServiceInternal {
- pub fn init() -> VirtualizationServiceInternal {
+ pub fn init() -> Strong<dyn IVirtualizationServiceInternal> {
let service = VirtualizationServiceInternal::default();
std::thread::spawn(|| {
@@ -174,7 +174,7 @@
}
});
- service
+ BnVirtualizationServiceInternal::new_binder(service, BinderFeatures::default())
}
}
diff --git a/virtualizationservice/src/main.rs b/virtualizationservice/src/main.rs
index ad21e89..97bb38f 100644
--- a/virtualizationservice/src/main.rs
+++ b/virtualizationservice/src/main.rs
@@ -16,18 +16,15 @@
mod aidl;
mod atom;
+mod maintenance;
mod remote_provisioning;
mod rkpvm;
-use crate::aidl::{
- remove_temporary_dir, BINDER_SERVICE_IDENTIFIER, TEMPORARY_DIRECTORY,
- VirtualizationServiceInternal
-};
+use crate::aidl::{remove_temporary_dir, VirtualizationServiceInternal, TEMPORARY_DIRECTORY};
use android_logger::{Config, FilterBuilder};
-use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::IVirtualizationServiceInternal::BnVirtualizationServiceInternal;
-use anyhow::Error;
-use binder::{register_lazy_service, BinderFeatures, ProcessState, ThreadState};
-use log::{info, LevelFilter};
+use anyhow::{bail, Context, Error, Result};
+use binder::{register_lazy_service, ProcessState, ThreadState};
+use log::{error, info, LevelFilter};
use std::fs::{create_dir, read_dir};
use std::os::unix::raw::{pid_t, uid_t};
use std::path::Path;
@@ -35,6 +32,8 @@
const LOG_TAG: &str = "VirtualizationService";
pub(crate) const REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME: &str =
"android.hardware.security.keymint.IRemotelyProvisionedComponent/avf";
+const INTERNAL_SERVICE_NAME: &str = "android.system.virtualizationservice";
+const MAINTENANCE_SERVICE_NAME: &str = "android.system.virtualizationmaintenance";
fn get_calling_pid() -> pid_t {
ThreadState::get_calling_pid()
@@ -45,6 +44,13 @@
}
fn main() {
+ if let Err(e) = try_main() {
+ error!("failed with {e:?}");
+ std::process::exit(1);
+ }
+}
+
+fn try_main() -> Result<()> {
android_logger::init_once(
Config::default()
.with_tag(LOG_TAG)
@@ -57,31 +63,33 @@
),
);
- clear_temporary_files().expect("Failed to delete old temporary files");
+ clear_temporary_files().context("Failed to delete old temporary files")?;
let common_dir_path = Path::new(TEMPORARY_DIRECTORY).join("common");
- create_dir(common_dir_path).expect("Failed to create common directory");
+ create_dir(common_dir_path).context("Failed to create common directory")?;
ProcessState::start_thread_pool();
-
- let service = VirtualizationServiceInternal::init();
- let service = BnVirtualizationServiceInternal::new_binder(service, BinderFeatures::default());
- register_lazy_service(BINDER_SERVICE_IDENTIFIER, service.as_binder()).unwrap();
- info!("Registered Binder service {}.", BINDER_SERVICE_IDENTIFIER);
+ register(INTERNAL_SERVICE_NAME, VirtualizationServiceInternal::init())?;
if cfg!(remote_attestation) {
// The IRemotelyProvisionedComponent service is only supposed to be triggered by rkpd for
// RKP VM attestation.
- let remote_provisioning_service = remote_provisioning::new_binder();
- register_lazy_service(
- REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME,
- remote_provisioning_service.as_binder(),
- )
- .unwrap();
- info!("Registered Binder service {}.", REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME);
+ register(REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME, remote_provisioning::new_binder())?;
+ }
+
+ if cfg!(llpvm_changes) {
+ register(MAINTENANCE_SERVICE_NAME, maintenance::new_binder())?;
}
ProcessState::join_thread_pool();
+ bail!("Thread pool unexpectedly ended");
+}
+
+fn register<T: binder::FromIBinder + ?Sized>(name: &str, service: binder::Strong<T>) -> Result<()> {
+ register_lazy_service(name, service.as_binder())
+ .with_context(|| format!("Failed to register {name}"))?;
+ info!("Registered Binder service {name}.");
+ Ok(())
}
/// Remove any files under `TEMPORARY_DIRECTORY`.
diff --git a/virtualizationservice/src/maintenance.rs b/virtualizationservice/src/maintenance.rs
new file mode 100644
index 0000000..191d39a
--- /dev/null
+++ b/virtualizationservice/src/maintenance.rs
@@ -0,0 +1,44 @@
+// Copyright 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use android_system_virtualizationmaintenance::aidl::android::system::virtualizationmaintenance;
+use anyhow::anyhow;
+use binder::{BinderFeatures, ExceptionCode, Interface, IntoBinderResult, Strong};
+use virtualizationmaintenance::IVirtualizationMaintenance::{
+ BnVirtualizationMaintenance, IVirtualizationMaintenance,
+};
+
+pub(crate) fn new_binder() -> Strong<dyn IVirtualizationMaintenance> {
+ BnVirtualizationMaintenance::new_binder(
+ VirtualizationMaintenanceService {},
+ BinderFeatures::default(),
+ )
+}
+
+pub struct VirtualizationMaintenanceService;
+
+impl Interface for VirtualizationMaintenanceService {}
+
+#[allow(non_snake_case)]
+impl IVirtualizationMaintenance for VirtualizationMaintenanceService {
+ fn appRemoved(&self, _user_id: i32, _app_id: i32) -> binder::Result<()> {
+ Err(anyhow!("appRemoved not supported"))
+ .or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION)
+ }
+
+ fn userRemoved(&self, _user_id: i32) -> binder::Result<()> {
+ Err(anyhow!("userRemoved not supported"))
+ .or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION)
+ }
+}