blob: 6e0064f7ef0e0b32797386f3898ba2512c0a084a [file] [log] [blame]
// 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.
//! Functions for creating and collecting atoms.
use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::DeathReason::DeathReason;
use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::{
AtomVmBooted::AtomVmBooted,
AtomVmCreationRequested::AtomVmCreationRequested,
AtomVmExited::AtomVmExited,
};
use anyhow::Result;
use log::{trace, warn};
use rustutils::system_properties::PropertyWatcher;
use statslog_virtualization_rust::{vm_booted, vm_creation_requested, vm_exited};
pub fn forward_vm_creation_atom(atom: &AtomVmCreationRequested) {
let config_type = match atom.configType {
x if x == vm_creation_requested::ConfigType::VirtualMachineAppConfig as i32 => {
vm_creation_requested::ConfigType::VirtualMachineAppConfig
}
x if x == vm_creation_requested::ConfigType::VirtualMachineRawConfig as i32 => {
vm_creation_requested::ConfigType::VirtualMachineRawConfig
}
_ => vm_creation_requested::ConfigType::UnknownConfig,
};
let vm_creation_requested = vm_creation_requested::VmCreationRequested {
uid: atom.uid,
vm_identifier: &atom.vmIdentifier,
hypervisor: vm_creation_requested::Hypervisor::Pkvm,
is_protected: atom.isProtected,
creation_succeeded: atom.creationSucceeded,
binder_exception_code: atom.binderExceptionCode,
config_type,
num_cpus: atom.numCpus,
cpu_affinity: "", // deprecated
memory_mib: atom.memoryMib,
apexes: &atom.apexes,
// TODO(seungjaeyoo) Fill information about disk_image for raw config
};
wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
match vm_creation_requested.stats_write() {
Err(e) => warn!("statslog_rust failed with error: {}", e),
Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
}
}
pub fn forward_vm_booted_atom(atom: &AtomVmBooted) {
let vm_booted = vm_booted::VmBooted {
uid: atom.uid,
vm_identifier: &atom.vmIdentifier,
elapsed_time_millis: atom.elapsedTimeMillis,
};
wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
match vm_booted.stats_write() {
Err(e) => warn!("statslog_rust failed with error: {}", e),
Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
}
}
pub fn forward_vm_exited_atom(atom: &AtomVmExited) {
let death_reason = match atom.deathReason {
DeathReason::INFRASTRUCTURE_ERROR => vm_exited::DeathReason::InfrastructureError,
DeathReason::KILLED => vm_exited::DeathReason::Killed,
DeathReason::UNKNOWN => vm_exited::DeathReason::Unknown,
DeathReason::SHUTDOWN => vm_exited::DeathReason::Shutdown,
DeathReason::START_FAILED => vm_exited::DeathReason::Error,
DeathReason::REBOOT => vm_exited::DeathReason::Reboot,
DeathReason::CRASH => vm_exited::DeathReason::Crash,
DeathReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH => {
vm_exited::DeathReason::PvmFirmwarePublicKeyMismatch
}
DeathReason::PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED => {
vm_exited::DeathReason::PvmFirmwareInstanceImageChanged
}
DeathReason::MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE => {
vm_exited::DeathReason::MicrodroidFailedToConnectToVirtualizationService
}
DeathReason::MICRODROID_PAYLOAD_HAS_CHANGED => {
vm_exited::DeathReason::MicrodroidPayloadHasChanged
}
DeathReason::MICRODROID_PAYLOAD_VERIFICATION_FAILED => {
vm_exited::DeathReason::MicrodroidPayloadVerificationFailed
}
DeathReason::MICRODROID_INVALID_PAYLOAD_CONFIG => {
vm_exited::DeathReason::MicrodroidInvalidPayloadConfig
}
DeathReason::MICRODROID_UNKNOWN_RUNTIME_ERROR => {
vm_exited::DeathReason::MicrodroidUnknownRuntimeError
}
DeathReason::HANGUP => vm_exited::DeathReason::Hangup,
_ => vm_exited::DeathReason::Unknown,
};
let vm_exited = vm_exited::VmExited {
uid: atom.uid,
vm_identifier: &atom.vmIdentifier,
elapsed_time_millis: atom.elapsedTimeMillis,
death_reason,
guest_time_millis: atom.guestTimeMillis,
rss_vm_kb: atom.rssVmKb,
rss_crosvm_kb: atom.rssCrosvmKb,
exit_signal: atom.exitSignal,
};
wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
match vm_exited.stats_write() {
Err(e) => warn!("statslog_rust failed with error: {}", e),
Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
}
}
fn wait_for_statsd() -> Result<()> {
PropertyWatcher::new("init.svc.statsd")?.wait_for_value("running", None)?;
Ok(())
}