mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-02 00:02:01 +00:00
runtime-rs: refactor NetDevice in qemu driver
In keeping with architecture of QemuCmdLine implementation we split the functionality into two objects: Netdev to represent and generate the -netdev part and DeviceVirtioNet for the -device virtio-net-<transport> part. This change is a pure refactor, existing functionality does not change. However, we do remove some stub generalizations and govmm-isms, notably: - we remove the NetDev enum since the only network interface types that kata seems to use with qemu are tuntap and macvtap, both of which are implemented by the same -netdev tap - enum DeviceDriver is also left out since it doesn't seem reasonable to try to represent VFIO NICs (which are completely different from virtio-net ones) with the same struct as virtio-net - we also remove VirtioTransport because there's no use for it so far, but with the expectation that it will be added soon. We also make struct Netdev the owner of any vhost-net and queue file descriptors so that their lifetime is tied ultimately to the lifetime of QemuCmdLine automatically, instead of returning the fds to the caller and forcing it to achieve the equivalent functionality but manually. Signed-off-by: Pavel Mores <pmores@redhat.com>
This commit is contained in:
parent
7f23734172
commit
0a57e2bb32
@ -5,11 +5,12 @@
|
||||
|
||||
use super::network::{generate_netdev_fds, NetDevice};
|
||||
use crate::utils::clear_cloexec;
|
||||
use crate::{kernel_param::KernelParams, HypervisorConfig, NetworkConfig};
|
||||
use crate::{kernel_param::KernelParams, Address, HypervisorConfig, NetworkConfig};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_trait::async_trait;
|
||||
use kata_types::config::hypervisor::NetworkInfo;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::fs::{read_to_string, File};
|
||||
use std::os::fd::AsRawFd;
|
||||
@ -892,6 +893,136 @@ impl ToQemuParams for Serial {
|
||||
}
|
||||
}
|
||||
|
||||
fn format_fds(files: &[File]) -> String {
|
||||
files
|
||||
.iter()
|
||||
.map(|file| file.as_raw_fd().to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(":")
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Netdev {
|
||||
id: String,
|
||||
|
||||
// File descriptors for vhost multi-queue support.
|
||||
// {
|
||||
// queue_fds: Vec<File>,
|
||||
// vhost_fds: Vec<File>,
|
||||
// }
|
||||
fds: HashMap<String, Vec<File>>,
|
||||
|
||||
// disable_vhost_net disables virtio device emulation from the host kernel instead of from qemu.
|
||||
disable_vhost_net: bool,
|
||||
}
|
||||
|
||||
impl Netdev {
|
||||
fn new(id: &str, host_if_name: &str, num_queues: u32) -> Result<Netdev> {
|
||||
let (tun_files, vhost_files) = generate_netdev_fds(host_if_name, num_queues)?;
|
||||
let fds = HashMap::from([
|
||||
("fds".to_owned(), tun_files),
|
||||
("vhostfds".to_owned(), vhost_files),
|
||||
]);
|
||||
for file in fds.values().flatten() {
|
||||
clear_cloexec(file.as_raw_fd()).context("clearing O_CLOEXEC failed")?;
|
||||
}
|
||||
|
||||
Ok(Netdev {
|
||||
id: id.to_owned(),
|
||||
fds,
|
||||
disable_vhost_net: false,
|
||||
})
|
||||
}
|
||||
|
||||
fn set_disable_vhost_net(&mut self, disable_vhost_net: bool) -> &mut Self {
|
||||
self.disable_vhost_net = disable_vhost_net;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ToQemuParams for Netdev {
|
||||
async fn qemu_params(&self) -> Result<Vec<String>> {
|
||||
let mut params: Vec<String> = Vec::new();
|
||||
params.push("tap".to_owned());
|
||||
params.push(format!("id={}", self.id));
|
||||
|
||||
if !self.disable_vhost_net {
|
||||
params.push("vhost=on".to_owned());
|
||||
if let Some(vhost_fds) = self.fds.get("vhostfds") {
|
||||
params.push(format!("vhostfds={}", format_fds(vhost_fds)));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(tuntap_fds) = self.fds.get("fds") {
|
||||
params.push(format!("fds={}", format_fds(tuntap_fds)));
|
||||
}
|
||||
|
||||
Ok(vec!["-netdev".to_owned(), params.join(",")])
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeviceVirtioNet {
|
||||
// driver is the qemu device driver
|
||||
device_driver: String,
|
||||
|
||||
// id is the corresponding backend net device identifier.
|
||||
netdev_id: String,
|
||||
|
||||
// mac_address is the guest-side networking device interface MAC address.
|
||||
mac_address: Address,
|
||||
|
||||
// disable_modern prevents qemu from relying on fast MMIO.
|
||||
disable_modern: bool,
|
||||
|
||||
num_queues: u32,
|
||||
}
|
||||
|
||||
impl DeviceVirtioNet {
|
||||
fn new(netdev_id: &str, mac_address: Address) -> DeviceVirtioNet {
|
||||
DeviceVirtioNet {
|
||||
device_driver: "virtio-net-pci".to_owned(),
|
||||
netdev_id: netdev_id.to_owned(),
|
||||
mac_address,
|
||||
disable_modern: false,
|
||||
num_queues: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_disable_modern(&mut self, disable_modern: bool) -> &mut Self {
|
||||
self.disable_modern = disable_modern;
|
||||
self
|
||||
}
|
||||
|
||||
fn set_num_queues(&mut self, num_queues: u32) -> &mut Self {
|
||||
self.num_queues = num_queues;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ToQemuParams for DeviceVirtioNet {
|
||||
async fn qemu_params(&self) -> Result<Vec<String>> {
|
||||
let mut params: Vec<String> = Vec::new();
|
||||
|
||||
//params.push(format!("driver={}", &self.device_driver.to_string()));
|
||||
params.push(self.device_driver.clone());
|
||||
params.push(format!("netdev={}", &self.netdev_id));
|
||||
|
||||
params.push(format!("mac={}", self.mac_address.to_string()));
|
||||
|
||||
if self.disable_modern {
|
||||
params.push("disable-modern=true".to_owned());
|
||||
}
|
||||
|
||||
params.push("mq=on".to_owned());
|
||||
params.push(format!("vectors={}", 2 * self.num_queues + 2));
|
||||
|
||||
Ok(vec!["-device".to_owned(), params.join(",")])
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ToQemuParams for NetDevice {
|
||||
// qemu_params returns the qemu parameters built out of this network device.
|
||||
|
Loading…
Reference in New Issue
Block a user