2019-09-25 12:14:15 +00:00
|
|
|
// Copyright © 2019 Intel Corporation
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
//
|
|
|
|
|
|
|
|
//! The internal VMM API for Cloud Hypervisor.
|
|
|
|
//!
|
|
|
|
//! This API is a synchronous, [mpsc](https://doc.rust-lang.org/std/sync/mpsc/)
|
|
|
|
//! based IPC for sending commands to the VMM thread, from other
|
|
|
|
//! Cloud Hypervisor threads. The IPC follows a command-response protocol, i.e.
|
|
|
|
//! each command will receive a response back.
|
|
|
|
//!
|
|
|
|
//! The main Cloud Hypervisor thread creates an API event file descriptor
|
|
|
|
//! to notify the VMM thread about pending API commands, together with an
|
|
|
|
//! API mpsc channel. The former is the IPC control plane, the latter is the
|
|
|
|
//! IPC data plane.
|
|
|
|
//! In order to use the IPC, a Cloud Hypervisor thread needs to have a clone
|
|
|
|
//! of both the API event file descriptor and the channel Sender. Then it must
|
|
|
|
//! go through the following steps:
|
|
|
|
//!
|
|
|
|
//! 1. The thread creates an mpsc channel for receiving the command response.
|
|
|
|
//! 2. The thread sends an ApiRequest to the Sender endpoint. The ApiRequest
|
|
|
|
//! contains the response channel Sender, for the VMM API server to be able
|
|
|
|
//! to send the response back.
|
|
|
|
//! 3. The thread writes to the API event file descriptor to notify the VMM
|
|
|
|
//! API server about a pending command.
|
|
|
|
//! 4. The thread reads the response back from the VMM API server, from the
|
|
|
|
//! response channel Receiver.
|
|
|
|
//! 5. The thread handles the response and forwards potential errors.
|
|
|
|
|
2019-11-24 17:39:06 +00:00
|
|
|
extern crate vm_device;
|
2019-09-26 17:00:43 +00:00
|
|
|
extern crate vmm_sys_util;
|
2019-09-18 09:14:49 +00:00
|
|
|
|
|
|
|
pub use self::http::start_http_thread;
|
|
|
|
|
|
|
|
pub mod http;
|
2019-09-26 23:37:06 +00:00
|
|
|
pub mod http_endpoint;
|
2019-09-18 09:14:49 +00:00
|
|
|
|
2020-04-14 09:21:24 +00:00
|
|
|
use crate::config::{
|
2020-04-28 15:21:22 +00:00
|
|
|
DeviceConfig, DiskConfig, FsConfig, NetConfig, PmemConfig, RestoreConfig, VmConfig, VsockConfig,
|
2020-04-14 09:21:24 +00:00
|
|
|
};
|
2019-10-01 12:07:15 +00:00
|
|
|
use crate::vm::{Error as VmError, VmState};
|
2020-06-11 12:32:44 +00:00
|
|
|
use micro_http::Body;
|
2019-10-01 14:41:50 +00:00
|
|
|
use std::io;
|
|
|
|
use std::sync::mpsc::{channel, RecvError, SendError, Sender};
|
2019-12-05 14:50:38 +00:00
|
|
|
use std::sync::{Arc, Mutex};
|
2019-09-26 17:00:43 +00:00
|
|
|
use vmm_sys_util::eventfd::EventFd;
|
2019-09-25 12:14:15 +00:00
|
|
|
|
|
|
|
/// API errors are sent back from the VMM API server through the ApiResponse.
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ApiError {
|
2019-10-01 14:41:50 +00:00
|
|
|
/// Cannot write to EventFd.
|
|
|
|
EventFdWrite(io::Error),
|
|
|
|
|
|
|
|
/// API request send error
|
|
|
|
RequestSend(SendError<ApiRequest>),
|
|
|
|
|
|
|
|
/// Wrong reponse payload type
|
|
|
|
ResponsePayloadType,
|
|
|
|
|
|
|
|
/// API response receive error
|
|
|
|
ResponseRecv(RecvError),
|
2019-09-25 12:14:15 +00:00
|
|
|
|
2019-09-30 09:53:49 +00:00
|
|
|
/// The VM could not boot.
|
|
|
|
VmBoot(VmError),
|
2019-09-27 14:48:16 +00:00
|
|
|
|
2019-09-30 14:17:28 +00:00
|
|
|
/// The VM is already created.
|
|
|
|
VmAlreadyCreated,
|
|
|
|
|
2019-10-01 14:41:50 +00:00
|
|
|
/// The VM could not be created.
|
|
|
|
VmCreate(VmError),
|
|
|
|
|
2019-10-01 15:24:39 +00:00
|
|
|
/// The VM could not be deleted.
|
|
|
|
VmDelete(VmError),
|
|
|
|
|
2019-10-01 12:07:15 +00:00
|
|
|
/// The VM info is not available.
|
2019-10-01 14:41:50 +00:00
|
|
|
VmInfo(VmError),
|
2019-10-01 12:07:15 +00:00
|
|
|
|
2019-09-30 14:17:28 +00:00
|
|
|
/// The VM config is missing.
|
|
|
|
VmMissingConfig,
|
|
|
|
|
2019-10-10 15:16:58 +00:00
|
|
|
/// The VM could not be paused.
|
|
|
|
VmPause(VmError),
|
|
|
|
|
2019-10-10 15:34:55 +00:00
|
|
|
/// The VM could not resume.
|
|
|
|
VmResume(VmError),
|
|
|
|
|
2019-09-30 14:24:15 +00:00
|
|
|
/// The VM is not booted.
|
|
|
|
VmNotBooted,
|
|
|
|
|
|
|
|
/// The VM is not created.
|
|
|
|
VmNotCreated,
|
|
|
|
|
2019-09-27 14:48:16 +00:00
|
|
|
/// The VM could not shutdown.
|
|
|
|
VmShutdown(VmError),
|
|
|
|
|
|
|
|
/// The VM could not reboot.
|
2019-10-01 14:41:50 +00:00
|
|
|
VmReboot(VmError),
|
2019-10-08 13:23:29 +00:00
|
|
|
|
2019-11-24 17:39:06 +00:00
|
|
|
/// The VM could not be snapshotted.
|
|
|
|
VmSnapshot(VmError),
|
|
|
|
|
2020-02-25 23:03:06 +00:00
|
|
|
/// The VM could not restored.
|
|
|
|
VmRestore(VmError),
|
|
|
|
|
2019-10-08 13:23:29 +00:00
|
|
|
/// The VMM could not shutdown.
|
|
|
|
VmmShutdown(VmError),
|
2019-11-26 16:46:10 +00:00
|
|
|
|
|
|
|
/// The VM could not be resized
|
|
|
|
VmResize(VmError),
|
2020-02-27 13:00:46 +00:00
|
|
|
|
|
|
|
/// The device could not be added to the VM.
|
|
|
|
VmAddDevice(VmError),
|
2020-03-09 10:49:15 +00:00
|
|
|
|
|
|
|
/// The device could not be removed from the VM.
|
|
|
|
VmRemoveDevice(VmError),
|
2020-03-20 16:31:15 +00:00
|
|
|
|
|
|
|
/// Cannot create seccomp filter
|
|
|
|
CreateSeccompFilter(seccomp::SeccompError),
|
|
|
|
|
|
|
|
/// Cannot apply seccomp filter
|
|
|
|
ApplySeccompFilter(seccomp::Error),
|
2020-03-23 16:21:58 +00:00
|
|
|
|
2020-03-23 16:21:58 +00:00
|
|
|
/// The disk could not be added to the VM.
|
2020-03-23 16:21:58 +00:00
|
|
|
VmAddDisk(VmError),
|
2020-03-23 16:21:58 +00:00
|
|
|
|
2020-04-14 09:21:24 +00:00
|
|
|
/// The fs could not be added to the VM.
|
|
|
|
VmAddFs(VmError),
|
|
|
|
|
2020-03-23 16:21:58 +00:00
|
|
|
/// The pmem device could not be added to the VM.
|
|
|
|
VmAddPmem(VmError),
|
2020-03-23 16:21:58 +00:00
|
|
|
|
|
|
|
/// The network device could not be added to the VM.
|
|
|
|
VmAddNet(VmError),
|
2020-04-28 15:21:22 +00:00
|
|
|
|
|
|
|
/// The vsock device could not be added to the VM.
|
|
|
|
VmAddVsock(VmError),
|
2019-09-25 12:14:15 +00:00
|
|
|
}
|
2019-10-01 14:41:50 +00:00
|
|
|
pub type ApiResult<T> = std::result::Result<T, ApiError>;
|
2019-09-25 12:14:15 +00:00
|
|
|
|
2019-10-01 12:07:15 +00:00
|
|
|
#[derive(Clone, Deserialize, Serialize)]
|
|
|
|
pub struct VmInfo {
|
2019-12-05 14:50:38 +00:00
|
|
|
pub config: Arc<Mutex<VmConfig>>,
|
2019-10-01 12:07:15 +00:00
|
|
|
pub state: VmState,
|
|
|
|
}
|
|
|
|
|
2019-11-04 18:06:45 +00:00
|
|
|
#[derive(Clone, Deserialize, Serialize)]
|
|
|
|
pub struct VmmPingResponse {
|
|
|
|
pub version: String,
|
|
|
|
}
|
|
|
|
|
2020-05-14 12:34:41 +00:00
|
|
|
#[derive(Clone, Deserialize, Serialize, Default)]
|
2019-11-26 16:46:10 +00:00
|
|
|
pub struct VmResizeData {
|
2020-01-07 10:43:56 +00:00
|
|
|
pub desired_vcpus: Option<u8>,
|
2020-01-10 15:52:23 +00:00
|
|
|
pub desired_ram: Option<u64>,
|
2020-04-03 09:27:20 +00:00
|
|
|
pub desired_ram_w_balloon: Option<u64>,
|
2019-11-26 16:46:10 +00:00
|
|
|
}
|
|
|
|
|
2020-05-14 12:34:41 +00:00
|
|
|
#[derive(Clone, Deserialize, Serialize, Default)]
|
2020-03-09 10:49:15 +00:00
|
|
|
pub struct VmRemoveDeviceData {
|
|
|
|
pub id: String,
|
|
|
|
}
|
|
|
|
|
2020-05-14 12:34:41 +00:00
|
|
|
#[derive(Clone, Deserialize, Serialize, Default)]
|
2019-11-24 17:39:06 +00:00
|
|
|
pub struct VmSnapshotConfig {
|
|
|
|
/// The snapshot destination URL
|
|
|
|
pub destination_url: String,
|
|
|
|
}
|
|
|
|
|
2019-09-25 12:14:15 +00:00
|
|
|
pub enum ApiResponsePayload {
|
|
|
|
/// No data is sent on the channel.
|
|
|
|
Empty,
|
2019-10-01 12:07:15 +00:00
|
|
|
|
|
|
|
/// Virtual machine information
|
|
|
|
VmInfo(VmInfo),
|
2019-11-04 18:06:45 +00:00
|
|
|
|
|
|
|
/// Vmm ping response
|
|
|
|
VmmPing(VmmPingResponse),
|
2020-06-11 12:32:44 +00:00
|
|
|
|
|
|
|
/// Vm action response
|
|
|
|
VmAction(Vec<u8>),
|
2019-09-25 12:14:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// This is the response sent by the VMM API server through the mpsc channel.
|
|
|
|
pub type ApiResponse = std::result::Result<ApiResponsePayload, ApiError>;
|
|
|
|
|
|
|
|
#[allow(clippy::large_enum_variant)]
|
|
|
|
pub enum ApiRequest {
|
|
|
|
/// Create the virtual machine. This request payload is a VM configuration
|
|
|
|
/// (VmConfig).
|
|
|
|
/// If the VMM API server could not create the VM, it will send a VmCreate
|
|
|
|
/// error back.
|
2019-12-05 14:50:38 +00:00
|
|
|
VmCreate(Arc<Mutex<VmConfig>>, Sender<ApiResponse>),
|
2019-09-25 12:14:15 +00:00
|
|
|
|
2019-09-30 09:53:49 +00:00
|
|
|
/// Boot the previously created virtual machine.
|
2019-09-25 12:14:15 +00:00
|
|
|
/// If the VM was not previously created, the VMM API server will send a
|
2019-09-30 09:53:49 +00:00
|
|
|
/// VmBoot error back.
|
|
|
|
VmBoot(Sender<ApiResponse>),
|
2019-09-27 14:48:16 +00:00
|
|
|
|
2019-10-01 15:24:39 +00:00
|
|
|
/// Delete the previously created virtual machine.
|
|
|
|
/// If the VM was not previously created, the VMM API server will send a
|
|
|
|
/// VmDelete error back.
|
|
|
|
/// If the VM is booted, we shut it down first.
|
|
|
|
VmDelete(Sender<ApiResponse>),
|
|
|
|
|
2019-10-01 12:07:15 +00:00
|
|
|
/// Request the VM information.
|
|
|
|
VmInfo(Sender<ApiResponse>),
|
|
|
|
|
2019-11-04 18:06:45 +00:00
|
|
|
/// Request the VMM API server status
|
|
|
|
VmmPing(Sender<ApiResponse>),
|
|
|
|
|
2019-10-10 15:16:58 +00:00
|
|
|
/// Pause a VM.
|
|
|
|
VmPause(Sender<ApiResponse>),
|
|
|
|
|
2019-10-10 15:34:55 +00:00
|
|
|
/// Resume a VM.
|
|
|
|
VmResume(Sender<ApiResponse>),
|
|
|
|
|
2020-06-24 10:20:13 +00:00
|
|
|
/// Get counters for a VM.
|
|
|
|
VmCounters(Sender<ApiResponse>),
|
|
|
|
|
2019-09-27 14:48:16 +00:00
|
|
|
/// Shut the previously booted virtual machine down.
|
|
|
|
/// If the VM was not previously booted or created, the VMM API server
|
|
|
|
/// will send a VmShutdown error back.
|
|
|
|
VmShutdown(Sender<ApiResponse>),
|
|
|
|
|
|
|
|
/// Reboot the previously booted virtual machine.
|
|
|
|
/// If the VM was not previously booted or created, the VMM API server
|
|
|
|
/// will send a VmReboot error back.
|
|
|
|
VmReboot(Sender<ApiResponse>),
|
2019-10-08 13:23:29 +00:00
|
|
|
|
|
|
|
/// Shut the VMM down.
|
|
|
|
/// This will shutdown and delete the current VM, if any, and then exit the
|
|
|
|
/// VMM process.
|
|
|
|
VmmShutdown(Sender<ApiResponse>),
|
2019-11-26 16:46:10 +00:00
|
|
|
|
2020-02-27 13:00:46 +00:00
|
|
|
/// Resize the VM.
|
2019-11-26 16:46:10 +00:00
|
|
|
VmResize(Arc<VmResizeData>, Sender<ApiResponse>),
|
2020-02-27 13:00:46 +00:00
|
|
|
|
|
|
|
/// Add a device to the VM.
|
2020-03-11 15:17:51 +00:00
|
|
|
VmAddDevice(Arc<DeviceConfig>, Sender<ApiResponse>),
|
2020-03-09 10:49:15 +00:00
|
|
|
|
|
|
|
/// Remove a device from the VM.
|
|
|
|
VmRemoveDevice(Arc<VmRemoveDeviceData>, Sender<ApiResponse>),
|
2020-03-23 16:21:58 +00:00
|
|
|
|
|
|
|
/// Add a disk to the VM.
|
|
|
|
VmAddDisk(Arc<DiskConfig>, Sender<ApiResponse>),
|
2020-03-23 16:21:58 +00:00
|
|
|
|
2020-04-14 09:21:24 +00:00
|
|
|
/// Add a fs to the VM.
|
|
|
|
VmAddFs(Arc<FsConfig>, Sender<ApiResponse>),
|
|
|
|
|
2020-03-23 16:21:58 +00:00
|
|
|
/// Add a pmem device to the VM.
|
|
|
|
VmAddPmem(Arc<PmemConfig>, Sender<ApiResponse>),
|
2020-03-23 16:21:58 +00:00
|
|
|
|
|
|
|
/// Add a network device to the VM.
|
|
|
|
VmAddNet(Arc<NetConfig>, Sender<ApiResponse>),
|
2019-11-24 17:39:06 +00:00
|
|
|
|
2020-04-28 15:21:22 +00:00
|
|
|
/// Add a vsock device to the VM.
|
|
|
|
VmAddVsock(Arc<VsockConfig>, Sender<ApiResponse>),
|
|
|
|
|
2019-11-24 17:39:06 +00:00
|
|
|
/// Take a VM snapshot
|
|
|
|
VmSnapshot(Arc<VmSnapshotConfig>, Sender<ApiResponse>),
|
2020-02-25 23:03:06 +00:00
|
|
|
|
|
|
|
/// Restore from a VM snapshot
|
2020-04-07 12:50:19 +00:00
|
|
|
VmRestore(Arc<RestoreConfig>, Sender<ApiResponse>),
|
2019-09-25 12:14:15 +00:00
|
|
|
}
|
2019-09-26 17:00:43 +00:00
|
|
|
|
|
|
|
pub fn vm_create(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
2019-12-05 14:50:38 +00:00
|
|
|
config: Arc<Mutex<VmConfig>>,
|
2019-10-01 14:41:50 +00:00
|
|
|
) -> ApiResult<()> {
|
2019-09-26 17:00:43 +00:00
|
|
|
let (response_sender, response_receiver) = channel();
|
|
|
|
|
|
|
|
// Send the VM creation request.
|
|
|
|
api_sender
|
|
|
|
.send(ApiRequest::VmCreate(config, response_sender))
|
2019-10-01 14:41:50 +00:00
|
|
|
.map_err(ApiError::RequestSend)?;
|
|
|
|
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
|
2019-09-26 17:00:43 +00:00
|
|
|
|
2019-10-01 14:41:50 +00:00
|
|
|
response_receiver.recv().map_err(ApiError::ResponseRecv)??;
|
2019-09-26 17:00:43 +00:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2019-09-27 14:48:16 +00:00
|
|
|
/// Represents a VM related action.
|
|
|
|
/// This is mostly used to factorize code between VM routines
|
|
|
|
/// that only differ by the IPC command they send.
|
|
|
|
pub enum VmAction {
|
|
|
|
/// Boot a VM
|
|
|
|
Boot,
|
|
|
|
|
2019-10-01 15:24:39 +00:00
|
|
|
/// Delete a VM
|
|
|
|
Delete,
|
|
|
|
|
2019-09-27 14:48:16 +00:00
|
|
|
/// Shut a VM down
|
|
|
|
Shutdown,
|
|
|
|
|
|
|
|
/// Reboot a VM
|
|
|
|
Reboot,
|
2019-10-10 15:16:58 +00:00
|
|
|
|
|
|
|
/// Pause a VM
|
|
|
|
Pause,
|
2019-10-10 15:34:55 +00:00
|
|
|
|
|
|
|
/// Resume a VM
|
|
|
|
Resume,
|
2020-05-14 10:17:34 +00:00
|
|
|
|
2020-06-24 10:20:13 +00:00
|
|
|
/// Return VM counters
|
|
|
|
Counters,
|
|
|
|
|
2020-05-14 10:17:34 +00:00
|
|
|
/// Add VFIO device
|
|
|
|
AddDevice(Arc<DeviceConfig>),
|
|
|
|
|
|
|
|
/// Add disk
|
|
|
|
AddDisk(Arc<DiskConfig>),
|
|
|
|
|
|
|
|
/// Add filesystem
|
|
|
|
AddFs(Arc<FsConfig>),
|
|
|
|
|
|
|
|
/// Add pmem
|
|
|
|
AddPmem(Arc<PmemConfig>),
|
|
|
|
|
|
|
|
/// Add network
|
|
|
|
AddNet(Arc<NetConfig>),
|
|
|
|
|
|
|
|
/// Add vsock
|
|
|
|
AddVsock(Arc<VsockConfig>),
|
|
|
|
|
|
|
|
/// Remove VFIO device
|
|
|
|
RemoveDevice(Arc<VmRemoveDeviceData>),
|
|
|
|
|
|
|
|
/// Resize VM
|
|
|
|
Resize(Arc<VmResizeData>),
|
|
|
|
|
|
|
|
/// Restore VM
|
|
|
|
Restore(Arc<RestoreConfig>),
|
|
|
|
|
|
|
|
/// Snapshot VM
|
|
|
|
Snapshot(Arc<VmSnapshotConfig>),
|
2019-09-27 14:48:16 +00:00
|
|
|
}
|
|
|
|
|
2020-06-11 12:32:44 +00:00
|
|
|
fn vm_action(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
|
|
|
action: VmAction,
|
|
|
|
) -> ApiResult<Option<Body>> {
|
2019-09-26 17:00:43 +00:00
|
|
|
let (response_sender, response_receiver) = channel();
|
|
|
|
|
2020-05-14 10:17:34 +00:00
|
|
|
use VmAction::*;
|
2019-09-27 14:48:16 +00:00
|
|
|
let request = match action {
|
2020-05-14 10:17:34 +00:00
|
|
|
Boot => ApiRequest::VmBoot(response_sender),
|
|
|
|
Delete => ApiRequest::VmDelete(response_sender),
|
|
|
|
Shutdown => ApiRequest::VmShutdown(response_sender),
|
|
|
|
Reboot => ApiRequest::VmReboot(response_sender),
|
|
|
|
Pause => ApiRequest::VmPause(response_sender),
|
|
|
|
Resume => ApiRequest::VmResume(response_sender),
|
2020-06-24 10:20:13 +00:00
|
|
|
Counters => ApiRequest::VmCounters(response_sender),
|
2020-05-14 10:17:34 +00:00
|
|
|
AddDevice(v) => ApiRequest::VmAddDevice(v, response_sender),
|
|
|
|
AddDisk(v) => ApiRequest::VmAddDisk(v, response_sender),
|
|
|
|
AddFs(v) => ApiRequest::VmAddFs(v, response_sender),
|
|
|
|
AddPmem(v) => ApiRequest::VmAddPmem(v, response_sender),
|
|
|
|
AddNet(v) => ApiRequest::VmAddNet(v, response_sender),
|
|
|
|
AddVsock(v) => ApiRequest::VmAddVsock(v, response_sender),
|
|
|
|
RemoveDevice(v) => ApiRequest::VmRemoveDevice(v, response_sender),
|
|
|
|
Resize(v) => ApiRequest::VmResize(v, response_sender),
|
|
|
|
Restore(v) => ApiRequest::VmRestore(v, response_sender),
|
|
|
|
Snapshot(v) => ApiRequest::VmSnapshot(v, response_sender),
|
2019-09-27 14:48:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Send the VM request.
|
2019-10-01 14:41:50 +00:00
|
|
|
api_sender.send(request).map_err(ApiError::RequestSend)?;
|
|
|
|
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
|
2019-09-26 17:00:43 +00:00
|
|
|
|
2020-06-11 12:32:44 +00:00
|
|
|
let body = match response_receiver.recv().map_err(ApiError::ResponseRecv)?? {
|
|
|
|
ApiResponsePayload::VmAction(response) => Some(Body::new(response)),
|
|
|
|
ApiResponsePayload::Empty => None,
|
|
|
|
_ => return Err(ApiError::ResponsePayloadType),
|
|
|
|
};
|
2019-09-26 17:00:43 +00:00
|
|
|
|
2020-06-11 12:32:44 +00:00
|
|
|
Ok(body)
|
2019-09-26 17:00:43 +00:00
|
|
|
}
|
2019-09-27 14:48:16 +00:00
|
|
|
|
2020-06-11 12:32:44 +00:00
|
|
|
pub fn vm_boot(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<Option<Body>> {
|
2019-09-27 14:48:16 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::Boot)
|
|
|
|
}
|
|
|
|
|
2020-06-11 12:32:44 +00:00
|
|
|
pub fn vm_delete(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<Option<Body>> {
|
2019-10-01 15:24:39 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::Delete)
|
|
|
|
}
|
|
|
|
|
2020-06-11 12:32:44 +00:00
|
|
|
pub fn vm_shutdown(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<Option<Body>> {
|
2019-09-27 14:48:16 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::Shutdown)
|
|
|
|
}
|
|
|
|
|
2020-06-11 12:32:44 +00:00
|
|
|
pub fn vm_reboot(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<Option<Body>> {
|
2019-09-27 14:48:16 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::Reboot)
|
|
|
|
}
|
2019-10-01 12:07:15 +00:00
|
|
|
|
2020-06-11 12:32:44 +00:00
|
|
|
pub fn vm_pause(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<Option<Body>> {
|
2019-10-10 15:16:58 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::Pause)
|
|
|
|
}
|
|
|
|
|
2020-06-11 12:32:44 +00:00
|
|
|
pub fn vm_resume(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<Option<Body>> {
|
2019-10-10 15:34:55 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::Resume)
|
|
|
|
}
|
|
|
|
|
2020-06-24 10:20:13 +00:00
|
|
|
pub fn vm_counters(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<Option<Body>> {
|
|
|
|
vm_action(api_evt, api_sender, VmAction::Counters)
|
|
|
|
}
|
|
|
|
|
2019-11-24 17:39:06 +00:00
|
|
|
pub fn vm_snapshot(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
|
|
|
data: Arc<VmSnapshotConfig>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::Snapshot(data))
|
2019-11-24 17:39:06 +00:00
|
|
|
}
|
|
|
|
|
2020-02-25 23:03:06 +00:00
|
|
|
pub fn vm_restore(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
2020-04-07 12:50:19 +00:00
|
|
|
data: Arc<RestoreConfig>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::Restore(data))
|
2020-02-25 23:03:06 +00:00
|
|
|
}
|
|
|
|
|
2019-10-01 14:41:50 +00:00
|
|
|
pub fn vm_info(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<VmInfo> {
|
2019-10-01 12:07:15 +00:00
|
|
|
let (response_sender, response_receiver) = channel();
|
|
|
|
|
|
|
|
// Send the VM request.
|
|
|
|
api_sender
|
|
|
|
.send(ApiRequest::VmInfo(response_sender))
|
2019-10-01 14:41:50 +00:00
|
|
|
.map_err(ApiError::RequestSend)?;
|
|
|
|
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
|
2019-10-01 12:07:15 +00:00
|
|
|
|
2019-10-01 14:41:50 +00:00
|
|
|
let vm_info = response_receiver.recv().map_err(ApiError::ResponseRecv)??;
|
2019-10-01 12:07:15 +00:00
|
|
|
|
|
|
|
match vm_info {
|
|
|
|
ApiResponsePayload::VmInfo(info) => Ok(info),
|
2019-10-01 14:41:50 +00:00
|
|
|
_ => Err(ApiError::ResponsePayloadType),
|
2019-10-01 12:07:15 +00:00
|
|
|
}
|
|
|
|
}
|
2019-10-08 13:23:29 +00:00
|
|
|
|
2019-11-04 18:06:45 +00:00
|
|
|
pub fn vmm_ping(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<VmmPingResponse> {
|
|
|
|
let (response_sender, response_receiver) = channel();
|
|
|
|
|
|
|
|
api_sender
|
|
|
|
.send(ApiRequest::VmmPing(response_sender))
|
|
|
|
.map_err(ApiError::RequestSend)?;
|
|
|
|
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
|
|
|
|
|
|
|
|
let vmm_pong = response_receiver.recv().map_err(ApiError::ResponseRecv)??;
|
|
|
|
|
|
|
|
match vmm_pong {
|
|
|
|
ApiResponsePayload::VmmPing(pong) => Ok(pong),
|
|
|
|
_ => Err(ApiError::ResponsePayloadType),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-08 13:23:29 +00:00
|
|
|
pub fn vmm_shutdown(api_evt: EventFd, api_sender: Sender<ApiRequest>) -> ApiResult<()> {
|
|
|
|
let (response_sender, response_receiver) = channel();
|
|
|
|
|
|
|
|
// Send the VMM shutdown request.
|
|
|
|
api_sender
|
|
|
|
.send(ApiRequest::VmmShutdown(response_sender))
|
|
|
|
.map_err(ApiError::RequestSend)?;
|
|
|
|
api_evt.write(1).map_err(ApiError::EventFdWrite)?;
|
|
|
|
|
|
|
|
response_receiver.recv().map_err(ApiError::ResponseRecv)??;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2019-11-26 16:46:10 +00:00
|
|
|
|
|
|
|
pub fn vm_resize(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
|
|
|
data: Arc<VmResizeData>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::Resize(data))
|
2019-11-26 16:46:10 +00:00
|
|
|
}
|
2020-02-27 13:00:46 +00:00
|
|
|
|
|
|
|
pub fn vm_add_device(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
2020-03-11 15:17:51 +00:00
|
|
|
data: Arc<DeviceConfig>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::AddDevice(data))
|
2020-02-27 13:00:46 +00:00
|
|
|
}
|
2020-03-09 10:49:15 +00:00
|
|
|
|
|
|
|
pub fn vm_remove_device(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
|
|
|
data: Arc<VmRemoveDeviceData>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::RemoveDevice(data))
|
2020-03-09 10:49:15 +00:00
|
|
|
}
|
2020-03-23 16:21:58 +00:00
|
|
|
|
|
|
|
pub fn vm_add_disk(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
|
|
|
data: Arc<DiskConfig>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::AddDisk(data))
|
2020-04-14 09:21:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn vm_add_fs(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
|
|
|
data: Arc<FsConfig>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::AddFs(data))
|
2020-03-23 16:21:58 +00:00
|
|
|
}
|
2020-03-23 16:21:58 +00:00
|
|
|
|
|
|
|
pub fn vm_add_pmem(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
|
|
|
data: Arc<PmemConfig>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::AddPmem(data))
|
2020-03-23 16:21:58 +00:00
|
|
|
}
|
2020-03-23 16:21:58 +00:00
|
|
|
|
|
|
|
pub fn vm_add_net(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
|
|
|
data: Arc<NetConfig>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::AddNet(data))
|
2020-03-23 16:21:58 +00:00
|
|
|
}
|
2020-04-28 15:21:22 +00:00
|
|
|
|
|
|
|
pub fn vm_add_vsock(
|
|
|
|
api_evt: EventFd,
|
|
|
|
api_sender: Sender<ApiRequest>,
|
|
|
|
data: Arc<VsockConfig>,
|
2020-06-11 12:32:44 +00:00
|
|
|
) -> ApiResult<Option<Body>> {
|
2020-05-14 10:17:34 +00:00
|
|
|
vm_action(api_evt, api_sender, VmAction::AddVsock(data))
|
2020-04-28 15:21:22 +00:00
|
|
|
}
|