mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-21 21:25:19 +00:00
vmm: add endpoint api for NMI support
Add http endpoint for trigger nmi. Signed-off-by: Yi Wang <foxywang@tencent.com>
This commit is contained in:
parent
f8ac38d113
commit
f40dd4a993
@ -273,6 +273,10 @@ impl RequestHandler for StubApiRequestHandler {
|
||||
fn vm_send_migration(&mut self, _: VmSendMigrationData) -> Result<(), MigratableError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn vm_nmi(&mut self) -> Result<(), VmError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn http_receiver_stub(exit_evt: EventFd, api_evt: EventFd, api_receiver: Receiver<ApiRequest>) {
|
||||
|
@ -9,7 +9,7 @@ use crate::api::http::{error_response, EndpointHandler, HttpError};
|
||||
use crate::api::VmCoredump;
|
||||
use crate::api::{
|
||||
AddDisk, ApiAction, ApiRequest, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem, VmAddUserDevice,
|
||||
VmAddVdpa, VmAddVsock, VmBoot, VmConfig, VmCounters, VmDelete, VmPause, VmPowerButton,
|
||||
VmAddVdpa, VmAddVsock, VmBoot, VmConfig, VmCounters, VmDelete, VmNmi, VmPause, VmPowerButton,
|
||||
VmReboot, VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeZone, VmRestore, VmResume,
|
||||
VmSendMigration, VmShutdown, VmSnapshot,
|
||||
};
|
||||
@ -172,6 +172,7 @@ vm_action_put_handler!(VmReboot);
|
||||
vm_action_put_handler!(VmPause);
|
||||
vm_action_put_handler!(VmResume);
|
||||
vm_action_put_handler!(VmPowerButton);
|
||||
vm_action_put_handler!(VmNmi);
|
||||
|
||||
vm_action_put_handler_body!(VmAddDevice);
|
||||
vm_action_put_handler_body!(AddDisk);
|
||||
|
@ -8,7 +8,7 @@ use self::http_endpoint::{VmActionHandler, VmCreate, VmInfo, VmmPing, VmmShutdow
|
||||
use crate::api::VmCoredump;
|
||||
use crate::api::{
|
||||
AddDisk, ApiError, ApiRequest, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem, VmAddUserDevice,
|
||||
VmAddVdpa, VmAddVsock, VmBoot, VmCounters, VmDelete, VmPause, VmPowerButton, VmReboot,
|
||||
VmAddVdpa, VmAddVsock, VmBoot, VmCounters, VmDelete, VmNmi, VmPause, VmPowerButton, VmReboot,
|
||||
VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeZone, VmRestore, VmResume,
|
||||
VmSendMigration, VmShutdown, VmSnapshot,
|
||||
};
|
||||
@ -268,6 +268,8 @@ pub static HTTP_ROUTES: Lazy<HttpRoutes> = Lazy::new(|| {
|
||||
.insert(endpoint!("/vmm.ping"), Box::new(VmmPing {}));
|
||||
r.routes
|
||||
.insert(endpoint!("/vmm.shutdown"), Box::new(VmmShutdown {}));
|
||||
r.routes
|
||||
.insert(endpoint!("/vm.nmi"), Box::new(VmActionHandler::new(&VmNmi)));
|
||||
|
||||
r
|
||||
});
|
||||
|
@ -159,6 +159,9 @@ pub enum ApiError {
|
||||
|
||||
/// Error triggering power button
|
||||
VmPowerButton(VmError),
|
||||
|
||||
/// Error triggering NMI
|
||||
VmNmi(VmError),
|
||||
}
|
||||
pub type ApiResult<T> = Result<T, ApiError>;
|
||||
|
||||
@ -200,6 +203,7 @@ impl Display for ApiError {
|
||||
VmReceiveMigration(migratable_error) => write!(f, "{}", migratable_error),
|
||||
VmSendMigration(migratable_error) => write!(f, "{}", migratable_error),
|
||||
VmPowerButton(vm_error) => write!(f, "{}", vm_error),
|
||||
VmNmi(vm_error) => write!(f, "{}", vm_error),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -353,6 +357,8 @@ pub trait RequestHandler {
|
||||
&mut self,
|
||||
send_data_migration: VmSendMigrationData,
|
||||
) -> Result<(), MigratableError>;
|
||||
|
||||
fn vm_nmi(&mut self) -> Result<(), VmError>;
|
||||
}
|
||||
|
||||
/// It would be nice if we could pass around an object like this:
|
||||
@ -380,6 +386,7 @@ fn get_response<Action: ApiAction>(
|
||||
let (response_sender, response_receiver) = channel();
|
||||
|
||||
let request = action.request(data, response_sender);
|
||||
|
||||
// Send the VM request.
|
||||
api_sender.send(request).map_err(ApiError::RequestSend)?;
|
||||
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
|
||||
@ -1415,3 +1422,36 @@ impl ApiAction for VmmShutdown {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VmNmi;
|
||||
|
||||
impl ApiAction for VmNmi {
|
||||
type RequestBody = ();
|
||||
type ResponseBody = Option<Body>;
|
||||
|
||||
fn request(&self, _: Self::RequestBody, response_sender: Sender<ApiResponse>) -> ApiRequest {
|
||||
Box::new(move |vmm| {
|
||||
info!("API request event: VmNmi");
|
||||
|
||||
let response = vmm
|
||||
.vm_nmi()
|
||||
.map_err(ApiError::VmNmi)
|
||||
.map(|_| ApiResponsePayload::Empty);
|
||||
|
||||
response_sender
|
||||
.send(response)
|
||||
.map_err(VmmError::ApiResponseSend)?;
|
||||
|
||||
Ok(false)
|
||||
})
|
||||
}
|
||||
|
||||
fn send(
|
||||
&self,
|
||||
api_evt: EventFd,
|
||||
api_sender: Sender<ApiRequest>,
|
||||
data: Self::RequestBody,
|
||||
) -> ApiResult<Self::ResponseBody> {
|
||||
get_response_body(self, api_evt, api_sender, data)
|
||||
}
|
||||
}
|
||||
|
@ -1840,6 +1840,15 @@ impl RequestHandler for Vmm {
|
||||
}
|
||||
}
|
||||
|
||||
fn vm_nmi(&mut self) -> result::Result<(), VmError> {
|
||||
if let Some(ref mut vm) = self.vm {
|
||||
info!("nmi");
|
||||
vm.power_button()
|
||||
} else {
|
||||
Err(VmError::VmNotRunning)
|
||||
}
|
||||
}
|
||||
|
||||
fn vm_receive_migration(
|
||||
&mut self,
|
||||
receive_data_migration: VmReceiveMigrationData,
|
||||
|
Loading…
Reference in New Issue
Block a user