1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Functions for creating and collecting atoms.
16 
17 use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::DeathReason::DeathReason;
18 use android_system_virtualizationservice_internal::aidl::android::system::virtualizationservice_internal::{
19     AtomVmBooted::AtomVmBooted,
20     AtomVmCreationRequested::AtomVmCreationRequested,
21     AtomVmExited::AtomVmExited,
22 };
23 use anyhow::Result;
24 use log::{trace, warn};
25 use rustutils::system_properties::PropertyWatcher;
26 use statslog_virtualization_rust::{vm_booted, vm_creation_requested, vm_exited};
27 
forward_vm_creation_atom(atom: &AtomVmCreationRequested)28 pub fn forward_vm_creation_atom(atom: &AtomVmCreationRequested) {
29     let config_type = match atom.configType {
30         x if x == vm_creation_requested::ConfigType::VirtualMachineAppConfig as i32 => {
31             vm_creation_requested::ConfigType::VirtualMachineAppConfig
32         }
33         x if x == vm_creation_requested::ConfigType::VirtualMachineRawConfig as i32 => {
34             vm_creation_requested::ConfigType::VirtualMachineRawConfig
35         }
36         _ => vm_creation_requested::ConfigType::UnknownConfig,
37     };
38     let vm_creation_requested = vm_creation_requested::VmCreationRequested {
39         uid: atom.uid,
40         vm_identifier: &atom.vmIdentifier,
41         hypervisor: vm_creation_requested::Hypervisor::Pkvm,
42         is_protected: atom.isProtected,
43         creation_succeeded: atom.creationSucceeded,
44         binder_exception_code: atom.binderExceptionCode,
45         config_type,
46         num_cpus: atom.numCpus,
47         cpu_affinity: "", // deprecated
48         memory_mib: atom.memoryMib,
49         apexes: &atom.apexes,
50         // TODO(seungjaeyoo) Fill information about disk_image for raw config
51     };
52 
53     wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
54     match vm_creation_requested.stats_write() {
55         Err(e) => warn!("statslog_rust failed with error: {}", e),
56         Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
57     }
58 }
59 
forward_vm_booted_atom(atom: &AtomVmBooted)60 pub fn forward_vm_booted_atom(atom: &AtomVmBooted) {
61     let vm_booted = vm_booted::VmBooted {
62         uid: atom.uid,
63         vm_identifier: &atom.vmIdentifier,
64         elapsed_time_millis: atom.elapsedTimeMillis,
65     };
66 
67     wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
68     match vm_booted.stats_write() {
69         Err(e) => warn!("statslog_rust failed with error: {}", e),
70         Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
71     }
72 }
73 
forward_vm_exited_atom(atom: &AtomVmExited)74 pub fn forward_vm_exited_atom(atom: &AtomVmExited) {
75     let death_reason = match atom.deathReason {
76         DeathReason::INFRASTRUCTURE_ERROR => vm_exited::DeathReason::InfrastructureError,
77         DeathReason::KILLED => vm_exited::DeathReason::Killed,
78         DeathReason::UNKNOWN => vm_exited::DeathReason::Unknown,
79         DeathReason::SHUTDOWN => vm_exited::DeathReason::Shutdown,
80         DeathReason::START_FAILED => vm_exited::DeathReason::Error,
81         DeathReason::REBOOT => vm_exited::DeathReason::Reboot,
82         DeathReason::CRASH => vm_exited::DeathReason::Crash,
83         DeathReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH => {
84             vm_exited::DeathReason::PvmFirmwarePublicKeyMismatch
85         }
86         DeathReason::PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED => {
87             vm_exited::DeathReason::PvmFirmwareInstanceImageChanged
88         }
89         DeathReason::MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE => {
90             vm_exited::DeathReason::MicrodroidFailedToConnectToVirtualizationService
91         }
92         DeathReason::MICRODROID_PAYLOAD_HAS_CHANGED => {
93             vm_exited::DeathReason::MicrodroidPayloadHasChanged
94         }
95         DeathReason::MICRODROID_PAYLOAD_VERIFICATION_FAILED => {
96             vm_exited::DeathReason::MicrodroidPayloadVerificationFailed
97         }
98         DeathReason::MICRODROID_INVALID_PAYLOAD_CONFIG => {
99             vm_exited::DeathReason::MicrodroidInvalidPayloadConfig
100         }
101         DeathReason::MICRODROID_UNKNOWN_RUNTIME_ERROR => {
102             vm_exited::DeathReason::MicrodroidUnknownRuntimeError
103         }
104         DeathReason::HANGUP => vm_exited::DeathReason::Hangup,
105         _ => vm_exited::DeathReason::Unknown,
106     };
107 
108     let vm_exited = vm_exited::VmExited {
109         uid: atom.uid,
110         vm_identifier: &atom.vmIdentifier,
111         elapsed_time_millis: atom.elapsedTimeMillis,
112         death_reason,
113         guest_time_millis: atom.guestTimeMillis,
114         rss_vm_kb: atom.rssVmKb,
115         rss_crosvm_kb: atom.rssCrosvmKb,
116         exit_signal: atom.exitSignal,
117     };
118 
119     wait_for_statsd().unwrap_or_else(|e| warn!("failed to wait for statsd with error: {}", e));
120     match vm_exited.stats_write() {
121         Err(e) => warn!("statslog_rust failed with error: {}", e),
122         Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
123     }
124 }
125 
wait_for_statsd() -> Result<()>126 fn wait_for_statsd() -> Result<()> {
127     PropertyWatcher::new("init.svc.statsd")?.wait_for_value("running", None)?;
128     Ok(())
129 }
130