vmm: enable coredump

Based on the newly added guest_debug feature, this patch adds http
endpoint support.

Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
Co-authored-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Yi Wang 2022-05-10 19:21:02 +08:00 committed by Sebastien Boeuf
parent ccb604e1e1
commit 8b585b96c1
6 changed files with 59 additions and 1 deletions

View File

@ -58,6 +58,7 @@ amx = ["vmm/amx"]
cmos = ["vmm/cmos"]
fwdebug = ["vmm/fwdebug"]
gdb = ["vmm/gdb"]
guest_debug = ["vmm/guest_debug"]
kvm = ["vmm/kvm"]
mshv = ["vmm/mshv"]
tdx = ["vmm/tdx"]

View File

@ -161,6 +161,8 @@ lazy_static! {
r.routes.insert(endpoint!("/vm.send-migration"), Box::new(VmActionHandler::new(VmAction::SendMigration(Arc::default()))));
r.routes.insert(endpoint!("/vm.shutdown"), Box::new(VmActionHandler::new(VmAction::Shutdown)));
r.routes.insert(endpoint!("/vm.snapshot"), Box::new(VmActionHandler::new(VmAction::Snapshot(Arc::default()))));
#[cfg(feature = "guest_debug")]
r.routes.insert(endpoint!("/vm.coredump"), Box::new(VmActionHandler::new(VmAction::Coredump(Arc::default()))));
r.routes.insert(endpoint!("/vmm.ping"), Box::new(VmmPing {}));
r.routes.insert(endpoint!("/vmm.shutdown"), Box::new(VmmShutdown {}));

View File

@ -4,6 +4,8 @@
//
use crate::api::http::{error_response, EndpointHandler, HttpError};
#[cfg(feature = "guest_debug")]
use crate::api::vm_coredump;
use crate::api::{
vm_add_device, vm_add_disk, vm_add_fs, vm_add_net, vm_add_pmem, vm_add_user_device,
vm_add_vdpa, vm_add_vsock, vm_boot, vm_counters, vm_create, vm_delete, vm_info, vm_pause,
@ -151,6 +153,12 @@ impl EndpointHandler for VmActionHandler {
api_sender,
Arc::new(serde_json::from_slice(body.raw())?),
),
#[cfg(feature = "guest_debug")]
Coredump(_) => vm_coredump(
api_notifier,
api_sender,
Arc::new(serde_json::from_slice(body.raw())?),
),
ReceiveMigration(_) => vm_receive_migration(
api_notifier,
api_sender,

View File

@ -99,6 +99,9 @@ pub enum ApiError {
/// The VM could not restored.
VmRestore(VmError),
/// The VM could not be coredumped.
VmCoredump(VmError),
/// The VMM could not shutdown.
VmmShutdown(VmError),
@ -189,6 +192,12 @@ pub struct VmSnapshotConfig {
pub destination_url: String,
}
#[derive(Clone, Deserialize, Serialize, Default, Debug)]
pub struct VmCoredumpData {
/// The coredump destination file
pub destination_url: String,
}
#[derive(Clone, Deserialize, Serialize, Default, Debug)]
pub struct VmReceiveMigrationData {
/// URL for the reception of migration state
@ -310,6 +319,10 @@ pub enum ApiRequest {
/// Restore from a VM snapshot
VmRestore(Arc<RestoreConfig>, Sender<ApiResponse>),
/// Take a VM coredump
#[cfg(feature = "guest_debug")]
VmCoredump(Arc<VmCoredumpData>, Sender<ApiResponse>),
/// Incoming migration
VmReceiveMigration(Arc<VmReceiveMigrationData>, Sender<ApiResponse>),
@ -402,6 +415,10 @@ pub enum VmAction {
/// Snapshot VM
Snapshot(Arc<VmSnapshotConfig>),
/// Coredump VM
#[cfg(feature = "guest_debug")]
Coredump(Arc<VmCoredumpData>),
/// Incoming migration
ReceiveMigration(Arc<VmReceiveMigrationData>),
@ -441,6 +458,8 @@ fn vm_action(
ResizeZone(v) => ApiRequest::VmResizeZone(v, response_sender),
Restore(v) => ApiRequest::VmRestore(v, response_sender),
Snapshot(v) => ApiRequest::VmSnapshot(v, response_sender),
#[cfg(feature = "guest_debug")]
Coredump(v) => ApiRequest::VmCoredump(v, response_sender),
ReceiveMigration(v) => ApiRequest::VmReceiveMigration(v, response_sender),
SendMigration(v) => ApiRequest::VmSendMigration(v, response_sender),
PowerButton => ApiRequest::VmPowerButton(response_sender),
@ -526,6 +545,15 @@ pub fn vm_restore(
vm_action(api_evt, api_sender, VmAction::Restore(data))
}
#[cfg(feature = "guest_debug")]
pub fn vm_coredump(
api_evt: EventFd,
api_sender: Sender<ApiRequest>,
data: Arc<VmCoredumpData>,
) -> ApiResult<Option<Body>> {
vm_action(api_evt, api_sender, VmAction::Coredump(data))
}
pub fn vm_info(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<VmInfo> {
let (response_sender, response_receiver) = channel();

View File

@ -79,7 +79,6 @@ pub struct X86_64UserRegs {
unsafe impl ByteValued for X86_64UserRegs {}
#[repr(C)]
#[allow(dead_code)]
pub struct X86_64ElfPrStatus {
pub pad1: [u8; 32],
pub pid: u32,

View File

@ -18,6 +18,8 @@ use crate::config::{
add_to_config, DeviceConfig, DiskConfig, FsConfig, NetConfig, PmemConfig, RestoreConfig,
UserDeviceConfig, VdpaConfig, VmConfig, VsockConfig,
};
#[cfg(feature = "guest_debug")]
use crate::coredump::GuestDebuggable;
#[cfg(all(feature = "kvm", target_arch = "x86_64"))]
use crate::migration::get_vm_snapshot;
use crate::migration::{recv_vm_config, recv_vm_state};
@ -562,6 +564,15 @@ impl Vmm {
}
}
#[cfg(feature = "guest_debug")]
fn vm_coredump(&mut self, destination_url: &str) -> result::Result<(), VmError> {
if let Some(ref mut vm) = self.vm {
vm.coredump(destination_url).map_err(VmError::Coredump)
} else {
Err(VmError::VmNotRunning)
}
}
fn vm_shutdown(&mut self) -> result::Result<(), VmError> {
if let Some(ref mut vm) = self.vm.take() {
vm.shutdown()
@ -1684,6 +1695,15 @@ impl Vmm {
sender.send(response).map_err(Error::ApiResponseSend)?;
}
#[cfg(feature = "guest_debug")]
ApiRequest::VmCoredump(coredump_data, sender) => {
let response = self
.vm_coredump(&coredump_data.destination_url)
.map_err(ApiError::VmCoredump)
.map(|_| ApiResponsePayload::Empty);
sender.send(response).map_err(Error::ApiResponseSend)?;
}
ApiRequest::VmmShutdown(sender) => {
let response = self
.vmm_shutdown()