mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-01 00:46:38 +00:00
runtime-rs: Consolidate the handling of fds passed to QEMU
File descriptors that are passed to QEMU need some special care. We want them to be closed when the QEMU process is started. But at the same time, it is required that the associated rust File structures, either coming from the` std::fs` or the `tokio::fs` crates, are still in scope when the QEMU process is forked. This is currently achieved by keeping File structures in variables at the outer scope of `start_vm()`. This scheme is currently duplicated, with similar justifications in the corresponding comments. Consolidate all this handling in one place with a more generic explanation. Fixes #9281 Signed-off-by: Greg Kurz <groug@kaod.org>
This commit is contained in:
@@ -66,13 +66,11 @@ impl QemuInner {
|
|||||||
|
|
||||||
let mut cmdline = QemuCmdLine::new(&self.id, &self.config)?;
|
let mut cmdline = QemuCmdLine::new(&self.id, &self.config)?;
|
||||||
|
|
||||||
// If there's a Vsock Device in `self.devices` the vhost-vsock file
|
// CAUTION: File descriptors that are passed to QEMU must stay open until the QEMU process
|
||||||
// descriptor needs to stay open until the qemu process launches.
|
// is started and closed afterwards. This is achieved by collecting them in _fds_for_qemu.
|
||||||
// This is why we need to store it in a variable at this scope.
|
// It is mandatory for _fds_for_qemu to last until the QEMU process is forked. Leave it
|
||||||
let mut _vhost_fd = None;
|
// in the outer scope of this function for this to happen. The files in _fds_for_qemu
|
||||||
// We need to keep the vhost-net/tuntap file descriptor open until the QEMU process launches.
|
// should not be used in any way.
|
||||||
// However, we're likely not interested in the specific type of file descriptor itself. We just
|
|
||||||
// want to ensure any fds associated with network devices remain open within the current scope.
|
|
||||||
let mut _fds_for_qemu: Vec<std::fs::File> = Vec::new();
|
let mut _fds_for_qemu: Vec<std::fs::File> = Vec::new();
|
||||||
|
|
||||||
for device in &mut self.devices {
|
for device in &mut self.devices {
|
||||||
@@ -89,7 +87,7 @@ impl QemuInner {
|
|||||||
DeviceType::Vsock(vsock_dev) => {
|
DeviceType::Vsock(vsock_dev) => {
|
||||||
let fd = vsock_dev.init_config().await?;
|
let fd = vsock_dev.init_config().await?;
|
||||||
cmdline.add_vsock(fd.as_raw_fd(), vsock_dev.config.guest_cid)?;
|
cmdline.add_vsock(fd.as_raw_fd(), vsock_dev.config.guest_cid)?;
|
||||||
_vhost_fd = Some(fd);
|
_fds_for_qemu.push(fd.into_std().await);
|
||||||
}
|
}
|
||||||
DeviceType::Block(block_dev) => {
|
DeviceType::Block(block_dev) => {
|
||||||
if block_dev.config.path_on_host == self.config.boot_info.initrd {
|
if block_dev.config.path_on_host == self.config.boot_info.initrd {
|
||||||
@@ -114,7 +112,8 @@ impl QemuInner {
|
|||||||
// we need ensure add_network_device happens in netns.
|
// we need ensure add_network_device happens in netns.
|
||||||
let _netns_guard = NetnsGuard::new(&netns).context("new netns guard")?;
|
let _netns_guard = NetnsGuard::new(&netns).context("new netns guard")?;
|
||||||
|
|
||||||
_fds_for_qemu = cmdline.add_network_device(&network.config, network_info)?;
|
_fds_for_qemu
|
||||||
|
.append(&mut cmdline.add_network_device(&network.config, network_info)?);
|
||||||
}
|
}
|
||||||
_ => info!(sl!(), "qemu cmdline: unsupported device: {:?}", device),
|
_ => info!(sl!(), "qemu cmdline: unsupported device: {:?}", device),
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user