virtio-devices: Remove panic when duplicating activate EventFds

Replace the (unlikely) panic when duplicating the EventFds with a
propagated error.

Signed-off-by: Rob Bradford <rbradford@meta.com>
This commit is contained in:
Rob Bradford
2026-06-01 12:57:22 +01:00
parent 2bcacbe19d
commit 3a1cf6e740
18 changed files with 35 additions and 32 deletions

View File

@@ -644,7 +644,7 @@ impl VirtioDevice for Balloon {
device_status,
} = context;
self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let mut virtqueues = Vec::new();
let (_, queue, queue_evt) = queues.remove(0);

View File

@@ -1104,7 +1104,7 @@ impl VirtioDevice for Block {
queue.set_event_idx(event_idx);
let queue_size = queue.size();
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let queue_idx = i as u16;
let mut handler = BlockEpollHandler {

View File

@@ -729,7 +729,7 @@ impl VirtioDevice for Console {
error!("Failed to signal console driver: {e:?}");
}
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let (_, input_queue, input_queue_evt) = queues.remove(0);
let (_, output_queue, output_queue_evt) = queues.remove(0);

View File

@@ -427,16 +427,21 @@ impl VirtioCommon {
self.workers = None;
}
pub fn dup_eventfds(&self) -> (EventFd, EventFd) {
(
self.workers
.as_ref()
.unwrap()
.kill_evt()
.try_clone()
.unwrap(),
self.pause_evt.as_ref().unwrap().try_clone().unwrap(),
)
pub fn dup_eventfds(&self) -> Result<(EventFd, EventFd), ActivateError> {
let kill_evt = self
.workers
.as_ref()
.ok_or(ActivateError::BadActivate)?
.kill_evt()
.try_clone()
.map_err(ActivateError::CloneEventFd)?;
let pause_evt = self
.pause_evt
.as_ref()
.ok_or(ActivateError::BadActivate)?
.try_clone()
.map_err(ActivateError::CloneEventFd)?;
Ok((kill_evt, pause_evt))
}
pub fn set_access_platform(&mut self, access_platform: Arc<dyn AccessPlatform>) {

View File

@@ -1301,7 +1301,7 @@ impl VirtioDevice for Iommu {
device_status,
} = context;
self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let (_, request_queue, request_queue_evt) = queues.remove(0);
let (_, _event_queue, _event_queue_evt) = queues.remove(0);

View File

@@ -108,8 +108,8 @@ const VIRTIO_F_NOTIFICATION_DATA: u32 = 38;
pub enum ActivateError {
#[error("Failed to activate virtio device")]
BadActivate,
#[error("Failed to clone exit event fd")]
CloneExitEventFd(#[source] std::io::Error),
#[error("Failed to clone EventFd")]
CloneEventFd(#[source] std::io::Error),
#[error("Failed to spawn thread")]
ThreadSpawn(#[source] std::io::Error),
#[error("Failed to setup vhost-user-fs daemon")]

View File

@@ -951,7 +951,7 @@ impl VirtioDevice for Mem {
device_status,
} = context;
self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let (_, queue, queue_evt) = queues.remove(0);

View File

@@ -691,7 +691,7 @@ impl VirtioDevice for Net {
ctrl_queue.set_event_idx(event_idx);
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let mut ctrl_handler = NetCtrlEpollHandler {
mem: mem.clone(),
kill_evt,
@@ -732,7 +732,7 @@ impl VirtioDevice for Net {
let queue_evt_pair = (queue_evt_0, queue_evt_1);
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let rx_rate_limiter: Option<rate_limiter::RateLimiter> = self
.rate_limiter_config

View File

@@ -378,7 +378,7 @@ impl VirtioDevice for Pmem {
device_status,
} = context;
self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
if let Some(disk) = self.disk.as_ref() {
let disk = disk.try_clone().map_err(|e| {
error!("failed cloning pmem disk: {e}");

View File

@@ -253,7 +253,7 @@ impl VirtioDevice for Rng {
device_status,
} = context;
self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
if let Some(file) = self.random_file.as_ref() {
let random_file = file.try_clone().map_err(|e| {

View File

@@ -624,7 +624,7 @@ impl VirtioDevice for Rtc {
device_status,
} = context;
self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let (_, queue, queue_evt) = queues.remove(0);

View File

@@ -34,9 +34,7 @@ where
let seccomp_filter = get_seccomp_filter(seccomp_action, thread_type)
.map_err(ActivateError::CreateSeccompFilter)?;
let thread_exit_evt = exit_evt
.try_clone()
.map_err(ActivateError::CloneExitEventFd)?;
let thread_exit_evt = exit_evt.try_clone().map_err(ActivateError::CloneEventFd)?;
let thread_name = name.to_string();
thread::Builder::new()

View File

@@ -281,7 +281,7 @@ impl VirtioDevice for Blk {
// Run a dedicated thread for handling potential reconnections with
// the backend.
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds();
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds()?;
let mut handler = self.vu_common.activate(
mem,

View File

@@ -255,7 +255,7 @@ impl VirtioDevice for Fs {
let backend_req_handler: Option<FrontendReqHandler<BackendReqHandler>> = None;
// Run a dedicated thread for handling potential reconnections with
// the backend.
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds();
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds()?;
let mut handler = self.vu_common.activate(
mem,

View File

@@ -317,7 +317,7 @@ impl VirtioDevice for GenericVhostUser {
// Run a dedicated thread for handling potential reconnections with
// the backend.
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds();
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds()?;
let mut handler = self.vu_common.activate(
mem,

View File

@@ -289,7 +289,7 @@ impl VirtioDevice for Net {
ctrl_queue.set_event_idx(event_idx);
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds();
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds()?;
let mut ctrl_handler = NetCtrlEpollHandler {
mem: mem.clone(),
@@ -330,7 +330,7 @@ impl VirtioDevice for Net {
// Run a dedicated thread for handling potential reconnections with
// the backend.
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds();
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds()?;
let mut handler = self.vu_common.activate(
mem,

View File

@@ -469,7 +469,7 @@ where
device_status,
} = context;
self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let mut virtqueues = Vec::new();
let mut queue_evts = Vec::new();

View File

@@ -328,7 +328,7 @@ impl VirtioDevice for Watchdog {
device_status,
} = context;
self.common.activate(&queues, interrupt_cb.clone())?;
let (kill_evt, pause_evt) = self.common.dup_eventfds();
let (kill_evt, pause_evt) = self.common.dup_eventfds()?;
let reset_evt = self.reset_evt.try_clone().map_err(|e| {
error!("Failed to clone reset_evt eventfd: {e}");