mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
devices: gracefully close preserved FDs on device remove
For a graceful resource management of externally provided FDs in Cloud Hypervisor, corresponding FDs need to be closed on a device removal. This is the case for virtio-net devices using external FDs, for example. With the fix introduced in this commit, we allow management software to properly clean up resources, e.g., libvirt can clean up tap devices. PS: CHV uses "added" and "removed", which has the same meaning as hot device attach/hotplug and hot device detach/unplug. Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de> On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
committed by
Rob Bradford
parent
f1206a19df
commit
a6426e3615
@@ -4512,9 +4512,35 @@ impl DeviceManager {
|
||||
.unwrap()
|
||||
.device_type(),
|
||||
);
|
||||
// When the device is added, we close all file descriptors
|
||||
// opened externally for this device. This allows management
|
||||
// software to properly clean up resources, e.g., libvirt can clean
|
||||
// up tap devices.
|
||||
//
|
||||
// TODO: once we allow externally opened FDs for other devices as well,
|
||||
// we should create a descriptive abstraction/function for this
|
||||
// functionality.
|
||||
match device_type {
|
||||
VirtioDeviceType::Net
|
||||
| VirtioDeviceType::Block
|
||||
VirtioDeviceType::Net => {
|
||||
let mut config = self.config.lock().unwrap();
|
||||
let nets = config.net.as_deref_mut().unwrap();
|
||||
let net_dev_cfg = nets
|
||||
.iter_mut()
|
||||
.find(|net| net.id.as_ref() == Some(&id))
|
||||
// unwrap: the device could not have been removed without an ID
|
||||
.unwrap();
|
||||
let fds = net_dev_cfg.fds.take().unwrap_or(Vec::new());
|
||||
|
||||
debug!("Closing preserved FDs from virtio-net device: id={id}, fds={fds:?}");
|
||||
for fd in fds {
|
||||
config.preserved_fds.as_mut().unwrap().retain(|x| *x != fd);
|
||||
// SAFETY: We are closing the only remaining instance of this FD.
|
||||
unsafe {
|
||||
libc::close(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
VirtioDeviceType::Block
|
||||
| VirtioDeviceType::Pmem
|
||||
| VirtioDeviceType::Fs
|
||||
| VirtioDeviceType::Vsock => {}
|
||||
|
||||
@@ -926,6 +926,10 @@ pub struct VmConfig {
|
||||
// VmConfig instance, such as FDs for creating TAP devices.
|
||||
// Preserved FDs will stay open as long as the holding VmConfig instance is
|
||||
// valid, and will be closed when the holding VmConfig instance is destroyed.
|
||||
//
|
||||
// This is populated as devices are added at runtime. Removing them again
|
||||
// causes the FDs to be closed early. This allows management software to
|
||||
// gracefully clean up resources (e.g., libvirt closes tap devices).
|
||||
#[serde(skip)]
|
||||
pub preserved_fds: Option<Vec<i32>>,
|
||||
#[serde(default)]
|
||||
|
||||
Reference in New Issue
Block a user