Load crashkernel using kexec
Microdroid_manager executes the kexec binary as part of the boot process
if ramdumping is supported.
Bug: 238404545
Test: boot microdroid
Change-Id: Ie9835b427dd0e556bf21a004cea070d553b829a8
diff --git a/microdroid/kdump/Android.bp b/microdroid/kdump/Android.bp
index 390886b..cc681a7 100644
--- a/microdroid/kdump/Android.bp
+++ b/microdroid/kdump/Android.bp
@@ -4,9 +4,10 @@
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 531c707..eb53337 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -166,6 +166,8 @@
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 @@
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<dyn IVirtualMachineService>) -> Result<i32> {