diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index 203012b8e..f6e9a4623 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -39,7 +39,6 @@ struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} pub struct Blk { - common: VirtioCommon, vu_common: VhostUserCommon, id: String, config: VirtioBlockConfig, @@ -170,17 +169,17 @@ impl Blk { }; Ok(Blk { - common: VirtioCommon { - device_type: VirtioDeviceType::Block as u32, - queue_sizes: vec![vu_cfg.queue_size; num_queues], - avail_features, - acked_features, - paused_sync: Some(Arc::new(Barrier::new(2))), - min_queues: DEFAULT_QUEUE_NUMBER as u16, - paused: Arc::new(AtomicBool::new(paused)), - ..Default::default() - }, vu_common: VhostUserCommon { + virtio_common: VirtioCommon { + device_type: VirtioDeviceType::Block as u32, + queue_sizes: vec![vu_cfg.queue_size; num_queues], + avail_features, + acked_features, + paused_sync: Some(Arc::new(Barrier::new(2))), + min_queues: DEFAULT_QUEUE_NUMBER as u16, + paused: Arc::new(AtomicBool::new(paused)), + ..Default::default() + }, vu: Some(Arc::new(Mutex::new(vu))), acked_protocol_features, socket_path: vu_cfg.socket, @@ -199,18 +198,18 @@ impl Blk { } fn state(&self) -> std::result::Result { - self.vu_common.state(&self.common, self.config) + self.vu_common.state(self.config) } } impl Drop for Blk { fn drop(&mut self) { - if let Some(kill_evt) = self.common.kill_evt.take() + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() && let Err(e) = kill_evt.write(1) { error!("failed to kill vhost-user-blk: {e:?}"); } - self.common.wait_for_epoll_threads(); + self.vu_common.virtio_common.wait_for_epoll_threads(); if let Some(thread) = self.epoll_thread.take() && let Err(e) = thread.join() { @@ -221,15 +220,15 @@ impl Drop for Blk { impl VirtioDevice for Blk { fn device_type(&self) -> u32 { - self.common.device_type + self.vu_common.virtio_common.device_type } fn queue_max_sizes(&self) -> &[u16] { - &self.common.queue_sizes + &self.vu_common.virtio_common.queue_sizes } fn features(&self) -> u64 { - let mut features = self.common.avail_features; + let mut features = self.vu_common.virtio_common.avail_features; if self.iommu { features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; } @@ -237,7 +236,7 @@ impl VirtioDevice for Blk { } fn ack_features(&mut self, value: u64) { - self.common.ack_features(value); + self.vu_common.virtio_common.ack_features(value); } fn read_config(&self, offset: u64, data: &mut [u8]) { @@ -278,27 +277,29 @@ impl VirtioDevice for Blk { queues, .. } = context; - self.common.activate(&queues, interrupt_cb.clone())?; + self.vu_common + .virtio_common + .activate(&queues, interrupt_cb.clone())?; self.guest_memory = Some(mem.clone()); let backend_req_handler: Option> = None; // Run a dedicated thread for handling potential reconnections with // the backend. - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut handler = self.vu_common.activate( mem, &queues, interrupt_cb, - self.common.acked_features, + self.vu_common.virtio_common.acked_features, backend_req_handler, kill_evt, pause_evt, )?; - let paused = self.common.paused.clone(); - let paused_sync = self.common.paused_sync.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); @@ -317,8 +318,8 @@ impl VirtioDevice for Blk { fn reset(&mut self) -> Option> { // We first must resume the virtio thread if it was paused. - if self.common.pause_evt.take().is_some() { - self.common.resume().ok()?; + if self.vu_common.virtio_common.pause_evt.take().is_some() { + self.vu_common.virtio_common.resume().ok()?; } if let Some(vu) = &self.vu_common.vu @@ -328,7 +329,7 @@ impl VirtioDevice for Blk { return None; } - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } @@ -336,7 +337,7 @@ impl VirtioDevice for Blk { event!("virtio-device", "reset", "id", &self.id); // Return the interrupt - Some(self.common.interrupt_cb.take().unwrap()) + Some(self.vu_common.virtio_common.interrupt_cb.take().unwrap()) } fn shutdown(&mut self) { @@ -354,11 +355,11 @@ impl VirtioDevice for Blk { impl Pausable for Blk { fn pause(&mut self) -> result::Result<(), MigratableError> { self.vu_common.pause()?; - self.common.pause() + self.vu_common.virtio_common.pause() } fn resume(&mut self) -> result::Result<(), MigratableError> { - self.common.resume()?; + self.vu_common.virtio_common.resume()?; if let Some(epoll_thread) = &self.epoll_thread { epoll_thread.thread().unpark(); @@ -397,7 +398,6 @@ impl Migratable for Blk { } fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { - self.vu_common - .complete_migration(self.common.kill_evt.take()) + self.vu_common.complete_migration() } } diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index 1b8edfe6b..3f982ff29 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -59,7 +59,6 @@ impl Default for VirtioFsConfig { unsafe impl ByteValued for VirtioFsConfig {} pub struct Fs { - common: VirtioCommon, vu_common: VhostUserCommon, id: String, config: VirtioFsConfig, @@ -178,17 +177,17 @@ impl Fs { }; Ok(Fs { - common: VirtioCommon { - device_type: VirtioDeviceType::Fs as u32, - avail_features, - acked_features, - queue_sizes: vec![queue_size; num_queues], - paused_sync: Some(Arc::new(Barrier::new(2))), - min_queues: 1, - paused: Arc::new(AtomicBool::new(paused)), - ..Default::default() - }, vu_common: VhostUserCommon { + virtio_common: VirtioCommon { + device_type: VirtioDeviceType::Fs as u32, + avail_features, + acked_features, + queue_sizes: vec![queue_size; num_queues], + paused_sync: Some(Arc::new(Barrier::new(2))), + min_queues: 1, + paused: Arc::new(AtomicBool::new(paused)), + ..Default::default() + }, vu: Some(Arc::new(Mutex::new(vu))), acked_protocol_features, socket_path: path.to_string(), @@ -208,17 +207,17 @@ impl Fs { } fn state(&self) -> std::result::Result { - self.vu_common.state(&self.common, self.config) + self.vu_common.state(self.config) } } impl Drop for Fs { fn drop(&mut self) { - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } - self.common.wait_for_epoll_threads(); + self.vu_common.virtio_common.wait_for_epoll_threads(); if let Some(thread) = self.epoll_thread.take() && let Err(e) = thread.join() { @@ -229,15 +228,15 @@ impl Drop for Fs { impl VirtioDevice for Fs { fn device_type(&self) -> u32 { - self.common.device_type + self.vu_common.virtio_common.device_type } fn queue_max_sizes(&self) -> &[u16] { - &self.common.queue_sizes + &self.vu_common.virtio_common.queue_sizes } fn features(&self) -> u64 { - let mut features = self.common.avail_features; + let mut features = self.vu_common.virtio_common.avail_features; if self.iommu { features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; } @@ -245,7 +244,7 @@ impl VirtioDevice for Fs { } fn ack_features(&mut self, value: u64) { - self.common.ack_features(value); + self.vu_common.virtio_common.ack_features(value); } fn read_config(&self, offset: u64, data: &mut [u8]) { @@ -259,26 +258,28 @@ impl VirtioDevice for Fs { queues, .. } = context; - self.common.activate(&queues, interrupt_cb.clone())?; + self.vu_common + .virtio_common + .activate(&queues, interrupt_cb.clone())?; self.guest_memory = Some(mem.clone()); let backend_req_handler: Option> = None; // Run a dedicated thread for handling potential reconnections with // the backend. - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut handler = self.vu_common.activate( mem, &queues, interrupt_cb, - self.common.acked_features, + self.vu_common.virtio_common.acked_features, backend_req_handler, kill_evt, pause_evt, )?; - let paused = self.common.paused.clone(); - let paused_sync = self.common.paused_sync.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); spawn_virtio_thread( @@ -297,8 +298,8 @@ impl VirtioDevice for Fs { fn reset(&mut self) -> Option> { // We first must resume the virtio thread if it was paused. - if self.common.pause_evt.take().is_some() { - self.common.resume().ok()?; + if self.vu_common.virtio_common.pause_evt.take().is_some() { + self.vu_common.virtio_common.resume().ok()?; } if let Some(vu) = &self.vu_common.vu @@ -308,7 +309,7 @@ impl VirtioDevice for Fs { return None; } - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } @@ -316,7 +317,7 @@ impl VirtioDevice for Fs { event!("virtio-device", "reset", "id", &self.id); // Return the interrupt - Some(self.common.interrupt_cb.take().unwrap()) + Some(self.vu_common.virtio_common.interrupt_cb.take().unwrap()) } fn shutdown(&mut self) { @@ -364,11 +365,11 @@ impl VirtioDevice for Fs { impl Pausable for Fs { fn pause(&mut self) -> result::Result<(), MigratableError> { self.vu_common.pause()?; - self.common.pause() + self.vu_common.virtio_common.pause() } fn resume(&mut self) -> result::Result<(), MigratableError> { - self.common.resume()?; + self.vu_common.virtio_common.resume()?; if let Some(epoll_thread) = &self.epoll_thread { epoll_thread.thread().unpark(); @@ -407,7 +408,6 @@ impl Migratable for Fs { } fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { - self.vu_common - .complete_migration(self.common.kill_evt.take()) + self.vu_common.complete_migration() } } diff --git a/virtio-devices/src/vhost_user/generic_vhost_user.rs b/virtio-devices/src/vhost_user/generic_vhost_user.rs index da8fe53a8..0554973f8 100644 --- a/virtio-devices/src/vhost_user/generic_vhost_user.rs +++ b/virtio-devices/src/vhost_user/generic_vhost_user.rs @@ -34,7 +34,6 @@ pub type State = VhostUserState<()>; struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} pub struct GenericVhostUser { - common: VirtioCommon, vu_common: VhostUserCommon, id: String, // Hold ownership of the memory that is allocated for the device @@ -138,17 +137,17 @@ since the backend only supports {backend_num_queues}\n", }; Ok(GenericVhostUser { - common: VirtioCommon { - device_type, - avail_features, - acked_features, - queue_sizes: request_queue_sizes, - paused_sync: Some(Arc::new(Barrier::new(2))), - min_queues: 1, - paused: Arc::new(AtomicBool::new(paused)), - ..Default::default() - }, vu_common: VhostUserCommon { + virtio_common: VirtioCommon { + device_type, + avail_features, + acked_features, + queue_sizes: request_queue_sizes, + paused_sync: Some(Arc::new(Barrier::new(2))), + min_queues: 1, + paused: Arc::new(AtomicBool::new(paused)), + ..Default::default() + }, vu: Some(Arc::new(Mutex::new(vu))), acked_protocol_features, socket_path: path.to_string(), @@ -168,7 +167,7 @@ since the backend only supports {backend_num_queues}\n", } fn state(&self) -> std::result::Result { - self.vu_common.state(&self.common, ()) + self.vu_common.state(()) } #[cold] @@ -189,11 +188,11 @@ space access. Reads will return 0xFF and writes will be ignored." impl Drop for GenericVhostUser { fn drop(&mut self) { - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } - self.common.wait_for_epoll_threads(); + self.vu_common.virtio_common.wait_for_epoll_threads(); if let Some(thread) = self.epoll_thread.take() && let Err(e) = thread.join() { @@ -204,15 +203,15 @@ impl Drop for GenericVhostUser { impl VirtioDevice for GenericVhostUser { fn device_type(&self) -> u32 { - self.common.device_type + self.vu_common.virtio_common.device_type } fn queue_max_sizes(&self) -> &[u16] { - &self.common.queue_sizes + &self.vu_common.virtio_common.queue_sizes } fn features(&self) -> u64 { - let mut features = self.common.avail_features; + let mut features = self.vu_common.virtio_common.avail_features; if self.iommu { features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; } @@ -220,7 +219,7 @@ impl VirtioDevice for GenericVhostUser { } fn ack_features(&mut self, value: u64) { - self.common.ack_features(value); + self.vu_common.virtio_common.ack_features(value); } fn read_config(&self, offset: u64, data: &mut [u8]) { @@ -282,26 +281,28 @@ impl VirtioDevice for GenericVhostUser { queues, .. } = context; - self.common.activate(&queues, interrupt_cb.clone())?; + self.vu_common + .virtio_common + .activate(&queues, interrupt_cb.clone())?; self.guest_memory = Some(mem.clone()); let backend_req_handler: Option> = None; // Run a dedicated thread for handling potential reconnections with // the backend. - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut handler = self.vu_common.activate( mem, &queues, interrupt_cb, - self.common.acked_features, + self.vu_common.virtio_common.acked_features, backend_req_handler, kill_evt, pause_evt, )?; - let paused = self.common.paused.clone(); - let paused_sync = self.common.paused_sync.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); spawn_virtio_thread( @@ -320,8 +321,8 @@ impl VirtioDevice for GenericVhostUser { fn reset(&mut self) -> Option> { // We first must resume the virtio thread if it was paused. - if self.common.pause_evt.take().is_some() { - self.common.resume().ok()?; + if self.vu_common.virtio_common.pause_evt.take().is_some() { + self.vu_common.virtio_common.resume().ok()?; } if let Some(vu) = &self.vu_common.vu @@ -331,7 +332,7 @@ impl VirtioDevice for GenericVhostUser { return None; } - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } @@ -339,7 +340,7 @@ impl VirtioDevice for GenericVhostUser { event!("virtio-device", "reset", "id", &self.id); // Return the interrupt - Some(self.common.interrupt_cb.take().unwrap()) + Some(self.vu_common.virtio_common.interrupt_cb.take().unwrap()) } fn shutdown(&mut self) { @@ -387,11 +388,11 @@ impl VirtioDevice for GenericVhostUser { impl Pausable for GenericVhostUser { fn pause(&mut self) -> result::Result<(), MigratableError> { self.vu_common.pause()?; - self.common.pause() + self.vu_common.virtio_common.pause() } fn resume(&mut self) -> result::Result<(), MigratableError> { - self.common.resume()?; + self.vu_common.virtio_common.resume()?; if let Some(epoll_thread) = &self.epoll_thread { epoll_thread.thread().unpark(); @@ -430,7 +431,6 @@ impl Migratable for GenericVhostUser { } fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { - self.vu_common - .complete_migration(self.common.kill_evt.take()) + self.vu_common.complete_migration() } } diff --git a/virtio-devices/src/vhost_user/mod.rs b/virtio-devices/src/vhost_user/mod.rs index 86a774737..a80c5aa23 100644 --- a/virtio-devices/src/vhost_user/mod.rs +++ b/virtio-devices/src/vhost_user/mod.rs @@ -29,7 +29,7 @@ use crate::{ ActivateError, EPOLL_HELPER_EVENT_LAST, EpollHelper, EpollHelperError, EpollHelperHandler, GuestMemoryMmap, GuestRegionMmap, VIRTIO_F_IN_ORDER, VIRTIO_F_NOTIFICATION_DATA, VIRTIO_F_ORDER_PLATFORM, VIRTIO_F_RING_EVENT_IDX, VIRTIO_F_RING_INDIRECT_DESC, - VIRTIO_F_VERSION_1, VirtioInterrupt, + VIRTIO_F_VERSION_1, VirtioCommon, VirtioInterrupt, }; pub mod blk; @@ -336,6 +336,7 @@ impl VhostUserState { #[derive(Default)] pub struct VhostUserCommon { + pub virtio_common: VirtioCommon, pub vu: Option>>, pub acked_protocol_features: u64, pub socket_path: String, @@ -485,12 +486,11 @@ impl VhostUserCommon { pub fn state( &self, - common: &crate::VirtioCommon, config: C, ) -> std::result::Result, MigratableError> { let mut state = VhostUserState { - avail_features: common.avail_features, - acked_features: common.acked_features, + avail_features: self.virtio_common.avail_features, + acked_features: self.virtio_common.acked_features, config, acked_protocol_features: self.acked_protocol_features, vu_num_queues: self.vu_num_queues, @@ -586,15 +586,12 @@ impl VhostUserCommon { Ok(()) } - pub fn complete_migration( - &mut self, - kill_evt: Option, - ) -> std::result::Result<(), MigratableError> { + pub fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { self.migration_started = false; // Make sure the device thread is killed in order to prevent from // reconnections to the socket. - if let Some(kill_evt) = kill_evt { + if let Some(kill_evt) = self.virtio_common.kill_evt.take() { kill_evt.write(1).map_err(|e| { MigratableError::CompleteMigration(anyhow!( "Error killing vhost-user thread: {e:?}" diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index d05626901..a270ed541 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -41,7 +41,6 @@ struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} pub struct Net { - common: VirtioCommon, vu_common: VhostUserCommon, id: String, config: VirtioNetConfig, @@ -198,17 +197,17 @@ impl Net { Ok(Net { id, - common: VirtioCommon { - device_type: VirtioDeviceType::Net as u32, - queue_sizes: vec![vu_cfg.queue_size; num_queues], - avail_features, - acked_features, - paused_sync: Some(Arc::new(Barrier::new(2))), - min_queues: DEFAULT_QUEUE_NUMBER as u16, - paused: Arc::new(AtomicBool::new(paused)), - ..Default::default() - }, vu_common: VhostUserCommon { + virtio_common: VirtioCommon { + device_type: VirtioDeviceType::Net as u32, + queue_sizes: vec![vu_cfg.queue_size; num_queues], + avail_features, + acked_features, + paused_sync: Some(Arc::new(Barrier::new(2))), + min_queues: DEFAULT_QUEUE_NUMBER as u16, + paused: Arc::new(AtomicBool::new(paused)), + ..Default::default() + }, vu: Some(Arc::new(Mutex::new(vu))), acked_protocol_features, socket_path: vu_cfg.socket, @@ -228,19 +227,19 @@ impl Net { } fn state(&self) -> std::result::Result { - self.vu_common.state(&self.common, self.config) + self.vu_common.state(self.config) } } impl Drop for Net { fn drop(&mut self) { - if let Some(kill_evt) = self.common.kill_evt.take() + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() && let Err(e) = kill_evt.write(1) { error!("failed to kill vhost-user-net: {e:?}"); } - self.common.wait_for_epoll_threads(); + self.vu_common.virtio_common.wait_for_epoll_threads(); if let Some(thread) = self.epoll_thread.take() && let Err(e) = thread.join() @@ -258,15 +257,15 @@ impl Drop for Net { impl VirtioDevice for Net { fn device_type(&self) -> u32 { - self.common.device_type + self.vu_common.virtio_common.device_type } fn queue_max_sizes(&self) -> &[u16] { - &self.common.queue_sizes + &self.vu_common.virtio_common.queue_sizes } fn features(&self) -> u64 { - let mut features = self.common.avail_features; + let mut features = self.vu_common.virtio_common.avail_features; if self.iommu { features |= 1u64 << VIRTIO_F_ACCESS_PLATFORM; } @@ -274,7 +273,7 @@ impl VirtioDevice for Net { } fn ack_features(&mut self, value: u64) { - self.common.ack_features(value); + self.vu_common.virtio_common.ack_features(value); } fn read_config(&self, offset: u64, data: &mut [u8]) { @@ -288,18 +287,28 @@ impl VirtioDevice for Net { mut queues, .. } = context; - self.common.activate(&queues, interrupt_cb.clone())?; + self.vu_common + .virtio_common + .activate(&queues, interrupt_cb.clone())?; self.guest_memory = Some(mem.clone()); let num_queues = queues.len(); - let event_idx = self.common.feature_acked(VIRTIO_RING_F_EVENT_IDX.into()); - if self.common.feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) && !num_queues.is_multiple_of(2) { + let event_idx = self + .vu_common + .virtio_common + .feature_acked(VIRTIO_RING_F_EVENT_IDX.into()); + if self + .vu_common + .virtio_common + .feature_acked(VIRTIO_NET_F_CTRL_VQ.into()) + && !num_queues.is_multiple_of(2) + { let ctrl_queue_index = num_queues - 1; let (_, mut ctrl_queue, ctrl_queue_evt) = queues.remove(ctrl_queue_index); ctrl_queue.set_event_idx(event_idx); - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut ctrl_handler = NetCtrlEpollHandler { mem: mem.clone(), @@ -313,12 +322,12 @@ impl VirtioDevice for Net { queue_index: ctrl_queue_index as u16, }; - let paused = self.common.paused.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); // Let's update the barrier as we need 1 for the control queue // thread + 1 for the common vhost-user thread + 1 for the main // thread signalling the pause. - self.common.paused_sync = Some(Arc::new(Barrier::new(3))); - let paused_sync = self.common.paused_sync.clone(); + self.vu_common.virtio_common.paused_sync = Some(Arc::new(Barrier::new(3))); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); spawn_virtio_thread( @@ -336,11 +345,12 @@ impl VirtioDevice for Net { // The backend acknowledged features must not contain VIRTIO_NET_F_MAC // since we don't expect the backend to handle it. - let backend_acked_features = self.common.acked_features & !(1 << VIRTIO_NET_F_MAC); + let backend_acked_features = + self.vu_common.virtio_common.acked_features & !(1 << VIRTIO_NET_F_MAC); // Run a dedicated thread for handling potential reconnections with // the backend. - let (kill_evt, pause_evt) = self.common.dup_eventfds(); + let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds(); let mut handler = self.vu_common.activate( mem, @@ -352,8 +362,8 @@ impl VirtioDevice for Net { pause_evt, )?; - let paused = self.common.paused.clone(); - let paused_sync = self.common.paused_sync.clone(); + let paused = self.vu_common.virtio_common.paused.clone(); + let paused_sync = self.vu_common.virtio_common.paused_sync.clone(); let mut epoll_threads = Vec::new(); spawn_virtio_thread( @@ -371,8 +381,8 @@ impl VirtioDevice for Net { fn reset(&mut self) -> Option> { // We first must resume the virtio thread if it was paused. - if self.common.pause_evt.take().is_some() { - self.common.resume().ok()?; + if self.vu_common.virtio_common.pause_evt.take().is_some() { + self.vu_common.virtio_common.resume().ok()?; } if let Some(vu) = &self.vu_common.vu @@ -382,7 +392,7 @@ impl VirtioDevice for Net { return None; } - if let Some(kill_evt) = self.common.kill_evt.take() { + if let Some(kill_evt) = self.vu_common.virtio_common.kill_evt.take() { // Ignore the result because there is nothing we can do about it. let _ = kill_evt.write(1); } @@ -390,7 +400,7 @@ impl VirtioDevice for Net { event!("virtio-device", "reset", "id", &self.id); // Return the interrupt - Some(self.common.interrupt_cb.take().unwrap()) + Some(self.vu_common.virtio_common.interrupt_cb.take().unwrap()) } fn shutdown(&mut self) { @@ -408,11 +418,11 @@ impl VirtioDevice for Net { impl Pausable for Net { fn pause(&mut self) -> result::Result<(), MigratableError> { self.vu_common.pause()?; - self.common.pause() + self.vu_common.virtio_common.pause() } fn resume(&mut self) -> result::Result<(), MigratableError> { - self.common.resume()?; + self.vu_common.virtio_common.resume()?; if let Some(epoll_thread) = &self.epoll_thread { epoll_thread.thread().unpark(); @@ -455,7 +465,6 @@ impl Migratable for Net { } fn complete_migration(&mut self) -> std::result::Result<(), MigratableError> { - self.vu_common - .complete_migration(self.common.kill_evt.take()) + self.vu_common.complete_migration() } }