blob: 7f1d6b179e78f01c861a9941ae287bff6ce71dc3 [file] [log] [blame]
Seungjae Yoo0a8c84c2022-07-11 08:19:15 +00001// 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
17use crate::aidl::clone_file;
18use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
Seungjae Yoob4c07ba2022-08-12 04:44:52 +000019 DeathReason::DeathReason, IVirtualMachine::IVirtualMachine,
20 VirtualMachineAppConfig::VirtualMachineAppConfig, VirtualMachineConfig::VirtualMachineConfig,
Seungjae Yoo0a8c84c2022-07-11 08:19:15 +000021};
22use android_system_virtualizationservice::binder::{Status, Strong};
23use anyhow::{anyhow, Result};
24use log::{trace, warn};
25use microdroid_payload_config::VmPayloadConfig;
Seungjae Yoob4c07ba2022-08-12 04:44:52 +000026use statslog_virtualization_rust::{vm_booted, vm_creation_requested, vm_exited};
Seungjae Yoo0a8c84c2022-07-11 08:19:15 +000027use zip::ZipArchive;
28
29fn get_vm_payload_config(config: &VirtualMachineAppConfig) -> Result<VmPayloadConfig> {
30 let apk = config.apk.as_ref().ok_or_else(|| anyhow!("APK is none"))?;
31 let apk_file = clone_file(apk)?;
32 let mut apk_zip = ZipArchive::new(&apk_file)?;
33 let config_file = apk_zip.by_name(&config.configPath)?;
34 let vm_payload_config: VmPayloadConfig = serde_json::from_reader(config_file)?;
35 Ok(vm_payload_config)
36}
37
38/// Write the stats of VMCreation to statsd
39pub fn write_vm_creation_stats(
40 config: &VirtualMachineConfig,
41 is_protected: bool,
42 ret: &binder::Result<Strong<dyn IVirtualMachine>>,
43) {
44 let creation_succeeded;
45 let binder_exception_code;
46 match ret {
47 Ok(_) => {
48 creation_succeeded = true;
49 binder_exception_code = Status::ok().exception_code() as i32;
50 }
51 Err(ref e) => {
52 creation_succeeded = false;
53 binder_exception_code = e.exception_code() as i32;
54 }
55 }
56
57 let config_type;
58 let num_cpus;
59 let cpu_affinity;
60 let memory_mib;
61 let apexes;
62 match config {
63 VirtualMachineConfig::AppConfig(config) => {
64 config_type = vm_creation_requested::ConfigType::VirtualMachineAppConfig;
65 num_cpus = config.numCpus;
66 cpu_affinity = config.cpuAffinity.clone().unwrap_or_default();
67 memory_mib = config.memoryMib;
68
69 let vm_payload_config = get_vm_payload_config(config);
70 if let Ok(vm_payload_config) = vm_payload_config {
71 apexes = vm_payload_config
72 .apexes
73 .iter()
74 .map(|x| x.name.clone())
75 .collect::<Vec<String>>()
76 .join(":");
77 } else {
78 apexes = "INFO: Can't get VmPayloadConfig".into();
79 }
80 }
81 VirtualMachineConfig::RawConfig(config) => {
82 config_type = vm_creation_requested::ConfigType::VirtualMachineRawConfig;
83 num_cpus = config.numCpus;
84 cpu_affinity = config.cpuAffinity.clone().unwrap_or_default();
85 memory_mib = config.memoryMib;
86 apexes = String::new();
87 }
88 }
89
90 let empty_string = String::new();
91 let vm_creation_requested = vm_creation_requested::VmCreationRequested {
92 // TODO(seungjaeyoo) Implement sending proper data about uid & vm_identifier
93 uid: -1,
94 vm_identifier: &empty_string,
95 hypervisor: vm_creation_requested::Hypervisor::Pkvm,
96 is_protected,
97 creation_succeeded,
98 binder_exception_code,
99 config_type,
100 num_cpus,
101 cpu_affinity: &cpu_affinity,
102 memory_mib,
103 apexes: &apexes,
104 // TODO(seungjaeyoo) Fill information about task_profile
105 // TODO(seungjaeyoo) Fill information about disk_image for raw config
106 };
107
108 match vm_creation_requested.stats_write() {
109 Err(e) => {
110 warn!("statslog_rust failed with error: {}", e);
111 }
112 Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
113 }
114}
Seungjae Yooacf559a2022-08-12 04:44:51 +0000115
116/// Write the stats of VM boot to statsd
117pub fn write_vm_booted_stats() {
118 let empty_string = String::new();
119 let vm_booted = vm_booted::VmBooted {
120 // TODO(seungjaeyoo) Implement sending proper data about uid & vm_identifier
121 uid: -1,
122 vm_identifier: &empty_string,
123 };
124 match vm_booted.stats_write() {
125 Err(e) => {
126 warn!("statslog_rust failed with error: {}", e);
127 }
128 Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
129 }
130}
Seungjae Yoob4c07ba2022-08-12 04:44:52 +0000131
132/// Write the stats of VM exit to statsd
133pub fn write_vm_exited_stats(reason: DeathReason) {
134 let empty_string = String::new();
135 let vm_exited = vm_exited::VmExited {
136 // TODO(seungjaeyoo) Implement sending proper data about uid & vm_identifier
137 uid: -1,
138 vm_identifier: &empty_string,
139 death_reason: match reason {
140 DeathReason::INFRASTRUCTURE_ERROR => vm_exited::DeathReason::InfrastructureError,
141 DeathReason::KILLED => vm_exited::DeathReason::Killed,
142 DeathReason::UNKNOWN => vm_exited::DeathReason::Unknown,
143 DeathReason::SHUTDOWN => vm_exited::DeathReason::Shutdown,
144 DeathReason::ERROR => vm_exited::DeathReason::Error,
145 DeathReason::REBOOT => vm_exited::DeathReason::Reboot,
146 DeathReason::CRASH => vm_exited::DeathReason::Crash,
147 DeathReason::PVM_FIRMWARE_PUBLIC_KEY_MISMATCH => {
148 vm_exited::DeathReason::PvmFirmwarePublicKeyMismatch
149 }
150 DeathReason::PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED => {
151 vm_exited::DeathReason::PvmFirmwareInstanceImageChanged
152 }
153 DeathReason::BOOTLOADER_PUBLIC_KEY_MISMATCH => {
154 vm_exited::DeathReason::BootloaderPublicKeyMismatch
155 }
156 DeathReason::BOOTLOADER_INSTANCE_IMAGE_CHANGED => {
157 vm_exited::DeathReason::BootloaderInstanceImageChanged
158 }
159 DeathReason::MICRODROID_FAILED_TO_CONNECT_TO_VIRTUALIZATION_SERVICE => {
160 vm_exited::DeathReason::MicrodroidFailedToConnectToVirtualizationService
161 }
162 DeathReason::MICRODROID_PAYLOAD_HAS_CHANGED => {
163 vm_exited::DeathReason::MicrodroidPayloadHasChanged
164 }
165 DeathReason::MICRODROID_PAYLOAD_VERIFICATION_FAILED => {
166 vm_exited::DeathReason::MicrodroidPayloadVerificationFailed
167 }
168 DeathReason::MICRODROID_INVALID_PAYLOAD_CONFIG => {
169 vm_exited::DeathReason::MicrodroidInvalidPayloadConfig
170 }
171 DeathReason::MICRODROID_UNKNOWN_RUNTIME_ERROR => {
172 vm_exited::DeathReason::MicrodroidUnknownRuntimeError
173 }
174 DeathReason::HANGUP => vm_exited::DeathReason::Hangup,
175 _ => vm_exited::DeathReason::Unknown,
176 },
177 };
178 match vm_exited.stats_write() {
179 Err(e) => {
180 warn!("statslog_rust failed with error: {}", e);
181 }
182 Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
183 }
184}