diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index 29ab67cf3..f3f8cacd3 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -18,6 +18,8 @@ use std::result; use std::sync::{Arc, Barrier, Mutex}; use std::thread; use std::vec::Vec; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use vhost::vhost_user::message::VhostUserConfigFlags; use vhost::vhost_user::message::VHOST_USER_CONFIG_OFFSET; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; @@ -29,11 +31,22 @@ use virtio_bindings::bindings::virtio_blk::{ VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_WRITE_ZEROES, }; use vm_memory::{ByteValued, GuestAddressSpace, GuestMemoryAtomic}; -use vm_migration::{Migratable, MigratableError, Pausable, Snapshottable, Transportable}; +use vm_migration::{ + Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped, +}; use vmm_sys_util::eventfd::EventFd; const DEFAULT_QUEUE_NUMBER: usize = 1; +#[derive(Versionize)] +pub struct State { + pub avail_features: u64, + pub acked_features: u64, + pub config: VirtioBlockConfig, +} + +impl VersionMapped for State {} + struct SlaveReqHandler {} impl VhostUserMasterReqHandler for SlaveReqHandler {} @@ -144,6 +157,20 @@ impl Blk { vu_num_queues: num_queues, }) } + + fn state(&self) -> State { + State { + avail_features: self.common.avail_features, + acked_features: self.common.acked_features, + config: self.config, + } + } + + fn set_state(&mut self, state: &State) { + self.common.avail_features = state.avail_features; + self.common.acked_features = state.acked_features; + self.config = state.config; + } } impl Drop for Blk { @@ -371,6 +398,15 @@ impl Snapshottable for Blk { fn id(&self) -> String { self.id.clone() } + + fn snapshot(&mut self) -> std::result::Result { + Snapshot::new_from_versioned_state(&self.id(), &self.state()) + } + + fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { + self.set_state(&snapshot.to_versioned_state(&self.id)?); + Ok(()) + } } impl Transportable for Blk {} impl Migratable for Blk {} diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index 79789ce06..05ea28866 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -19,6 +19,8 @@ use std::os::unix::io::AsRawFd; use std::result; use std::sync::{Arc, Barrier, Mutex}; use std::thread; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use vhost::vhost_user::message::{ VhostUserFSSlaveMsg, VhostUserFSSlaveMsgFlags, VhostUserProtocolFeatures, VhostUserVirtioFeatures, VHOST_USER_FS_SLAVE_ENTRIES, @@ -29,12 +31,23 @@ use vhost::vhost_user::{ use vm_memory::{ Address, ByteValued, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, }; -use vm_migration::{Migratable, MigratableError, Pausable, Snapshottable, Transportable}; +use vm_migration::{ + Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped, +}; use vmm_sys_util::eventfd::EventFd; const NUM_QUEUE_OFFSET: usize = 1; const DEFAULT_QUEUE_NUMBER: usize = 2; +#[derive(Versionize)] +pub struct State { + pub avail_features: u64, + pub acked_features: u64, + pub config: VirtioFsConfig, +} + +impl VersionMapped for State {} + struct SlaveReqHandler { cache_offset: GuestAddress, cache_size: u64, @@ -263,11 +276,11 @@ impl VhostUserMasterReqHandler for SlaveReqHandler { } } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Versionize)] #[repr(C, packed)] -struct VirtioFsConfig { - tag: [u8; 36], - num_request_queues: u32, +pub struct VirtioFsConfig { + pub tag: [u8; 36], + pub num_request_queues: u32, } impl Default for VirtioFsConfig { @@ -385,6 +398,20 @@ impl Fs { vu_num_queues: num_queues, }) } + + fn state(&self) -> State { + State { + avail_features: self.common.avail_features, + acked_features: self.common.acked_features, + config: self.config, + } + } + + fn set_state(&mut self, state: &State) { + self.common.avail_features = state.avail_features; + self.common.acked_features = state.acked_features; + self.config = state.config; + } } impl Drop for Fs { @@ -642,6 +669,15 @@ impl Snapshottable for Fs { fn id(&self) -> String { self.id.clone() } + + fn snapshot(&mut self) -> std::result::Result { + Snapshot::new_from_versioned_state(&self.id(), &self.state()) + } + + fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { + self.set_state(&snapshot.to_versioned_state(&self.id)?); + Ok(()) + } } impl Transportable for Fs {} impl Migratable for Fs {} diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index 8524bf6f7..93bce970c 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -20,6 +20,8 @@ use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier, Mutex}; use std::thread; use std::vec::Vec; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vhost::vhost_user::{MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler}; use virtio_bindings::bindings::virtio_net::{ @@ -29,11 +31,22 @@ use virtio_bindings::bindings::virtio_net::{ VIRTIO_NET_F_MAC, VIRTIO_NET_F_MRG_RXBUF, }; use vm_memory::{ByteValued, GuestAddressSpace, GuestMemoryAtomic}; -use vm_migration::{Migratable, MigratableError, Pausable, Snapshottable, Transportable}; +use vm_migration::{ + Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable, VersionMapped, +}; use vmm_sys_util::eventfd::EventFd; const DEFAULT_QUEUE_NUMBER: usize = 2; +#[derive(Versionize)] +pub struct State { + pub avail_features: u64, + pub acked_features: u64, + pub config: VirtioNetConfig, +} + +impl VersionMapped for State {} + struct SlaveReqHandler {} impl VhostUserMasterReqHandler for SlaveReqHandler {} @@ -195,6 +208,20 @@ impl Net { vu_num_queues, }) } + + fn state(&self) -> State { + State { + avail_features: self.common.avail_features, + acked_features: self.common.acked_features, + config: self.config, + } + } + + fn set_state(&mut self, state: &State) { + self.common.avail_features = state.avail_features; + self.common.acked_features = state.acked_features; + self.config = state.config; + } } impl Drop for Net { @@ -448,6 +475,15 @@ impl Snapshottable for Net { fn id(&self) -> String { self.id.clone() } + + fn snapshot(&mut self) -> std::result::Result { + Snapshot::new_from_versioned_state(&self.id(), &self.state()) + } + + fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { + self.set_state(&snapshot.to_versioned_state(&self.id)?); + Ok(()) + } } impl Transportable for Net {} impl Migratable for Net {}