vmm: api: Add a Snapshot command

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2019-11-24 18:39:06 +01:00 committed by Rob Bradford
parent 452475c280
commit cf8f8ce93a
3 changed files with 49 additions and 0 deletions

View File

@ -29,6 +29,7 @@
//! 5. The thread handles the response and forwards potential errors.
extern crate micro_http;
extern crate vm_device;
extern crate vmm_sys_util;
pub use self::http::start_http_thread;
@ -94,6 +95,9 @@ pub enum ApiError {
/// The VM could not reboot.
VmReboot(VmError),
/// The VM could not be snapshotted.
VmSnapshot(VmError),
/// The VMM could not shutdown.
VmmShutdown(VmError),
@ -145,6 +149,12 @@ pub struct VmRemoveDeviceData {
pub id: String,
}
#[derive(Clone, Deserialize, Serialize)]
pub struct VmSnapshotConfig {
/// The snapshot destination URL
pub destination_url: String,
}
pub enum ApiResponsePayload {
/// No data is sent on the channel.
Empty,
@ -222,6 +232,9 @@ pub enum ApiRequest {
/// Add a network device to the VM.
VmAddNet(Arc<NetConfig>, Sender<ApiResponse>),
/// Take a VM snapshot
VmSnapshot(Arc<VmSnapshotConfig>, Sender<ApiResponse>),
}
pub fn vm_create(
@ -310,6 +323,24 @@ pub fn vm_resume(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<
vm_action(api_evt, api_sender, VmAction::Resume)
}
pub fn vm_snapshot(
api_evt: EventFd,
api_sender: Sender<ApiRequest>,
data: Arc<VmSnapshotConfig>,
) -> ApiResult<()> {
let (response_sender, response_receiver) = channel();
// Send the VM snapshot request.
api_sender
.send(ApiRequest::VmSnapshot(data, response_sender))
.map_err(ApiError::RequestSend)?;
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
response_receiver.recv().map_err(ApiError::ResponseRecv)??;
Ok(())
}
pub fn vm_info(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<VmInfo> {
let (response_sender, response_receiver) = channel();

View File

@ -288,6 +288,10 @@ impl Vmm {
}
}
fn vm_snapshot(&mut self, _destination_url: &str) -> result::Result<(), VmError> {
Ok(())
}
fn vm_shutdown(&mut self) -> result::Result<(), VmError> {
if let Some(ref mut vm) = self.vm.take() {
vm.shutdown()
@ -589,6 +593,14 @@ impl Vmm {
sender.send(response).map_err(Error::ApiResponseSend)?;
}
ApiRequest::VmSnapshot(snapshot_data, sender) => {
let response = self
.vm_snapshot(&snapshot_data.destination_url)
.map_err(ApiError::VmSnapshot)
.map(|_| ApiResponsePayload::Empty);
sender.send(response).map_err(Error::ApiResponseSend)?;
}
ApiRequest::VmmShutdown(sender) => {
let response = self
.vmm_shutdown()

View File

@ -180,6 +180,12 @@ pub enum Error {
/// Eventfd write error
EventfdError(std::io::Error),
/// Cannot snapshot VM
Snapshot(MigratableError),
/// Cannot send VM snapshot
SnapshotSend(MigratableError),
}
pub type Result<T> = result::Result<T, Error>;