Merge "Load crashkernel using kexec"
diff --git a/.prebuilt_info/prebuilt_info_pvmfw_pvmfw_img.asciipb b/.prebuilt_info/prebuilt_info_pvmfw_pvmfw_img.asciipb
index 6956ab1..7b2cad9 100644
--- a/.prebuilt_info/prebuilt_info_pvmfw_pvmfw_img.asciipb
+++ b/.prebuilt_info/prebuilt_info_pvmfw_pvmfw_img.asciipb
@@ -1,6 +1,6 @@
drops {
android_build_drop {
- build_id: "8819384"
+ build_id: "8964254"
target: "u-boot_pvmfw"
source_file: "pvmfw.img"
}
diff --git a/compos/common/compos_client.rs b/compos/common/compos_client.rs
index 770f489..946bc5b 100644
--- a/compos/common/compos_client.rs
+++ b/compos/common/compos_client.rs
@@ -102,6 +102,7 @@
let config_path = parameters.config_path.as_deref().unwrap_or(DEFAULT_VM_CONFIG_PATH);
let config = VirtualMachineConfig::AppConfig(VirtualMachineAppConfig {
+ name: String::from("Compos"),
apk: Some(apk_fd),
idsig: Some(idsig_fd),
instanceImage: Some(instance_fd),
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index 955b350..cc13ae5 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -379,6 +379,7 @@
}
VirtualMachineAppConfig appConfig = getConfig().toParcel();
+ appConfig.name = mName;
// Fill the idsig file by hashing the apk
service.createOrUpdateIdsigFile(
diff --git a/libs/vmconfig/src/lib.rs b/libs/vmconfig/src/lib.rs
index 607b347..7ca8272 100644
--- a/libs/vmconfig/src/lib.rs
+++ b/libs/vmconfig/src/lib.rs
@@ -33,6 +33,8 @@
/// Configuration for a particular VM to be started.
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct VmConfig {
+ /// The name of VM.
+ pub name: Option<String>,
/// The filename of the kernel image, if any.
pub kernel: Option<PathBuf>,
/// The filename of the initial ramdisk for the kernel, if any.
@@ -91,6 +93,7 @@
} else {
0
};
+
Ok(VirtualMachineRawConfig {
kernel: maybe_open_parcel_file(&self.kernel, false)?,
initrd: maybe_open_parcel_file(&self.initrd, false)?,
diff --git a/pvmfw/pvmfw.img b/pvmfw/pvmfw.img
index b360bda..7cc8009 100644
--- a/pvmfw/pvmfw.img
+++ b/pvmfw/pvmfw.img
Binary files differ
diff --git a/rialto/tests/test.rs b/rialto/tests/test.rs
index fb6a1ad..8a78861 100644
--- a/rialto/tests/test.rs
+++ b/rialto/tests/test.rs
@@ -54,6 +54,7 @@
let log = android_log_fd()?;
let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
+ name: String::from("RialtoTest"),
kernel: None,
initrd: None,
params: None,
diff --git a/tests/hostside/Android.bp b/tests/hostside/Android.bp
index 5ce19bd..d77f3de 100644
--- a/tests/hostside/Android.bp
+++ b/tests/hostside/Android.bp
@@ -15,6 +15,7 @@
static_libs: [
"MicrodroidHostTestHelper",
"compatibility-host-util",
+ "cts-statsd-atom-host-test-utils",
],
per_testcase_directory: true,
data: [
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidTestCase.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidTestCase.java
index 76bfafb..5ac36a0 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidTestCase.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidTestCase.java
@@ -25,13 +25,19 @@
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
+import android.cts.statsdatom.lib.ConfigUtils;
+import android.cts.statsdatom.lib.ReportUtils;
+
import com.android.compatibility.common.util.CddTest;
+import com.android.os.AtomsProto;
+import com.android.os.StatsLog;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.result.TestDescription;
import com.android.tradefed.result.TestResult;
@@ -472,6 +478,89 @@
}
@Test
+ public void testTelemetryPushedAtoms() throws Exception {
+ // Reset statsd config and report before the test
+ ConfigUtils.removeConfig(getDevice());
+ ReportUtils.clearReports(getDevice());
+
+ // Setup statsd config
+ int[] atomIds = {
+ AtomsProto.Atom.VM_CREATION_REQUESTED_FIELD_NUMBER,
+ AtomsProto.Atom.VM_BOOTED_FIELD_NUMBER,
+ AtomsProto.Atom.VM_EXITED_FIELD_NUMBER,
+ };
+ ConfigUtils.uploadConfigForPushedAtoms(getDevice(), PACKAGE_NAME, atomIds);
+
+ // Create VM with microdroid
+ final String configPath = "assets/vm_config_apex.json"; // path inside the APK
+ final String cid =
+ startMicrodroid(
+ getDevice(),
+ getBuild(),
+ APK_NAME,
+ PACKAGE_NAME,
+ configPath,
+ /* debug */ true,
+ minMemorySize(),
+ Optional.of(NUM_VCPUS),
+ Optional.of(CPU_AFFINITY));
+
+ // Check VmCreationRequested atom and clear the statsd report
+ List<StatsLog.EventMetricData> data;
+ data = ReportUtils.getEventMetricDataList(getDevice());
+ assertEquals(1, data.size());
+ assertEquals(
+ AtomsProto.Atom.VM_CREATION_REQUESTED_FIELD_NUMBER,
+ data.get(0).getAtom().getPushedCase().getNumber());
+ AtomsProto.VmCreationRequested atomVmCreationRequested =
+ data.get(0).getAtom().getVmCreationRequested();
+ assertEquals(
+ AtomsProto.VmCreationRequested.Hypervisor.PKVM,
+ atomVmCreationRequested.getHypervisor());
+ assertFalse(atomVmCreationRequested.getIsProtected());
+ assertTrue(atomVmCreationRequested.getCreationSucceeded());
+ assertEquals(0, atomVmCreationRequested.getBinderExceptionCode());
+ assertEquals("VmRunApp", atomVmCreationRequested.getVmIdentifier());
+ assertEquals(
+ AtomsProto.VmCreationRequested.ConfigType.VIRTUAL_MACHINE_APP_CONFIG,
+ atomVmCreationRequested.getConfigType());
+ assertEquals(NUM_VCPUS, atomVmCreationRequested.getNumCpus());
+ assertEquals(CPU_AFFINITY, atomVmCreationRequested.getCpuAffinity());
+ assertEquals(minMemorySize(), atomVmCreationRequested.getMemoryMib());
+ assertEquals(
+ "com.android.art:com.android.compos:com.android.sdkext",
+ atomVmCreationRequested.getApexes());
+
+ // Boot VM with microdroid
+ adbConnectToMicrodroid(getDevice(), cid);
+ waitForBootComplete();
+
+ // Check VmBooted atom and clear the statsd report
+ data = ReportUtils.getEventMetricDataList(getDevice());
+ assertEquals(1, data.size());
+ assertEquals(
+ AtomsProto.Atom.VM_BOOTED_FIELD_NUMBER,
+ data.get(0).getAtom().getPushedCase().getNumber());
+ AtomsProto.VmBooted atomVmBooted = data.get(0).getAtom().getVmBooted();
+ assertEquals("VmRunApp", atomVmBooted.getVmIdentifier());
+
+ // Shutdown VM with microdroid
+ shutdownMicrodroid(getDevice(), cid);
+ // TODO: make sure the VM is completely shut down while 'vm stop' command running.
+ Thread.sleep(1000);
+
+ // Check VmExited atom and clear the statsd report
+ data = ReportUtils.getEventMetricDataList(getDevice());
+ assertEquals(1, data.size());
+ assertEquals(
+ AtomsProto.Atom.VM_EXITED_FIELD_NUMBER,
+ data.get(0).getAtom().getPushedCase().getNumber());
+ AtomsProto.VmExited atomVmExited = data.get(0).getAtom().getVmExited();
+ assertEquals("VmRunApp", atomVmExited.getVmIdentifier());
+ assertEquals(AtomsProto.VmExited.DeathReason.KILLED, atomVmExited.getDeathReason());
+ }
+
+ @Test
@CddTest(requirements = {"9.17/C-1-1", "9.17/C-1-2", "9.17/C/1-3"})
public void testMicrodroidBoots() throws Exception {
final String configPath = "assets/vm_config.json"; // path inside the APK
diff --git a/tests/testapk/Android.bp b/tests/testapk/Android.bp
index 29a74ca..60912ea 100644
--- a/tests/testapk/Android.bp
+++ b/tests/testapk/Android.bp
@@ -25,6 +25,7 @@
use_embedded_native_libs: true,
// We only support 64-bit ABI, but CTS demands all APKs to be multi-ABI.
compile_multilib: "both",
+ min_sdk_version: "33",
}
// TODO(jiyong): make this a binary, not a shared library
diff --git a/tests/testapk/AndroidManifest.xml b/tests/testapk/AndroidManifest.xml
index bc955d2..9c8b2d5 100644
--- a/tests/testapk/AndroidManifest.xml
+++ b/tests/testapk/AndroidManifest.xml
@@ -16,6 +16,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.microdroid.test">
<uses-permission android:name="android.permission.MANAGE_VIRTUAL_MACHINE" />
+ <uses-sdk android:minSdkVersion="33" android:targetSdkVersion="33" />
<application>
<uses-library android:name="android.system.virtualmachine" android:required="false" />
</application>
diff --git a/tests/testapk/assets/vm_config_apex.json b/tests/testapk/assets/vm_config_apex.json
new file mode 100644
index 0000000..0f100aa
--- /dev/null
+++ b/tests/testapk/assets/vm_config_apex.json
@@ -0,0 +1,25 @@
+{
+ "os": {
+ "name": "microdroid"
+ },
+ "task": {
+ "type": "microdroid_launcher",
+ "command": "MicrodroidTestNativeLib.so",
+ "args": [
+ "hello",
+ "microdroid"
+ ]
+ },
+ "apexes": [
+ {
+ "name": "com.android.art"
+ },
+ {
+ "name": "com.android.compos"
+ },
+ {
+ "name": "com.android.sdkext"
+ }
+ ],
+ "export_tombstones": true
+}
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
index 22b8a94..8eb5497 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineAppConfig.aidl
@@ -17,6 +17,9 @@
/** Configuration for running an App in a VM */
parcelable VirtualMachineAppConfig {
+ /** Name of VM */
+ String name;
+
/** Main APK */
ParcelFileDescriptor apk;
diff --git a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
index 83a81a0..d11de03 100644
--- a/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
+++ b/virtualizationservice/aidl/android/system/virtualizationservice/VirtualMachineRawConfig.aidl
@@ -19,6 +19,9 @@
/** Raw configuration for running a VM. */
parcelable VirtualMachineRawConfig {
+ /** Name of VM */
+ String name;
+
/** The kernel image, if any. */
@nullable ParcelFileDescriptor kernel;
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index bba75ac..5f4b7a7 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -14,6 +14,7 @@
//! Implementation of the AIDL interface of the VirtualizationService.
+use crate::atom::{write_vm_booted_stats, write_vm_creation_stats};
use crate::composite::make_composite_image;
use crate::crosvm::{CrosvmConfig, DiskFile, PayloadState, VmInstance, VmState};
use crate::payload::add_microdroid_images;
@@ -48,11 +49,10 @@
use binder_common::rpc_server::run_rpc_server_with_factory;
use disk::QcowFile;
use idsig::{HashAlgorithm, V4Signature};
-use log::{debug, error, info, warn, trace};
+use log::{debug, error, info, warn};
use microdroid_payload_config::VmPayloadConfig;
use rustutils::system_properties;
use semver::VersionReq;
-use statslog_virtualization_rust::vm_creation_requested::{stats_write, Hypervisor};
use std::convert::TryInto;
use std::ffi::CStr;
use std::fs::{create_dir, File, OpenOptions};
@@ -131,23 +131,7 @@
) -> binder::Result<Strong<dyn IVirtualMachine>> {
let mut is_protected = false;
let ret = self.create_vm_internal(config, console_fd, log_fd, &mut is_protected);
- match ret {
- Ok(_) => {
- let ok_status = Status::ok();
- write_vm_creation_stats(
- is_protected,
- /*creation_succeeded*/ true,
- ok_status.exception_code() as i32,
- );
- }
- Err(ref e) => {
- write_vm_creation_stats(
- is_protected,
- /*creation_succeeded*/ false,
- e.exception_code() as i32,
- );
- }
- }
+ write_vm_creation_stats(config, is_protected, &ret);
ret
}
@@ -468,6 +452,7 @@
// Actually start the VM.
let crosvm_config = CrosvmConfig {
cid,
+ name: config.name.clone(),
bootloader: maybe_clone_file(&config.bootloader)?,
kernel: maybe_clone_file(&config.kernel)?,
initrd: maybe_clone_file(&config.initrd)?,
@@ -506,16 +491,6 @@
}
}
-/// Write the stats of VMCreation to statsd
-fn write_vm_creation_stats(is_protected: bool, creation_succeeded: bool, exception_code: i32) {
- match stats_write(Hypervisor::Pkvm, is_protected, creation_succeeded, exception_code) {
- Err(e) => {
- warn!("statslog_rust failed with error: {}", e);
- }
- Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
- }
-}
-
/// Waits for incoming connections from VM. If a new connection is made, stores the stream in the
/// corresponding `VmInstance`.
fn handle_stream_connection_from_vm(state: Arc<Mutex<State>>) -> Result<()> {
@@ -649,6 +624,7 @@
vm_config.memoryMib = config.memoryMib;
}
+ vm_config.name = config.name.clone();
vm_config.protectedVm = config.protectedVm;
vm_config.numCpus = config.numCpus;
vm_config.cpuAffinity = config.cpuAffinity.clone();
@@ -1003,7 +979,7 @@
}
/// Converts a `&ParcelFileDescriptor` to a `File` by cloning the file.
-fn clone_file(file: &ParcelFileDescriptor) -> Result<File, Status> {
+pub fn clone_file(file: &ParcelFileDescriptor) -> Result<File, Status> {
file.as_ref().try_clone().map_err(|e| {
Status::new_exception_str(
ExceptionCode::BAD_PARCELABLE,
@@ -1069,6 +1045,8 @@
})?;
let stream = vm.stream.lock().unwrap().take();
vm.callbacks.notify_payload_started(cid, stream);
+
+ write_vm_booted_stats(vm.requester_uid as i32, &vm.name);
Ok(())
} else {
error!("notifyPayloadStarted is called from an unknown CID {}", cid);
diff --git a/virtualizationservice/src/atom.rs b/virtualizationservice/src/atom.rs
new file mode 100644
index 0000000..feaa72a
--- /dev/null
+++ b/virtualizationservice/src/atom.rs
@@ -0,0 +1,179 @@
+// 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 crate::aidl::clone_file;
+use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
+ DeathReason::DeathReason, IVirtualMachine::IVirtualMachine,
+ VirtualMachineAppConfig::VirtualMachineAppConfig, VirtualMachineConfig::VirtualMachineConfig,
+};
+use android_system_virtualizationservice::binder::{Status, Strong};
+use anyhow::{anyhow, Result};
+use binder::ThreadState;
+use log::{trace, warn};
+use microdroid_payload_config::VmPayloadConfig;
+use statslog_virtualization_rust::{vm_booted, vm_creation_requested, vm_exited};
+use zip::ZipArchive;
+
+fn get_vm_payload_config(config: &VirtualMachineAppConfig) -> Result<VmPayloadConfig> {
+ let apk = config.apk.as_ref().ok_or_else(|| anyhow!("APK is none"))?;
+ let apk_file = clone_file(apk)?;
+ let mut apk_zip = ZipArchive::new(&apk_file)?;
+ let config_file = apk_zip.by_name(&config.configPath)?;
+ let vm_payload_config: VmPayloadConfig = serde_json::from_reader(config_file)?;
+ Ok(vm_payload_config)
+}
+
+/// Write the stats of VMCreation to statsd
+pub fn write_vm_creation_stats(
+ config: &VirtualMachineConfig,
+ is_protected: bool,
+ ret: &binder::Result<Strong<dyn IVirtualMachine>>,
+) {
+ let creation_succeeded;
+ let binder_exception_code;
+ match ret {
+ Ok(_) => {
+ creation_succeeded = true;
+ binder_exception_code = Status::ok().exception_code() as i32;
+ }
+ Err(ref e) => {
+ creation_succeeded = false;
+ binder_exception_code = e.exception_code() as i32;
+ }
+ }
+
+ let vm_identifier;
+ let config_type;
+ let num_cpus;
+ let cpu_affinity;
+ let memory_mib;
+ let apexes;
+ match config {
+ VirtualMachineConfig::AppConfig(config) => {
+ vm_identifier = &config.name;
+ config_type = vm_creation_requested::ConfigType::VirtualMachineAppConfig;
+ num_cpus = config.numCpus;
+ cpu_affinity = config.cpuAffinity.clone().unwrap_or_default();
+ memory_mib = config.memoryMib;
+
+ let vm_payload_config = get_vm_payload_config(config);
+ if let Ok(vm_payload_config) = vm_payload_config {
+ apexes = vm_payload_config
+ .apexes
+ .iter()
+ .map(|x| x.name.clone())
+ .collect::<Vec<String>>()
+ .join(":");
+ } else {
+ apexes = "INFO: Can't get VmPayloadConfig".into();
+ }
+ }
+ VirtualMachineConfig::RawConfig(config) => {
+ vm_identifier = &config.name;
+ config_type = vm_creation_requested::ConfigType::VirtualMachineRawConfig;
+ num_cpus = config.numCpus;
+ cpu_affinity = config.cpuAffinity.clone().unwrap_or_default();
+ memory_mib = config.memoryMib;
+ apexes = String::new();
+ }
+ }
+
+ 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: &cpu_affinity,
+ 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);
+ }
+ Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
+ }
+}
+
+/// Write the stats of VM boot to statsd
+pub fn write_vm_booted_stats(uid: i32, vm_identifier: &String) {
+ let vm_booted = vm_booted::VmBooted { uid, vm_identifier };
+ match vm_booted.stats_write() {
+ Err(e) => {
+ warn!("statslog_rust failed with error: {}", e);
+ }
+ Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
+ }
+}
+
+/// Write the stats of VM exit to statsd
+pub fn write_vm_exited_stats(uid: i32, vm_identifier: &String, reason: DeathReason) {
+ let vm_exited = vm_exited::VmExited {
+ uid,
+ vm_identifier,
+ 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,
+ },
+ };
+ match vm_exited.stats_write() {
+ Err(e) => {
+ warn!("statslog_rust failed with error: {}", e);
+ }
+ Ok(_) => trace!("statslog_rust succeeded for virtualization service"),
+ }
+}
diff --git a/virtualizationservice/src/crosvm.rs b/virtualizationservice/src/crosvm.rs
index a7e82da..29d2fe7 100644
--- a/virtualizationservice/src/crosvm.rs
+++ b/virtualizationservice/src/crosvm.rs
@@ -15,6 +15,7 @@
//! Functions for running instances of `crosvm`.
use crate::aidl::VirtualMachineCallbacks;
+use crate::atom::write_vm_exited_stats;
use crate::Cid;
use anyhow::{anyhow, bail, Context, Error};
use command_fds::CommandFdExt;
@@ -70,6 +71,7 @@
#[derive(Debug)]
pub struct CrosvmConfig {
pub cid: Cid,
+ pub name: String,
pub bootloader: Option<File>,
pub kernel: Option<File>,
pub initrd: Option<File>,
@@ -170,6 +172,8 @@
pub vm_state: Mutex<VmState>,
/// The CID assigned to the VM for vsock communication.
pub cid: Cid,
+ /// The name of the VM.
+ pub name: String,
/// Whether the VM is a protected VM.
pub protected: bool,
/// Directory of temporary files used by the VM while it is running.
@@ -204,10 +208,12 @@
) -> Result<VmInstance, Error> {
validate_config(&config)?;
let cid = config.cid;
+ let name = config.name.clone();
let protected = config.protected;
Ok(VmInstance {
vm_state: Mutex::new(VmState::NotStarted { config }),
cid,
+ name,
protected,
temporary_directory,
requester_uid,
@@ -261,7 +267,10 @@
};
self.handle_ramdump().unwrap_or_else(|e| error!("Error handling ramdump: {}", e));
- self.callbacks.callback_on_died(self.cid, death_reason(&result, &failure_reason));
+
+ let death_reason = death_reason(&result, &failure_reason);
+ self.callbacks.callback_on_died(self.cid, death_reason);
+ write_vm_exited_stats(self.requester_uid as i32, &self.name, death_reason);
// Delete temporary files.
if let Err(e) = remove_dir_all(&self.temporary_directory) {
diff --git a/virtualizationservice/src/main.rs b/virtualizationservice/src/main.rs
index 3b0adb9..93a5966 100644
--- a/virtualizationservice/src/main.rs
+++ b/virtualizationservice/src/main.rs
@@ -15,6 +15,7 @@
//! Android VirtualizationService
mod aidl;
+mod atom;
mod composite;
mod crosvm;
mod payload;
diff --git a/vm/src/main.rs b/vm/src/main.rs
index c421b04..ee0e2e6 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -40,6 +40,10 @@
enum Opt {
/// Run a virtual machine with a config in APK
RunApp {
+ /// Name of VM
+ #[structopt(long)]
+ name: Option<String>,
+
/// Path to VM Payload APK
#[structopt(parse(from_os_str))]
apk: PathBuf,
@@ -102,6 +106,10 @@
},
/// Run a virtual machine
Run {
+ /// Name of VM
+ #[structopt(long)]
+ name: Option<String>,
+
/// Path to VM config JSON
#[structopt(parse(from_os_str))]
config: PathBuf,
@@ -195,6 +203,7 @@
match opt {
Opt::RunApp {
+ name,
apk,
idsig,
instance,
@@ -211,6 +220,7 @@
task_profiles,
extra_idsigs,
} => command_run_app(
+ name,
service.as_ref(),
&apk,
&idsig,
@@ -228,8 +238,9 @@
task_profiles,
&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(
+ name,
service.as_ref(),
&config,
daemonize,
diff --git a/vm/src/run.rs b/vm/src/run.rs
index 9bd7863..05a9390 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -35,6 +35,7 @@
/// Run a VM from the given APK, idsig, and config.
#[allow(clippy::too_many_arguments)]
pub fn command_run_app(
+ name: Option<String>,
service: &dyn IVirtualizationService,
apk: &Path,
idsig: &Path,
@@ -91,6 +92,7 @@
let extra_idsig_fds = extra_idsig_files?.into_iter().map(ParcelFileDescriptor::new).collect();
let config = VirtualMachineConfig::AppConfig(VirtualMachineAppConfig {
+ name: name.unwrap_or_else(|| String::from("VmRunApp")),
apk: apk_fd.into(),
idsig: idsig_fd.into(),
extraIdsigs: extra_idsig_fds,
@@ -117,6 +119,7 @@
/// Run a VM from the given configuration file.
#[allow(clippy::too_many_arguments)]
pub fn command_run(
+ name: Option<String>,
service: &dyn IVirtualizationService,
config_path: &Path,
daemonize: bool,
@@ -136,6 +139,11 @@
if let Some(cpus) = cpus {
config.numCpus = cpus as i32;
}
+ if let Some(name) = name {
+ config.name = name;
+ } else {
+ config.name = String::from("VmRun");
+ }
config.cpuAffinity = cpu_affinity;
config.taskProfiles = task_profiles;
run(
diff --git a/vmbase/example/tests/test.rs b/vmbase/example/tests/test.rs
index fd6eb8c..58fffff 100644
--- a/vmbase/example/tests/test.rs
+++ b/vmbase/example/tests/test.rs
@@ -48,7 +48,9 @@
File::open(VMBASE_EXAMPLE_PATH)
.with_context(|| format!("Failed to open VM image {}", VMBASE_EXAMPLE_PATH))?,
);
+
let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
+ name: String::from("VmBaseTest"),
kernel: None,
initrd: None,
params: None,
diff --git a/vmbase/exceptions_panic.S b/vmbase/exceptions_panic.S
index 6f73da8..4a3f2db 100644
--- a/vmbase/exceptions_panic.S
+++ b/vmbase/exceptions_panic.S
@@ -22,8 +22,8 @@
*/
.macro exception_panic
- mov x0, 0x80400000
- add x0, x0, 9
+ mov x0, 0x84000000
+ movk x0, 9
mov x1, 0
mov x2, 0
mov x3, 0