Implement collecting VmStatus in microdroid_manager
Bug: 236253808
Test: Manually run statsd_testdrive 512 while running atest MicrodroidTestCase#testTelemetryPushedAtoms
Change-Id: I55ebb75f93943a3095f27c74fcef577a1d054865
diff --git a/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl b/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
index e8c1724..4fa5fa0 100644
--- a/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
+++ b/virtualizationservice/aidl/android/system/virtualmachineservice/IVirtualMachineService.aidl
@@ -16,6 +16,8 @@
package android.system.virtualmachineservice;
import android.system.virtualizationcommon.ErrorCode;
+import android.system.virtualmachineservice.VirtualMachineCpuStatus;
+import android.system.virtualmachineservice.VirtualMachineMemStatus;
/** {@hide} */
interface IVirtualMachineService {
@@ -56,4 +58,14 @@
* Notifies that an error has occurred inside the VM..
*/
void notifyError(ErrorCode errorCode, in String message);
+
+ /**
+ * Notifies the current CPU status of the VM.
+ */
+ void notifyCpuStatus(in VirtualMachineCpuStatus cpuStatus);
+
+ /**
+ * Notifies the current memory status of the VM.
+ */
+ void notifyMemStatus(in VirtualMachineMemStatus memStatus);
}
diff --git a/virtualizationservice/aidl/android/system/virtualmachineservice/VirtualMachineCpuStatus.aidl b/virtualizationservice/aidl/android/system/virtualmachineservice/VirtualMachineCpuStatus.aidl
new file mode 100644
index 0000000..307c3f9
--- /dev/null
+++ b/virtualizationservice/aidl/android/system/virtualmachineservice/VirtualMachineCpuStatus.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 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.virtualmachineservice;
+
+parcelable VirtualMachineCpuStatus {
+ long cpu_time_user;
+ long cpu_time_nice;
+ long cpu_time_sys;
+ long cpu_time_idle;
+}
diff --git a/virtualizationservice/aidl/android/system/virtualmachineservice/VirtualMachineMemStatus.aidl b/virtualizationservice/aidl/android/system/virtualmachineservice/VirtualMachineMemStatus.aidl
new file mode 100644
index 0000000..3de57c6
--- /dev/null
+++ b/virtualizationservice/aidl/android/system/virtualmachineservice/VirtualMachineMemStatus.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2022 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.virtualmachineservice;
+
+parcelable VirtualMachineMemStatus {
+ long mem_total;
+ long mem_free;
+ long mem_available;
+ long mem_buffer;
+ long mem_cached;
+}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index f956062..33102eb 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -14,13 +14,17 @@
//! Implementation of the AIDL interface of the VirtualizationService.
-use crate::atom::{write_vm_booted_stats, write_vm_creation_stats};
+use crate::atom::{
+ write_vm_booted_stats, write_vm_cpu_status_stats, write_vm_creation_stats,
+ write_vm_mem_status_stats,
+};
use crate::composite::make_composite_image;
use crate::crosvm::{CrosvmConfig, DiskFile, PayloadState, VmInstance, VmState};
use crate::payload::{add_microdroid_payload_images, add_microdroid_system_images};
+use crate::selinux::{getfilecon, SeContext};
use crate::{Cid, FIRST_GUEST_CID, SYSPROP_LAST_CID};
-use crate::selinux::{SeContext, getfilecon};
use android_os_permissions_aidl::aidl::android::os::IPermissionController;
+use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::ErrorCode::ErrorCode;
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
DeathReason::DeathReason,
DiskImage::DiskImage,
@@ -29,39 +33,42 @@
IVirtualizationService::IVirtualizationService,
Partition::Partition,
PartitionType::PartitionType,
- VirtualMachineAppConfig::{VirtualMachineAppConfig, Payload::Payload},
+ VirtualMachineAppConfig::{Payload::Payload, VirtualMachineAppConfig},
VirtualMachineConfig::VirtualMachineConfig,
VirtualMachineDebugInfo::VirtualMachineDebugInfo,
VirtualMachinePayloadConfig::VirtualMachinePayloadConfig,
VirtualMachineRawConfig::VirtualMachineRawConfig,
VirtualMachineState::VirtualMachineState,
};
+use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::{
+ IVirtualMachineService::{
+ BnVirtualMachineService, IVirtualMachineService, VM_BINDER_SERVICE_PORT,
+ VM_STREAM_SERVICE_PORT, VM_TOMBSTONES_SERVICE_PORT,
+ },
+ VirtualMachineCpuStatus::VirtualMachineCpuStatus,
+ VirtualMachineMemStatus::VirtualMachineMemStatus,
+};
+use anyhow::{anyhow, bail, Context, Result};
+use apkverify::{HashAlgorithm, V4Signature};
use binder::{
self, BinderFeatures, ExceptionCode, Interface, LazyServiceGuard, ParcelFileDescriptor,
SpIBinder, Status, StatusCode, Strong, ThreadState,
};
-use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::{
- BnVirtualMachineService, IVirtualMachineService, VM_BINDER_SERVICE_PORT,
- VM_STREAM_SERVICE_PORT, VM_TOMBSTONES_SERVICE_PORT,
-};
-use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::ErrorCode::ErrorCode;
-use anyhow::{anyhow, bail, Context, Result};
-use rpcbinder::run_rpc_server_with_factory;
use disk::QcowFile;
-use apkverify::{HashAlgorithm, V4Signature};
use log::{debug, error, info, warn};
-use microdroid_payload_config::{VmPayloadConfig, OsConfig, Task, TaskType};
+use microdroid_payload_config::{OsConfig, Task, TaskType, VmPayloadConfig};
+use rpcbinder::run_rpc_server_with_factory;
use rustutils::system_properties;
use semver::VersionReq;
use std::convert::TryInto;
use std::ffi::CStr;
use std::fs::{create_dir, File, OpenOptions};
-use std::io::{Error, ErrorKind, Write, Read};
+use std::io::{Error, ErrorKind, Read, Write};
use std::num::NonZeroU32;
use std::os::unix::io::{FromRawFd, IntoRawFd};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex, Weak};
-use tombstoned_client::{TombstonedConnection, DebuggerdDumpType};
+use tombstoned_client::{DebuggerdDumpType, TombstonedConnection};
use vmconfig::VmConfig;
use vsock::{VsockListener, VsockStream};
use zip::ZipArchive;
@@ -1168,6 +1175,36 @@
))
}
}
+
+ fn notifyCpuStatus(&self, status: &VirtualMachineCpuStatus) -> binder::Result<()> {
+ let cid = self.cid;
+ if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
+ info!("VM having CID {} encountered an error", cid);
+ write_vm_cpu_status_stats(vm.requester_uid as i32, &vm.name, status);
+ Ok(())
+ } else {
+ error!("notifyCurrentStatus is called from an unknown CID {}", cid);
+ Err(Status::new_service_specific_error_str(
+ -1,
+ Some(format!("cannot find a VM with CID {}", cid)),
+ ))
+ }
+ }
+
+ fn notifyMemStatus(&self, status: &VirtualMachineMemStatus) -> binder::Result<()> {
+ let cid = self.cid;
+ if let Some(vm) = self.state.lock().unwrap().get_vm(cid) {
+ info!("VM having CID {} encountered an error", cid);
+ write_vm_mem_status_stats(vm.requester_uid as i32, &vm.name, status);
+ Ok(())
+ } else {
+ error!("notifyCurrentStatus is called from an unknown CID {}", cid);
+ Err(Status::new_service_specific_error_str(
+ -1,
+ Some(format!("cannot find a VM with CID {}", cid)),
+ ))
+ }
+ }
}
impl VirtualMachineService {
diff --git a/virtualizationservice/src/atom.rs b/virtualizationservice/src/atom.rs
index eabb4cc..8c46ac5 100644
--- a/virtualizationservice/src/atom.rs
+++ b/virtualizationservice/src/atom.rs
@@ -22,11 +22,17 @@
VirtualMachineConfig::VirtualMachineConfig,
};
use android_system_virtualizationservice::binder::{Status, Strong};
+use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::{
+ VirtualMachineCpuStatus::VirtualMachineCpuStatus,
+ VirtualMachineMemStatus::VirtualMachineMemStatus,
+};
use anyhow::{anyhow, Result};
use binder::{ParcelFileDescriptor, ThreadState};
use log::{trace, warn};
use microdroid_payload_config::VmPayloadConfig;
-use statslog_virtualization_rust::{vm_booted, vm_creation_requested, vm_exited};
+use statslog_virtualization_rust::{
+ vm_booted, vm_cpu_status_reported, vm_creation_requested, vm_exited, vm_mem_status_reported,
+};
use std::time::{Duration, SystemTime};
use zip::ZipArchive;
@@ -206,3 +212,48 @@
Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
}
}
+
+/// Write the stats of VM cpu status to statsd
+pub fn write_vm_cpu_status_stats(
+ uid: i32,
+ vm_identifier: &String,
+ cpu_status: &VirtualMachineCpuStatus,
+) {
+ let vm_cpu_status_reported = vm_cpu_status_reported::VmCpuStatusReported {
+ uid,
+ vm_identifier,
+ cpu_time_user_millis: cpu_status.cpu_time_user,
+ cpu_time_nice_millis: cpu_status.cpu_time_nice,
+ cpu_time_sys_millis: cpu_status.cpu_time_sys,
+ cpu_time_idle_millis: cpu_status.cpu_time_idle,
+ };
+ match vm_cpu_status_reported.stats_write() {
+ Err(e) => {
+ warn!("statslog_rust failed with error: {}", e);
+ }
+ Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
+ }
+}
+
+/// Write the stats of VM memory status to statsd
+pub fn write_vm_mem_status_stats(
+ uid: i32,
+ vm_identifier: &String,
+ mem_status: &VirtualMachineMemStatus,
+) {
+ let vm_mem_status_reported = vm_mem_status_reported::VmMemStatusReported {
+ uid,
+ vm_identifier,
+ mem_total_kb: mem_status.mem_total,
+ mem_free_kb: mem_status.mem_free,
+ mem_available_kb: mem_status.mem_available,
+ mem_buffer_kb: mem_status.mem_buffer,
+ mem_cached_kb: mem_status.mem_cached,
+ };
+ match vm_mem_status_reported.stats_write() {
+ Err(e) => {
+ warn!("statslog_rust failed with error: {}", e);
+ }
+ Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
+ }
+}