From a77f89847ec1e0f172a6e95b7a6d89aa6d4dc958 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Thu, 26 Mar 2026 08:48:32 -0700 Subject: [PATCH] virtio-devices: vhost_user: Consolidate device State into VhostUserState Each vhost-user device type had near identical State structs. Deduplicate those by introducing a new common struct (and parameterising it when it needs to embed a config member.) This will make it easier to reuse more code in the future and to add more struct members to handle the requirements of snapshot/restore. These changes have been designed to have no impact on the existing snapshot/restore state. Signed-off-by: Rob Bradford --- virtio-devices/src/vhost_user/blk.rs | 13 +++--------- virtio-devices/src/vhost_user/fs.rs | 14 +++---------- .../src/vhost_user/generic_vhost_user.rs | 13 +++--------- virtio-devices/src/vhost_user/mod.rs | 20 +++++++++++++++++-- virtio-devices/src/vhost_user/net.rs | 13 +++--------- 5 files changed, 30 insertions(+), 43 deletions(-) diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index 9125e7990..66958e32c 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -9,7 +9,6 @@ use block::VirtioBlockConfig; use event_monitor::event; use log::{error, info}; use seccompiler::SeccompAction; -use serde::{Deserialize, Serialize}; use vhost::vhost_user::message::{ VhostUserConfigFlags, VhostUserProtocolFeatures, VhostUserVirtioFeatures, }; @@ -29,19 +28,12 @@ use super::vu_common_ctrl::{VhostUserConfig, VhostUserHandle}; use super::{DEFAULT_VIRTIO_FEATURES, Error, Result}; use crate::seccomp_filters::Thread; use crate::thread_helper::spawn_virtio_thread; -use crate::vhost_user::VhostUserCommon; +use crate::vhost_user::{VhostUserCommon, VhostUserState}; use crate::{GuestMemoryMmap, GuestRegionMmap, VIRTIO_F_ACCESS_PLATFORM, VirtioInterrupt}; const DEFAULT_QUEUE_NUMBER: usize = 1; -#[derive(Serialize, Deserialize)] -pub struct State { - pub avail_features: u64, - pub acked_features: u64, - pub config: VirtioBlockConfig, - pub acked_protocol_features: u64, - pub vu_num_queues: usize, -} +pub type State = VhostUserState; struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} @@ -206,6 +198,7 @@ impl Blk { config: self.config, acked_protocol_features: self.vu_common.acked_protocol_features, vu_num_queues: self.vu_common.vu_num_queues, + ..Default::default() } } } diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index fb21105c8..f9f819c0c 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -22,7 +22,7 @@ use super::vu_common_ctrl::VhostUserHandle; use super::{DEFAULT_VIRTIO_FEATURES, Error, Result}; use crate::seccomp_filters::Thread; use crate::thread_helper::spawn_virtio_thread; -use crate::vhost_user::VhostUserCommon; +use crate::vhost_user::{VhostUserCommon, VhostUserState}; use crate::{ ActivateResult, GuestMemoryMmap, GuestRegionMmap, MmapRegion, VIRTIO_F_ACCESS_PLATFORM, VirtioCommon, VirtioDevice, VirtioDeviceType, VirtioInterrupt, VirtioSharedMemoryList, @@ -31,15 +31,7 @@ use crate::{ const NUM_QUEUE_OFFSET: usize = 1; const DEFAULT_QUEUE_NUMBER: usize = 2; -#[derive(Serialize, Deserialize)] -pub struct State { - pub avail_features: u64, - pub acked_features: u64, - pub config: VirtioFsConfig, - pub acked_protocol_features: u64, - pub vu_num_queues: usize, - pub backend_req_support: bool, -} +pub type State = VhostUserState; struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} @@ -215,7 +207,7 @@ impl Fs { config: self.config, acked_protocol_features: self.vu_common.acked_protocol_features, vu_num_queues: self.vu_common.vu_num_queues, - backend_req_support: false, + ..Default::default() } } } diff --git a/virtio-devices/src/vhost_user/generic_vhost_user.rs b/virtio-devices/src/vhost_user/generic_vhost_user.rs index b90c6c079..d0880b02e 100644 --- a/virtio-devices/src/vhost_user/generic_vhost_user.rs +++ b/virtio-devices/src/vhost_user/generic_vhost_user.rs @@ -9,7 +9,6 @@ use std::{result, thread}; use event_monitor::event; use log::{error, info, warn}; use seccompiler::SeccompAction; -use serde::{Deserialize, Serialize}; use vhost::vhost_user::message::{ VhostUserConfigFlags, VhostUserProtocolFeatures, VhostUserVirtioFeatures, }; @@ -24,20 +23,13 @@ use super::vu_common_ctrl::VhostUserHandle; use super::{Error, Result}; use crate::seccomp_filters::Thread; use crate::thread_helper::spawn_virtio_thread; -use crate::vhost_user::VhostUserCommon; +use crate::vhost_user::{VhostUserCommon, VhostUserState}; use crate::{ ActivateResult, GuestMemoryMmap, GuestRegionMmap, MmapRegion, VIRTIO_F_ACCESS_PLATFORM, VirtioCommon, VirtioDevice, VirtioInterrupt, VirtioSharedMemoryList, }; -#[derive(Serialize, Deserialize)] -pub struct State { - pub avail_features: u64, - pub acked_features: u64, - pub acked_protocol_features: u64, - pub vu_num_queues: usize, - pub backend_req_support: bool, -} +pub type State = VhostUserState<()>; struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} @@ -171,6 +163,7 @@ since the backend only supports {backend_num_queues}\n", acked_protocol_features: self.vu_common.acked_protocol_features, vu_num_queues: self.vu_common.vu_num_queues, backend_req_support: false, + ..Default::default() } } diff --git a/virtio-devices/src/vhost_user/mod.rs b/virtio-devices/src/vhost_user/mod.rs index aca9aba11..863212539 100644 --- a/virtio-devices/src/vhost_user/mod.rs +++ b/virtio-devices/src/vhost_user/mod.rs @@ -295,6 +295,22 @@ impl EpollHelperHandler for VhostUserEpollHandle } } +/// Common snapshot state for all vhost-user device types. +/// +/// Generic over `C` which is the device-specific config type +/// (e.g. VirtioBlockConfig, VirtioFsConfig, VirtioNetConfig). +/// Devices without a config type use `()`. +#[derive(Default, Serialize, Deserialize)] +pub struct VhostUserState { + pub avail_features: u64, + pub acked_features: u64, + pub config: C, + pub acked_protocol_features: u64, + pub vu_num_queues: usize, + #[serde(default)] + pub backend_req_support: bool, +} + #[derive(Default)] pub struct VhostUserCommon { pub vu: Option>>, @@ -441,9 +457,9 @@ impl VhostUserCommon { Ok(()) } - pub fn snapshot<'a, T>(&mut self, state: &T) -> std::result::Result + pub fn snapshot(&mut self, state: &T) -> std::result::Result where - T: Serialize + Deserialize<'a>, + T: Serialize, { let snapshot = Snapshot::new_from_state(state)?; diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index 165115ae7..d6d142ba6 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -9,7 +9,6 @@ use event_monitor::event; use log::{error, info}; use net_util::{CtrlQueue, MacAddr, VirtioNetConfig, build_net_config_space}; use seccompiler::SeccompAction; -use serde::{Deserialize, Serialize}; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vhost::vhost_user::{FrontendReqHandler, VhostUserFrontend, VhostUserFrontendReqHandler}; use virtio_bindings::virtio_net::{ @@ -28,7 +27,7 @@ use vmm_sys_util::eventfd::EventFd; use crate::seccomp_filters::Thread; use crate::thread_helper::spawn_virtio_thread; use crate::vhost_user::vu_common_ctrl::{VhostUserConfig, VhostUserHandle}; -use crate::vhost_user::{DEFAULT_VIRTIO_FEATURES, Error, Result, VhostUserCommon}; +use crate::vhost_user::{DEFAULT_VIRTIO_FEATURES, Error, Result, VhostUserCommon, VhostUserState}; use crate::{ ActivateResult, GuestMemoryMmap, GuestRegionMmap, NetCtrlEpollHandler, VIRTIO_F_ACCESS_PLATFORM, VirtioCommon, VirtioDevice, VirtioDeviceType, VirtioInterrupt, @@ -36,14 +35,7 @@ use crate::{ const DEFAULT_QUEUE_NUMBER: usize = 2; -#[derive(Serialize, Deserialize)] -pub struct State { - pub avail_features: u64, - pub acked_features: u64, - pub config: VirtioNetConfig, - pub acked_protocol_features: u64, - pub vu_num_queues: usize, -} +pub type State = VhostUserState; struct BackendReqHandler {} impl VhostUserFrontendReqHandler for BackendReqHandler {} @@ -235,6 +227,7 @@ impl Net { config: self.config, acked_protocol_features: self.vu_common.acked_protocol_features, vu_num_queues: self.vu_common.vu_num_queues, + ..Default::default() } } }