mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 05:35:20 +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> {
|
fn vm_send_migration(&mut self, _: VmSendMigrationData) -> Result<(), MigratableError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn vm_nmi(&mut self) -> Result<(), VmError> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn http_receiver_stub(exit_evt: EventFd, api_evt: EventFd, api_receiver: Receiver<ApiRequest>) {
|
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::VmCoredump;
|
||||||
use crate::api::{
|
use crate::api::{
|
||||||
AddDisk, ApiAction, ApiRequest, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem, VmAddUserDevice,
|
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,
|
VmReboot, VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeZone, VmRestore, VmResume,
|
||||||
VmSendMigration, VmShutdown, VmSnapshot,
|
VmSendMigration, VmShutdown, VmSnapshot,
|
||||||
};
|
};
|
||||||
@ -172,6 +172,7 @@ vm_action_put_handler!(VmReboot);
|
|||||||
vm_action_put_handler!(VmPause);
|
vm_action_put_handler!(VmPause);
|
||||||
vm_action_put_handler!(VmResume);
|
vm_action_put_handler!(VmResume);
|
||||||
vm_action_put_handler!(VmPowerButton);
|
vm_action_put_handler!(VmPowerButton);
|
||||||
|
vm_action_put_handler!(VmNmi);
|
||||||
|
|
||||||
vm_action_put_handler_body!(VmAddDevice);
|
vm_action_put_handler_body!(VmAddDevice);
|
||||||
vm_action_put_handler_body!(AddDisk);
|
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::VmCoredump;
|
||||||
use crate::api::{
|
use crate::api::{
|
||||||
AddDisk, ApiError, ApiRequest, VmAddDevice, VmAddFs, VmAddNet, VmAddPmem, VmAddUserDevice,
|
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,
|
VmReceiveMigration, VmRemoveDevice, VmResize, VmResizeZone, VmRestore, VmResume,
|
||||||
VmSendMigration, VmShutdown, VmSnapshot,
|
VmSendMigration, VmShutdown, VmSnapshot,
|
||||||
};
|
};
|
||||||
@ -268,6 +268,8 @@ pub static HTTP_ROUTES: Lazy<HttpRoutes> = Lazy::new(|| {
|
|||||||
.insert(endpoint!("/vmm.ping"), Box::new(VmmPing {}));
|
.insert(endpoint!("/vmm.ping"), Box::new(VmmPing {}));
|
||||||
r.routes
|
r.routes
|
||||||
.insert(endpoint!("/vmm.shutdown"), Box::new(VmmShutdown {}));
|
.insert(endpoint!("/vmm.shutdown"), Box::new(VmmShutdown {}));
|
||||||
|
r.routes
|
||||||
|
.insert(endpoint!("/vm.nmi"), Box::new(VmActionHandler::new(&VmNmi)));
|
||||||
|
|
||||||
r
|
r
|
||||||
});
|
});
|
||||||
|
@ -159,6 +159,9 @@ pub enum ApiError {
|
|||||||
|
|
||||||
/// Error triggering power button
|
/// Error triggering power button
|
||||||
VmPowerButton(VmError),
|
VmPowerButton(VmError),
|
||||||
|
|
||||||
|
/// Error triggering NMI
|
||||||
|
VmNmi(VmError),
|
||||||
}
|
}
|
||||||
pub type ApiResult<T> = Result<T, ApiError>;
|
pub type ApiResult<T> = Result<T, ApiError>;
|
||||||
|
|
||||||
@ -200,6 +203,7 @@ impl Display for ApiError {
|
|||||||
VmReceiveMigration(migratable_error) => write!(f, "{}", migratable_error),
|
VmReceiveMigration(migratable_error) => write!(f, "{}", migratable_error),
|
||||||
VmSendMigration(migratable_error) => write!(f, "{}", migratable_error),
|
VmSendMigration(migratable_error) => write!(f, "{}", migratable_error),
|
||||||
VmPowerButton(vm_error) => write!(f, "{}", vm_error),
|
VmPowerButton(vm_error) => write!(f, "{}", vm_error),
|
||||||
|
VmNmi(vm_error) => write!(f, "{}", vm_error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -353,6 +357,8 @@ pub trait RequestHandler {
|
|||||||
&mut self,
|
&mut self,
|
||||||
send_data_migration: VmSendMigrationData,
|
send_data_migration: VmSendMigrationData,
|
||||||
) -> Result<(), MigratableError>;
|
) -> Result<(), MigratableError>;
|
||||||
|
|
||||||
|
fn vm_nmi(&mut self) -> Result<(), VmError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// It would be nice if we could pass around an object like this:
|
/// 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 (response_sender, response_receiver) = channel();
|
||||||
|
|
||||||
let request = action.request(data, response_sender);
|
let request = action.request(data, response_sender);
|
||||||
|
|
||||||
// Send the VM request.
|
// Send the VM request.
|
||||||
api_sender.send(request).map_err(ApiError::RequestSend)?;
|
api_sender.send(request).map_err(ApiError::RequestSend)?;
|
||||||
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
|
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
|
||||||
@ -1415,3 +1422,36 @@ impl ApiAction for VmmShutdown {
|
|||||||
Ok(())
|
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(
|
fn vm_receive_migration(
|
||||||
&mut self,
|
&mut self,
|
||||||
receive_data_migration: VmReceiveMigrationData,
|
receive_data_migration: VmReceiveMigrationData,
|
||||||
|
Loading…
Reference in New Issue
Block a user