vmm: api: Support multiple fds with add-net

Based on the latest code from the micro-http crate, this patch adds the
support for multiple file descriptors to be sent along with the add-net
request. This means we can now hotplug multiqueue network interface to
the VM.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2022-01-21 08:54:22 +01:00 committed by Rob Bradford
parent 400c28fa58
commit 4e46a1bc3c
3 changed files with 13 additions and 8 deletions

2
Cargo.lock generated
View File

@ -493,7 +493,7 @@ dependencies = [
[[package]]
name = "micro_http"
version = "0.1.0"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#0a58eb1ece68e326e68365c4297d0a7c08ecd9bc"
source = "git+https://github.com/firecracker-microvm/micro-http?branch=main#a730d86940081ad044cdfbc1285c1db6d3048392"
dependencies = [
"libc",
"vmm-sys-util",

View File

@ -146,9 +146,13 @@ pub trait EndpointHandler: Sync + Send {
api_notifier: EventFd,
api_sender: Sender<ApiRequest>,
) -> Response {
let file = req.file.as_ref().map(|f| f.try_clone().unwrap());
// Cloning the files here is very important as it dup() the file
// descriptors, leaving open the one that was received. This way,
// rebooting the VM will work since the VM will be created from the
// original file descriptors.
let files = req.files.iter().map(|f| f.try_clone().unwrap()).collect();
let res = match req.method() {
Method::Put => self.put_handler(api_notifier, api_sender, &req.body, file),
Method::Put => self.put_handler(api_notifier, api_sender, &req.body, files),
Method::Get => self.get_handler(api_notifier, api_sender, &req.body),
_ => return Response::new(Version::Http11, StatusCode::BadRequest),
};
@ -176,7 +180,7 @@ pub trait EndpointHandler: Sync + Send {
_api_notifier: EventFd,
_api_sender: Sender<ApiRequest>,
_body: &Option<Body>,
_file: Option<File>,
_files: Vec<File>,
) -> std::result::Result<Option<Body>, HttpError> {
Err(HttpError::BadRequest)
}

View File

@ -76,7 +76,7 @@ impl EndpointHandler for VmActionHandler {
api_notifier: EventFd,
api_sender: Sender<ApiRequest>,
body: &Option<Body>,
file: Option<File>,
mut files: Vec<File>,
) -> std::result::Result<Option<Body>, HttpError> {
use VmAction::*;
if let Some(body) = body {
@ -111,10 +111,11 @@ impl EndpointHandler for VmActionHandler {
AddNet(_) => {
let mut net_cfg: NetConfig = serde_json::from_slice(body.raw())?;
// Update network config with optional file that might have
// Update network config with optional files that might have
// been sent through control message.
if let Some(file) = file {
net_cfg.fds = Some(vec![file.into_raw_fd()]);
if !files.is_empty() {
let fds = files.drain(..).map(|f| f.into_raw_fd()).collect();
net_cfg.fds = Some(fds);
}
vm_add_net(api_notifier, api_sender, Arc::new(net_cfg))
.map_err(HttpError::VmAddNet)