runtime-rs: make QemuCmdLine own vsock file descriptor

Make file descriptors to be passed to qemu owned by QemuCmdLine.  See
commit 52958f17cd for more explanation.

Signed-off-by: Pavel Mores <pmores@redhat.com>
This commit is contained in:
Pavel Mores 2024-03-25 11:10:37 +01:00
parent 0cf0e923fc
commit c94e55d45a
2 changed files with 10 additions and 16 deletions

View File

@ -13,7 +13,7 @@ use std::collections::HashMap;
use std::fmt::Display;
use std::fs::{read_to_string, File};
use std::os::fd::AsRawFd;
use std::os::unix::io::RawFd;
use tokio;
// These should have been called MiB and GiB for better readability but the
// more fitting names unfortunately generate linter warnings.
@ -811,13 +811,13 @@ impl ToQemuParams for DeviceVirtioBlk {
struct VhostVsock {
bus_type: VirtioBusType,
vhostfd: RawFd,
vhostfd: tokio::fs::File,
guest_cid: u32,
disable_modern: bool,
}
impl VhostVsock {
fn new(vhostfd: RawFd, guest_cid: u32, bus_type: VirtioBusType) -> VhostVsock {
fn new(vhostfd: tokio::fs::File, guest_cid: u32, bus_type: VirtioBusType) -> VhostVsock {
VhostVsock {
bus_type,
vhostfd,
@ -840,7 +840,7 @@ impl ToQemuParams for VhostVsock {
if self.disable_modern {
params.push("disable-modern=true".to_owned());
}
params.push(format!("vhostfd={}", self.vhostfd));
params.push(format!("vhostfd={}", self.vhostfd.as_raw_fd()));
params.push(format!("guest-cid={}", self.guest_cid));
Ok(vec!["-device".to_owned(), params.join(",")])
@ -1198,8 +1198,8 @@ impl<'a> QemuCmdLine<'a> {
}
}
pub fn add_vsock(&mut self, vhostfd: RawFd, guest_cid: u32) -> Result<()> {
clear_cloexec(vhostfd).context("clearing O_CLOEXEC failed on vsock fd")?;
pub fn add_vsock(&mut self, vhostfd: tokio::fs::File, guest_cid: u32) -> Result<()> {
clear_cloexec(vhostfd.as_raw_fd()).context("clearing O_CLOEXEC failed on vsock fd")?;
let mut vhost_vsock_pci = VhostVsock::new(vhostfd, guest_cid, self.bus_type());

View File

@ -17,7 +17,6 @@ use kata_types::{
};
use persist::sandbox_persist::Persist;
use std::collections::HashMap;
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::process::Stdio;
use tokio::{
@ -65,15 +64,11 @@ impl QemuInner {
info!(sl!(), "Starting QEMU VM");
let netns = self.netns.clone().unwrap_or_default();
// CAUTION: since 'cmdline' contains file descriptors that have to stay
// open until spawn() is called to launch qemu later in this function,
// 'cmdline' has to live at least until spawn() is called
let mut cmdline = QemuCmdLine::new(&self.id, &self.config)?;
// CAUTION: File descriptors that are passed to QEMU must stay open until the QEMU process
// is started and closed afterwards. This is achieved by collecting them in _fds_for_qemu.
// It is mandatory for _fds_for_qemu to last until the QEMU process is forked. Leave it
// in the outer scope of this function for this to happen. The files in _fds_for_qemu
// should not be used in any way.
let mut _fds_for_qemu: Vec<std::fs::File> = Vec::new();
for device in &mut self.devices {
match device {
DeviceType::ShareFs(share_fs_dev) => {
@ -87,8 +82,7 @@ impl QemuInner {
}
DeviceType::Vsock(vsock_dev) => {
let fd = vsock_dev.init_config().await?;
cmdline.add_vsock(fd.as_raw_fd(), vsock_dev.config.guest_cid)?;
_fds_for_qemu.push(fd.into_std().await);
cmdline.add_vsock(fd, vsock_dev.config.guest_cid)?;
}
DeviceType::Block(block_dev) => {
if block_dev.config.path_on_host == self.config.boot_info.initrd {