diff --git a/microdroid/kdump/Android.bp b/microdroid/kdump/Android.bp index 390886b7..cc681a7e 100644 --- a/microdroid/kdump/Android.bp +++ b/microdroid/kdump/Android.bp @@ -4,9 +4,10 @@ package { cc_binary { name: "microdroid_kexec", - stem: "kexec", + stem: "kexec_load", srcs: ["kexec.c"], installable: false, + static_executable: true, // required because this runs before linkerconfig compile_multilib: "64", } diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs index 531c707f..eb533371 100644 --- a/microdroid_manager/src/main.rs +++ b/microdroid_manager/src/main.rs @@ -166,6 +166,8 @@ fn try_main() -> Result<()> { let _ = kernlog::init(); info!("started."); + load_crashkernel_if_supported().context("Failed to load crashkernel")?; + let service = get_vms_rpc_binder() .context("cannot connect to VirtualMachineService") .map_err(|e| MicrodroidError::FailedToConnectToVirtualizationService(e.to_string()))?; @@ -610,6 +612,20 @@ fn load_config(path: &Path) -> Result { Ok(serde_json::from_reader(file)?) } +/// Loads the crashkernel into memory using kexec if the VM is loaded with `crashkernel=' parameter +/// in the cmdline. +fn load_crashkernel_if_supported() -> Result<()> { + let supported = std::fs::read_to_string("/proc/cmdline")?.contains(" crashkernel="); + info!("ramdump supported: {}", supported); + if supported { + let status = Command::new("/system/bin/kexec_load").status()?; + if !status.success() { + return Err(anyhow!("Failed to load crashkernel: {:?}", status)); + } + } + Ok(()) +} + /// Executes the given task. Stdout of the task is piped into the vsock stream to the /// virtualizationservice in the host side. fn exec_task(task: &Task, service: &Strong) -> Result {