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_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)",
|
"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)",
|
"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",
|
"vfio 0.0.1",
|
||||||
"vm-allocator 0.1.0",
|
"vm-allocator 0.1.0",
|
||||||
"vm-device 0.1.0",
|
"vm-device 0.1.0",
|
||||||
|
@ -37,6 +37,7 @@ vm-device = { path = "../vm-device" }
|
|||||||
vm-virtio = { path = "../vm-virtio" }
|
vm-virtio = { path = "../vm-virtio" }
|
||||||
vmm-sys-util = ">=0.3.1"
|
vmm-sys-util = ">=0.3.1"
|
||||||
signal-hook = "0.1.13"
|
signal-hook = "0.1.13"
|
||||||
|
tempfile = "3.1.0"
|
||||||
|
|
||||||
[dependencies.linux-loader]
|
[dependencies.linux-loader]
|
||||||
git = "https://github.com/rust-vmm/linux-loader"
|
git = "https://github.com/rust-vmm/linux-loader"
|
||||||
|
@ -587,11 +587,6 @@ impl NetConfig {
|
|||||||
vhost_socket = Some(vhost_socket_str.to_owned());
|
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 {
|
Ok(NetConfig {
|
||||||
tap,
|
tap,
|
||||||
ip,
|
ip,
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
extern crate vm_device;
|
extern crate vm_device;
|
||||||
|
|
||||||
use crate::config::ConsoleOutputMode;
|
use crate::config::ConsoleOutputMode;
|
||||||
use crate::config::VmConfig;
|
use crate::config::{NetConfig, VmConfig};
|
||||||
use crate::interrupt::{
|
use crate::interrupt::{
|
||||||
KvmLegacyUserspaceInterruptManager, KvmMsiInterruptManager, KvmRoutingEntry,
|
KvmLegacyUserspaceInterruptManager, KvmMsiInterruptManager, KvmRoutingEntry,
|
||||||
};
|
};
|
||||||
@ -40,6 +40,7 @@ use std::result;
|
|||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
use std::sync::Weak;
|
use std::sync::Weak;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError};
|
use vfio::{VfioDevice, VfioDmaMapping, VfioPciDevice, VfioPciError};
|
||||||
use vm_allocator::SystemAllocator;
|
use vm_allocator::SystemAllocator;
|
||||||
@ -197,6 +198,12 @@ pub enum DeviceManagerError {
|
|||||||
|
|
||||||
/// Failed cloning a File.
|
/// Failed cloning a File.
|
||||||
CloneFile(io::Error),
|
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>;
|
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 {
|
pub struct DeviceManager {
|
||||||
// Manage address space related to devices
|
// Manage address space related to devices
|
||||||
address_manager: Arc<AddressManager>,
|
address_manager: Arc<AddressManager>,
|
||||||
@ -402,7 +420,10 @@ pub struct DeviceManager {
|
|||||||
virtio_devices: Vec<(VirtioDeviceArc, bool)>,
|
virtio_devices: Vec<(VirtioDeviceArc, bool)>,
|
||||||
|
|
||||||
// The path to the VMM for self spawning
|
// 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 {
|
impl DeviceManager {
|
||||||
@ -413,7 +434,7 @@ impl DeviceManager {
|
|||||||
memory_manager: Arc<Mutex<MemoryManager>>,
|
memory_manager: Arc<Mutex<MemoryManager>>,
|
||||||
_exit_evt: &EventFd,
|
_exit_evt: &EventFd,
|
||||||
reset_evt: &EventFd,
|
reset_evt: &EventFd,
|
||||||
_vmm_path: PathBuf,
|
vmm_path: PathBuf,
|
||||||
) -> DeviceManagerResult<Self> {
|
) -> DeviceManagerResult<Self> {
|
||||||
let io_bus = devices::Bus::new();
|
let io_bus = devices::Bus::new();
|
||||||
let mmio_bus = devices::Bus::new();
|
let mmio_bus = devices::Bus::new();
|
||||||
@ -487,7 +508,8 @@ impl DeviceManager {
|
|||||||
migratable_devices,
|
migratable_devices,
|
||||||
memory_manager,
|
memory_manager,
|
||||||
virtio_devices: Vec::new(),
|
virtio_devices: Vec::new(),
|
||||||
_vmm_path,
|
vmm_path,
|
||||||
|
vhost_user_backends: Vec::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
device_manager
|
device_manager
|
||||||
@ -932,15 +954,45 @@ impl DeviceManager {
|
|||||||
Ok(devices)
|
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
|
/// Add virto-net and vhost-user-net devices
|
||||||
fn make_virtio_net_devices(&mut self) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool)>> {
|
fn make_virtio_net_devices(&mut self) -> DeviceManagerResult<Vec<(VirtioDeviceArc, bool)>> {
|
||||||
let mut devices = Vec::new();
|
let mut devices = Vec::new();
|
||||||
|
let net_devices = self.config.lock().unwrap().net.clone();
|
||||||
if let Some(net_list_cfg) = &self.config.lock().unwrap().net {
|
if let Some(net_list_cfg) = &net_devices {
|
||||||
for net_cfg in net_list_cfg.iter() {
|
for net_cfg in net_list_cfg.iter() {
|
||||||
if net_cfg.vhost_user {
|
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 {
|
let vu_cfg = VhostUserConfig {
|
||||||
sock: net_cfg.vhost_socket.clone().unwrap(),
|
sock,
|
||||||
num_queues: net_cfg.num_queues,
|
num_queues: net_cfg.num_queues,
|
||||||
queue_size: net_cfg.queue_size,
|
queue_size: net_cfg.queue_size,
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,7 @@ extern crate serde;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
extern crate tempfile;
|
||||||
extern crate vmm_sys_util;
|
extern crate vmm_sys_util;
|
||||||
|
|
||||||
use crate::api::{ApiError, ApiRequest, ApiResponse, ApiResponsePayload, VmInfo, VmmPingResponse};
|
use crate::api::{ApiError, ApiRequest, ApiResponse, ApiResponsePayload, VmInfo, VmmPingResponse};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user