mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-03-20 07:58:55 +00:00
vmm: Add support for spawning vhost-user-net backend
If no socket is supplied when enabling "vhost_user=true" on "--net" follow the "exe" path in the /proc entry for this process and launch the network backend (via the vmm_path field.) Currently this only supports creating a new tap interface as the network backend also only supports that. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
d054dddcb3
commit
bc75c1b4e1
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1212,6 +1212,7 @@ dependencies = [
|
||||
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"signal-hook 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vfio 0.0.1",
|
||||
"vm-allocator 0.1.0",
|
||||
"vm-device 0.1.0",
|
||||
|
@ -37,6 +37,7 @@ vm-device = { path = "../vm-device" }
|
||||
vm-virtio = { path = "../vm-virtio" }
|
||||
vmm-sys-util = ">=0.3.1"
|
||||
signal-hook = "0.1.13"
|
||||
tempfile = "3.1.0"
|
||||
|
||||
[dependencies.linux-loader]
|
||||
git = "https://github.com/rust-vmm/linux-loader"
|
||||
|
@ -587,11 +587,6 @@ impl NetConfig {
|
||||
vhost_socket = Some(vhost_socket_str.to_owned());
|
||||
}
|
||||
|
||||
// For now we require a socket if vhost-user is turned on
|
||||
if vhost_user && vhost_socket.is_none() {
|
||||
return Err(Error::ParseNetVhostSocketRequired);
|
||||
}
|
||||
|
||||
Ok(NetConfig {
|
||||
tap,
|
||||
ip,
|
||||
|
@ -12,7 +12,7 @@
|
||||
extern crate vm_device;
|
||||
|
||||
use crate::config::ConsoleOutputMode;
|
||||
use crate::config::VmConfig;
|
||||
use crate::config::{NetConfig, VmConfig};
|
||||
use crate::interrupt::{
|
||||
KvmLegacyUserspaceInterruptManager, KvmMsiInterruptManager, KvmRoutingEntry,
|
||||
};
|
||||
@ -40,6 +40,7 @@ use std::result;
|
||||
#[cfg(feature = "pci_support")]
|
||||
use std::sync::Weak;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tempfile::NamedTempFile;
|
||||
#[cfg(feature = "pci_support")]
|
||||
use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError};
|
||||
use vm_allocator::SystemAllocator;
|
||||
@ -197,6 +198,12 @@ pub enum DeviceManagerError {
|
||||
|
||||
/// Failed cloning a File.
|
||||
CloneFile(io::Error),
|
||||
|
||||
/// Failed to create socket file
|
||||
CreateSocketFile(io::Error),
|
||||
|
||||
/// Failed to spawn the network backend
|
||||
SpawnNetBackend(io::Error),
|
||||
}
|
||||
pub type DeviceManagerResult<T> = result::Result<T, DeviceManagerError>;
|
||||
|
||||
@ -366,6 +373,17 @@ impl DeviceRelocation for AddressManager {
|
||||
}
|
||||
}
|
||||
|
||||
struct ActivatedBackend {
|
||||
_socket_file: tempfile::NamedTempFile,
|
||||
child: std::process::Child,
|
||||
}
|
||||
|
||||
impl Drop for ActivatedBackend {
|
||||
fn drop(&mut self) {
|
||||
self.child.wait().ok();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DeviceManager {
|
||||
// Manage address space related to devices
|
||||
address_manager: Arc<AddressManager>,
|
||||
@ -402,7 +420,10 @@ pub struct DeviceManager {
|
||||
virtio_devices: Vec<(VirtioDeviceArc, bool)>,
|
||||
|
||||
// The path to the VMM for self spawning
|
||||
_vmm_path: PathBuf,
|
||||
vmm_path: PathBuf,
|
||||
|
||||
// Backends that have been spawned
|
||||
vhost_user_backends: Vec<ActivatedBackend>,
|
||||
}
|
||||
|
||||
impl DeviceManager {
|
||||
@ -413,7 +434,7 @@ impl DeviceManager {
|
||||
memory_manager: Arc<Mutex<MemoryManager>>,
|
||||
_exit_evt: &EventFd,
|
||||
reset_evt: &EventFd,
|
||||
_vmm_path: PathBuf,
|
||||
vmm_path: PathBuf,
|
||||
) -> DeviceManagerResult<Self> {
|
||||
let io_bus = devices::Bus::new();
|
||||
let mmio_bus = devices::Bus::new();
|
||||
@ -487,7 +508,8 @@ impl DeviceManager {
|
||||
migratable_devices,
|
||||
memory_manager,
|
||||
virtio_devices: Vec::new(),
|
||||
_vmm_path,
|
||||
vmm_path,
|
||||
vhost_user_backends: Vec::new(),
|
||||
};
|
||||
|
||||
device_manager
|
||||
@ -932,15 +954,45 @@ impl DeviceManager {
|
||||
Ok(devices)
|
||||
}
|
||||
|
||||
/// Launch network backend
|
||||
fn start_net_backend(&mut self, net_cfg: &NetConfig) -> DeviceManagerResult<String> {
|
||||
let _socket_file = NamedTempFile::new().map_err(DeviceManagerError::CreateSocketFile)?;
|
||||
let sock = _socket_file.path().to_str().unwrap().to_owned();
|
||||
|
||||
let child = std::process::Command::new(&self.vmm_path)
|
||||
.args(&[
|
||||
"--net-backend",
|
||||
&format!(
|
||||
"ip={},mask={},sock={},num_queues={},queue_size={}",
|
||||
net_cfg.ip, net_cfg.mask, &sock, net_cfg.num_queues, net_cfg.queue_size
|
||||
),
|
||||
])
|
||||
.spawn()
|
||||
.map_err(DeviceManagerError::SpawnNetBackend)?;
|
||||
|
||||
// The ActivatedBackend::drop() will automatically reap the child
|
||||
self.vhost_user_backends.push(ActivatedBackend {
|
||||
child,
|
||||
_socket_file,
|
||||
});
|
||||
|
||||
Ok(sock)
|
||||
}
|
||||
|
||||
/// Add virto-net and vhost-user-net devices
|
||||
fn make_virtio_net_devices(&mut self) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool)>> {
|
||||
let mut devices = Vec::new();
|
||||
|
||||
if let Some(net_list_cfg) = &self.config.lock().unwrap().net {
|
||||
let net_devices = self.config.lock().unwrap().net.clone();
|
||||
if let Some(net_list_cfg) = &net_devices {
|
||||
for net_cfg in net_list_cfg.iter() {
|
||||
if net_cfg.vhost_user {
|
||||
let sock = if let Some(sock) = net_cfg.vhost_socket.clone() {
|
||||
sock
|
||||
} else {
|
||||
self.start_net_backend(net_cfg)?
|
||||
};
|
||||
let vu_cfg = VhostUserConfig {
|
||||
sock: net_cfg.vhost_socket.clone().unwrap(),
|
||||
sock,
|
||||
num_queues: net_cfg.num_queues,
|
||||
queue_size: net_cfg.queue_size,
|
||||
};
|
||||
|
@ -12,6 +12,7 @@ extern crate serde;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate serde_json;
|
||||
extern crate tempfile;
|
||||
extern crate vmm_sys_util;
|
||||
|
||||
use crate::api::{ApiError, ApiRequest, ApiResponse, ApiResponsePayload, VmInfo, VmmPingResponse};
|
||||
|
Loading…
x
Reference in New Issue
Block a user