Send UID and VM identifier to existing atoms

Bug: 236252851
Test: N/A

Change-Id: I5e4db74f9a5cefd071676b9d248e9c5d91c5bfdd
This commit is contained in:
Seungjae Yoo 2022-08-12 04:44:52 +00:00
parent b4c07bab62
commit 62085c0e65
12 changed files with 55 additions and 19 deletions

View File

@ -102,6 +102,7 @@ impl ComposClient {
let config_path = parameters.config_path.as_deref().unwrap_or(DEFAULT_VM_CONFIG_PATH); let config_path = parameters.config_path.as_deref().unwrap_or(DEFAULT_VM_CONFIG_PATH);
let config = VirtualMachineConfig::AppConfig(VirtualMachineAppConfig { let config = VirtualMachineConfig::AppConfig(VirtualMachineAppConfig {
name: String::from("Compos"),
apk: Some(apk_fd), apk: Some(apk_fd),
idsig: Some(idsig_fd), idsig: Some(idsig_fd),
instanceImage: Some(instance_fd), instanceImage: Some(instance_fd),

View File

@ -379,6 +379,7 @@ public class VirtualMachine {
} }
VirtualMachineAppConfig appConfig = getConfig().toParcel(); VirtualMachineAppConfig appConfig = getConfig().toParcel();
appConfig.name = mName;
// Fill the idsig file by hashing the apk // Fill the idsig file by hashing the apk
service.createOrUpdateIdsigFile( service.createOrUpdateIdsigFile(

View File

@ -33,6 +33,8 @@ use std::path::{Path, PathBuf};
/// Configuration for a particular VM to be started. /// Configuration for a particular VM to be started.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct VmConfig { pub struct VmConfig {
/// The name of VM.
pub name: Option<String>,
/// The filename of the kernel image, if any. /// The filename of the kernel image, if any.
pub kernel: Option<PathBuf>, pub kernel: Option<PathBuf>,
/// The filename of the initial ramdisk for the kernel, if any. /// The filename of the initial ramdisk for the kernel, if any.
@ -91,6 +93,7 @@ impl VmConfig {
} else { } else {
0 0
}; };
Ok(VirtualMachineRawConfig { Ok(VirtualMachineRawConfig {
kernel: maybe_open_parcel_file(&self.kernel, false)?, kernel: maybe_open_parcel_file(&self.kernel, false)?,
initrd: maybe_open_parcel_file(&self.initrd, false)?, initrd: maybe_open_parcel_file(&self.initrd, false)?,

View File

@ -54,6 +54,7 @@ fn test_boots() -> Result<(), Error> {
let log = android_log_fd()?; let log = android_log_fd()?;
let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig { let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
name: String::from("RialtoTest"),
kernel: None, kernel: None,
initrd: None, initrd: None,
params: None, params: None,

View File

@ -17,6 +17,9 @@ package android.system.virtualizationservice;
/** Configuration for running an App in a VM */ /** Configuration for running an App in a VM */
parcelable VirtualMachineAppConfig { parcelable VirtualMachineAppConfig {
/** Name of VM */
String name;
/** Main APK */ /** Main APK */
ParcelFileDescriptor apk; ParcelFileDescriptor apk;

View File

@ -19,6 +19,9 @@ import android.system.virtualizationservice.DiskImage;
/** Raw configuration for running a VM. */ /** Raw configuration for running a VM. */
parcelable VirtualMachineRawConfig { parcelable VirtualMachineRawConfig {
/** Name of VM */
String name;
/** The kernel image, if any. */ /** The kernel image, if any. */
@nullable ParcelFileDescriptor kernel; @nullable ParcelFileDescriptor kernel;

View File

@ -452,6 +452,7 @@ impl VirtualizationService {
// Actually start the VM. // Actually start the VM.
let crosvm_config = CrosvmConfig { let crosvm_config = CrosvmConfig {
cid, cid,
name: config.name.clone(),
bootloader: maybe_clone_file(&config.bootloader)?, bootloader: maybe_clone_file(&config.bootloader)?,
kernel: maybe_clone_file(&config.kernel)?, kernel: maybe_clone_file(&config.kernel)?,
initrd: maybe_clone_file(&config.initrd)?, initrd: maybe_clone_file(&config.initrd)?,
@ -623,6 +624,7 @@ fn load_app_config(
vm_config.memoryMib = config.memoryMib; vm_config.memoryMib = config.memoryMib;
} }
vm_config.name = config.name.clone();
vm_config.protectedVm = config.protectedVm; vm_config.protectedVm = config.protectedVm;
vm_config.numCpus = config.numCpus; vm_config.numCpus = config.numCpus;
vm_config.cpuAffinity = config.cpuAffinity.clone(); vm_config.cpuAffinity = config.cpuAffinity.clone();
@ -1043,7 +1045,8 @@ impl IVirtualMachineService for VirtualMachineService {
})?; })?;
let stream = vm.stream.lock().unwrap().take(); let stream = vm.stream.lock().unwrap().take();
vm.callbacks.notify_payload_started(cid, stream); vm.callbacks.notify_payload_started(cid, stream);
write_vm_booted_stats();
write_vm_booted_stats(vm.requester_uid as i32, &vm.name);
Ok(()) Ok(())
} else { } else {
error!("notifyPayloadStarted is called from an unknown CID {}", cid); error!("notifyPayloadStarted is called from an unknown CID {}", cid);

View File

@ -21,6 +21,7 @@ use android_system_virtualizationservice::aidl::android::system::virtualizations
}; };
use android_system_virtualizationservice::binder::{Status, Strong}; use android_system_virtualizationservice::binder::{Status, Strong};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use binder::ThreadState;
use log::{trace, warn}; use log::{trace, warn};
use microdroid_payload_config::VmPayloadConfig; use microdroid_payload_config::VmPayloadConfig;
use statslog_virtualization_rust::{vm_booted, vm_creation_requested, vm_exited}; use statslog_virtualization_rust::{vm_booted, vm_creation_requested, vm_exited};
@ -54,6 +55,7 @@ pub fn write_vm_creation_stats(
} }
} }
let vm_identifier;
let config_type; let config_type;
let num_cpus; let num_cpus;
let cpu_affinity; let cpu_affinity;
@ -61,6 +63,7 @@ pub fn write_vm_creation_stats(
let apexes; let apexes;
match config { match config {
VirtualMachineConfig::AppConfig(config) => { VirtualMachineConfig::AppConfig(config) => {
vm_identifier = &config.name;
config_type = vm_creation_requested::ConfigType::VirtualMachineAppConfig; config_type = vm_creation_requested::ConfigType::VirtualMachineAppConfig;
num_cpus = config.numCpus; num_cpus = config.numCpus;
cpu_affinity = config.cpuAffinity.clone().unwrap_or_default(); cpu_affinity = config.cpuAffinity.clone().unwrap_or_default();
@ -79,6 +82,7 @@ pub fn write_vm_creation_stats(
} }
} }
VirtualMachineConfig::RawConfig(config) => { VirtualMachineConfig::RawConfig(config) => {
vm_identifier = &config.name;
config_type = vm_creation_requested::ConfigType::VirtualMachineRawConfig; config_type = vm_creation_requested::ConfigType::VirtualMachineRawConfig;
num_cpus = config.numCpus; num_cpus = config.numCpus;
cpu_affinity = config.cpuAffinity.clone().unwrap_or_default(); cpu_affinity = config.cpuAffinity.clone().unwrap_or_default();
@ -87,11 +91,9 @@ pub fn write_vm_creation_stats(
} }
} }
let empty_string = String::new();
let vm_creation_requested = vm_creation_requested::VmCreationRequested { let vm_creation_requested = vm_creation_requested::VmCreationRequested {
// TODO(seungjaeyoo) Implement sending proper data about uid & vm_identifier uid: ThreadState::get_calling_uid() as i32,
uid: -1, vm_identifier,
vm_identifier: &empty_string,
hypervisor: vm_creation_requested::Hypervisor::Pkvm, hypervisor: vm_creation_requested::Hypervisor::Pkvm,
is_protected, is_protected,
creation_succeeded, creation_succeeded,
@ -114,13 +116,8 @@ pub fn write_vm_creation_stats(
} }
/// Write the stats of VM boot to statsd /// Write the stats of VM boot to statsd
pub fn write_vm_booted_stats() { pub fn write_vm_booted_stats(uid: i32, vm_identifier: &String) {
let empty_string = String::new(); let vm_booted = vm_booted::VmBooted { uid, vm_identifier };
let vm_booted = vm_booted::VmBooted {
// TODO(seungjaeyoo) Implement sending proper data about uid & vm_identifier
uid: -1,
vm_identifier: &empty_string,
};
match vm_booted.stats_write() { match vm_booted.stats_write() {
Err(e) => { Err(e) => {
warn!("statslog_rust failed with error: {}", e); warn!("statslog_rust failed with error: {}", e);
@ -130,12 +127,10 @@ pub fn write_vm_booted_stats() {
} }
/// Write the stats of VM exit to statsd /// Write the stats of VM exit to statsd
pub fn write_vm_exited_stats(reason: DeathReason) { pub fn write_vm_exited_stats(uid: i32, vm_identifier: &String, reason: DeathReason) {
let empty_string = String::new();
let vm_exited = vm_exited::VmExited { let vm_exited = vm_exited::VmExited {
// TODO(seungjaeyoo) Implement sending proper data about uid & vm_identifier uid,
uid: -1, vm_identifier,
vm_identifier: &empty_string,
death_reason: match reason { death_reason: match reason {
DeathReason::INFRASTRUCTURE_ERROR => vm_exited::DeathReason::InfrastructureError, DeathReason::INFRASTRUCTURE_ERROR => vm_exited::DeathReason::InfrastructureError,
DeathReason::KILLED => vm_exited::DeathReason::Killed, DeathReason::KILLED => vm_exited::DeathReason::Killed,

View File

@ -70,6 +70,7 @@ lazy_static! {
#[derive(Debug)] #[derive(Debug)]
pub struct CrosvmConfig { pub struct CrosvmConfig {
pub cid: Cid, pub cid: Cid,
pub name: String,
pub bootloader: Option<File>, pub bootloader: Option<File>,
pub kernel: Option<File>, pub kernel: Option<File>,
pub initrd: Option<File>, pub initrd: Option<File>,
@ -170,6 +171,8 @@ pub struct VmInstance {
pub vm_state: Mutex<VmState>, pub vm_state: Mutex<VmState>,
/// The CID assigned to the VM for vsock communication. /// The CID assigned to the VM for vsock communication.
pub cid: Cid, pub cid: Cid,
/// The name of the VM.
pub name: String,
/// Whether the VM is a protected VM. /// Whether the VM is a protected VM.
pub protected: bool, pub protected: bool,
/// Directory of temporary files used by the VM while it is running. /// Directory of temporary files used by the VM while it is running.
@ -204,10 +207,12 @@ impl VmInstance {
) -> Result<VmInstance, Error> { ) -> Result<VmInstance, Error> {
validate_config(&config)?; validate_config(&config)?;
let cid = config.cid; let cid = config.cid;
let name = config.name.clone();
let protected = config.protected; let protected = config.protected;
Ok(VmInstance { Ok(VmInstance {
vm_state: Mutex::new(VmState::NotStarted { config }), vm_state: Mutex::new(VmState::NotStarted { config }),
cid, cid,
name,
protected, protected,
temporary_directory, temporary_directory,
requester_uid, requester_uid,
@ -264,7 +269,7 @@ impl VmInstance {
let death_reason = death_reason(&result, &failure_reason); let death_reason = death_reason(&result, &failure_reason);
self.callbacks.callback_on_died(self.cid, death_reason); self.callbacks.callback_on_died(self.cid, death_reason);
write_vm_exited_stats(death_reason); write_vm_exited_stats(self.requester_uid as i32, &self.name, death_reason);
// Delete temporary files. // Delete temporary files.
if let Err(e) = remove_dir_all(&self.temporary_directory) { if let Err(e) = remove_dir_all(&self.temporary_directory) {

View File

@ -40,6 +40,10 @@ struct Idsigs(Vec<PathBuf>);
enum Opt { enum Opt {
/// Run a virtual machine with a config in APK /// Run a virtual machine with a config in APK
RunApp { RunApp {
/// Name of VM
#[structopt(long)]
name: Option<String>,
/// Path to VM Payload APK /// Path to VM Payload APK
#[structopt(parse(from_os_str))] #[structopt(parse(from_os_str))]
apk: PathBuf, apk: PathBuf,
@ -102,6 +106,10 @@ enum Opt {
}, },
/// Run a virtual machine /// Run a virtual machine
Run { Run {
/// Name of VM
#[structopt(long)]
name: Option<String>,
/// Path to VM config JSON /// Path to VM config JSON
#[structopt(parse(from_os_str))] #[structopt(parse(from_os_str))]
config: PathBuf, config: PathBuf,
@ -195,6 +203,7 @@ fn main() -> Result<(), Error> {
match opt { match opt {
Opt::RunApp { Opt::RunApp {
name,
apk, apk,
idsig, idsig,
instance, instance,
@ -211,6 +220,7 @@ fn main() -> Result<(), Error> {
task_profiles, task_profiles,
extra_idsigs, extra_idsigs,
} => command_run_app( } => command_run_app(
name,
service.as_ref(), service.as_ref(),
&apk, &apk,
&idsig, &idsig,
@ -228,8 +238,9 @@ fn main() -> Result<(), Error> {
task_profiles, task_profiles,
&extra_idsigs, &extra_idsigs,
), ),
Opt::Run { config, daemonize, cpus, cpu_affinity, task_profiles, console, log } => { Opt::Run { name, config, daemonize, cpus, cpu_affinity, task_profiles, console, log } => {
command_run( command_run(
name,
service.as_ref(), service.as_ref(),
&config, &config,
daemonize, daemonize,

View File

@ -35,6 +35,7 @@ use zip::ZipArchive;
/// Run a VM from the given APK, idsig, and config. /// Run a VM from the given APK, idsig, and config.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn command_run_app( pub fn command_run_app(
name: Option<String>,
service: &dyn IVirtualizationService, service: &dyn IVirtualizationService,
apk: &Path, apk: &Path,
idsig: &Path, idsig: &Path,
@ -91,6 +92,7 @@ pub fn command_run_app(
let extra_idsig_fds = extra_idsig_files?.into_iter().map(ParcelFileDescriptor::new).collect(); let extra_idsig_fds = extra_idsig_files?.into_iter().map(ParcelFileDescriptor::new).collect();
let config = VirtualMachineConfig::AppConfig(VirtualMachineAppConfig { let config = VirtualMachineConfig::AppConfig(VirtualMachineAppConfig {
name: name.unwrap_or_else(|| String::from("VmRunApp")),
apk: apk_fd.into(), apk: apk_fd.into(),
idsig: idsig_fd.into(), idsig: idsig_fd.into(),
extraIdsigs: extra_idsig_fds, extraIdsigs: extra_idsig_fds,
@ -117,6 +119,7 @@ pub fn command_run_app(
/// Run a VM from the given configuration file. /// Run a VM from the given configuration file.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn command_run( pub fn command_run(
name: Option<String>,
service: &dyn IVirtualizationService, service: &dyn IVirtualizationService,
config_path: &Path, config_path: &Path,
daemonize: bool, daemonize: bool,
@ -136,6 +139,11 @@ pub fn command_run(
if let Some(cpus) = cpus { if let Some(cpus) = cpus {
config.numCpus = cpus as i32; config.numCpus = cpus as i32;
} }
if let Some(name) = name {
config.name = name;
} else {
config.name = String::from("VmRun");
}
config.cpuAffinity = cpu_affinity; config.cpuAffinity = cpu_affinity;
config.taskProfiles = task_profiles; config.taskProfiles = task_profiles;
run( run(

View File

@ -48,7 +48,9 @@ fn test_run_example_vm() -> Result<(), Error> {
File::open(VMBASE_EXAMPLE_PATH) File::open(VMBASE_EXAMPLE_PATH)
.with_context(|| format!("Failed to open VM image {}", VMBASE_EXAMPLE_PATH))?, .with_context(|| format!("Failed to open VM image {}", VMBASE_EXAMPLE_PATH))?,
); );
let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig { let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
name: String::from("VmBaseTest"),
kernel: None, kernel: None,
initrd: None, initrd: None,
params: None, params: None,