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 <rbradford@meta.com>
This commit is contained in:
Rob Bradford
2026-03-26 08:48:32 -07:00
parent e1e6d0a25b
commit a77f89847e
5 changed files with 30 additions and 43 deletions

View File

@@ -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<VirtioBlockConfig>;
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()
}
}
}

View File

@@ -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<VirtioFsConfig>;
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()
}
}
}

View File

@@ -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()
}
}

View File

@@ -295,6 +295,22 @@ impl<S: VhostUserFrontendReqHandler> 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<C> {
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<Arc<Mutex<VhostUserHandle>>>,
@@ -441,9 +457,9 @@ impl VhostUserCommon {
Ok(())
}
pub fn snapshot<'a, T>(&mut self, state: &T) -> std::result::Result<Snapshot, MigratableError>
pub fn snapshot<T>(&mut self, state: &T) -> std::result::Result<Snapshot, MigratableError>
where
T: Serialize + Deserialize<'a>,
T: Serialize,
{
let snapshot = Snapshot::new_from_state(state)?;

View File

@@ -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<VirtioNetConfig>;
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()
}
}
}