From c94e55d45a7ca15e294095643202107d1d6c69a7 Mon Sep 17 00:00:00 2001 From: Pavel Mores Date: Mon, 25 Mar 2024 11:10:37 +0100 Subject: [PATCH] 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 --- .../hypervisor/src/qemu/cmdline_generator.rs | 12 ++++++------ src/runtime-rs/crates/hypervisor/src/qemu/inner.rs | 14 ++++---------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs index 2a1eddb064..e6e63cff41 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs @@ -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()); diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs b/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs index 31fc6ff650..16da0bdafb 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs @@ -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 = 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 {