Merge "[VS]Wait for statsd to run before pushing atoms"
diff --git a/virtualizationservice/src/atom.rs b/virtualizationservice/src/atom.rs
index eabb4cc..20f88e7 100644
--- a/virtualizationservice/src/atom.rs
+++ b/virtualizationservice/src/atom.rs
@@ -26,7 +26,9 @@
use binder::{ParcelFileDescriptor, ThreadState};
use log::{trace, warn};
use microdroid_payload_config::VmPayloadConfig;
+use rustutils::system_properties;
use statslog_virtualization_rust::{vm_booted, vm_creation_requested, vm_exited};
+use std::thread;
use std::time::{Duration, SystemTime};
use zip::ZipArchive;
@@ -86,17 +88,16 @@
binder_exception_code = e.exception_code() as i32;
}
}
-
let (vm_identifier, config_type, num_cpus, memory_mib, apexes) = match config {
VirtualMachineConfig::AppConfig(config) => (
- &config.name,
+ config.name.clone(),
vm_creation_requested::ConfigType::VirtualMachineAppConfig,
config.numCpus,
config.memoryMib,
get_apex_list(config),
),
VirtualMachineConfig::RawConfig(config) => (
- &config.name,
+ config.name.clone(),
vm_creation_requested::ConfigType::VirtualMachineRawConfig,
config.numCpus,
config.memoryMib,
@@ -104,105 +105,139 @@
),
};
- let vm_creation_requested = vm_creation_requested::VmCreationRequested {
- uid: ThreadState::get_calling_uid() as i32,
- vm_identifier,
- hypervisor: vm_creation_requested::Hypervisor::Pkvm,
- is_protected,
- creation_succeeded,
- binder_exception_code,
- config_type,
- num_cpus,
- cpu_affinity: "", // deprecated
- memory_mib,
- apexes: &apexes,
- // TODO(seungjaeyoo) Fill information about task_profile
- // TODO(seungjaeyoo) Fill information about disk_image for raw config
- };
+ let uid = ThreadState::get_calling_uid() as i32;
+ thread::spawn(move || {
+ let vm_creation_requested = vm_creation_requested::VmCreationRequested {
+ uid,
+ vm_identifier: &vm_identifier,
+ hypervisor: vm_creation_requested::Hypervisor::Pkvm,
+ is_protected,
+ creation_succeeded,
+ binder_exception_code,
+ config_type,
+ num_cpus,
+ cpu_affinity: "", // deprecated
+ memory_mib,
+ apexes: &apexes,
+ // TODO(seungjaeyoo) Fill information about task_profile
+ // TODO(seungjaeyoo) Fill information about disk_image for raw config
+ };
- match vm_creation_requested.stats_write() {
- Err(e) => {
- warn!("statslog_rust failed with error: {}", e);
+ 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"),
}
- Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
- }
+ });
}
/// Write the stats of VM boot to statsd
+/// The function creates a separate thread which waits fro statsd to start to push atom
pub fn write_vm_booted_stats(
uid: i32,
- vm_identifier: &String,
+ vm_identifier: &str,
vm_start_timestamp: Option<SystemTime>,
) {
+ let vm_identifier = vm_identifier.to_owned();
let duration = get_duration(vm_start_timestamp);
- let vm_booted = vm_booted::VmBooted {
- uid,
- vm_identifier,
- elapsed_time_millis: duration.as_millis() as i64,
- };
- match vm_booted.stats_write() {
- Err(e) => {
- warn!("statslog_rust failed with error: {}", e);
+ thread::spawn(move || {
+ let vm_booted = vm_booted::VmBooted {
+ uid,
+ vm_identifier: &vm_identifier,
+ elapsed_time_millis: duration.as_millis() as i64,
+ };
+ 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"),
}
- Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
- }
+ });
}
/// Write the stats of VM exit to statsd
+/// The function creates a separate thread which waits fro statsd to start to push atom
pub fn write_vm_exited_stats(
uid: i32,
- vm_identifier: &String,
+ vm_identifier: &str,
reason: DeathReason,
vm_start_timestamp: Option<SystemTime>,
) {
+ let vm_identifier = vm_identifier.to_owned();
let duration = get_duration(vm_start_timestamp);
- let vm_exited = vm_exited::VmExited {
- uid,
- vm_identifier,
- elapsed_time_millis: duration.as_millis() as i64,
- death_reason: match reason {
- 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::ERROR => 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
+ thread::spawn(move || {
+ let vm_exited = vm_exited::VmExited {
+ uid,
+ vm_identifier: &vm_identifier,
+ elapsed_time_millis: duration.as_millis() as i64,
+ death_reason: match reason {
+ 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::ERROR => 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::BOOTLOADER_PUBLIC_KEY_MISMATCH => {
+ vm_exited::DeathReason::BootloaderPublicKeyMismatch
+ }
+ DeathReason::BOOTLOADER_INSTANCE_IMAGE_CHANGED => {
+ vm_exited::DeathReason::BootloaderInstanceImageChanged
+ }
+ 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,
+ },
+ };
+ 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);
}
- DeathReason::PVM_FIRMWARE_INSTANCE_IMAGE_CHANGED => {
- vm_exited::DeathReason::PvmFirmwareInstanceImageChanged
- }
- DeathReason::BOOTLOADER_PUBLIC_KEY_MISMATCH => {
- vm_exited::DeathReason::BootloaderPublicKeyMismatch
- }
- DeathReason::BOOTLOADER_INSTANCE_IMAGE_CHANGED => {
- vm_exited::DeathReason::BootloaderInstanceImageChanged
- }
- 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,
- },
- };
- match vm_exited.stats_write() {
- Err(e) => {
- warn!("statslog_rust failed with error: {}", e);
+ Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
}
- Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
+ });
+}
+
+fn wait_for_statsd() -> Result<()> {
+ let mut prop = system_properties::PropertyWatcher::new("init.svc.statsd")?;
+ loop {
+ prop.wait()?;
+ match system_properties::read("init.svc.statsd")? {
+ Some(s) => {
+ if s == "running" {
+ break;
+ }
+ }
+ None => {
+ // This case never really happens because
+ // prop.wait() waits for property to be non-null.
+ break;
+ }
+ }
}
+ Ok(())
}