diff --git a/Cargo.lock b/Cargo.lock index 0c0d0efe9..b5d53fd7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -141,6 +141,8 @@ dependencies = [ "serde_derive", "serde_json", "thiserror", + "versionize", + "versionize_derive", "virtio-bindings", "vm-memory", "vm-virtio", @@ -1279,6 +1281,8 @@ dependencies = [ "serde", "serde_derive", "serde_json", + "versionize", + "versionize_derive", "vhost", "virtio-bindings", "vm-allocator", diff --git a/block_util/Cargo.toml b/block_util/Cargo.toml index a1c3e6f13..ebc2779bf 100644 --- a/block_util/Cargo.toml +++ b/block_util/Cargo.toml @@ -17,6 +17,8 @@ serde = ">=1.0.27" serde_derive = ">=1.0.27" serde_json = ">=1.0.9" thiserror = "1.0" +versionize = "0.1.6" +versionize_derive = "0.1.4" virtio-bindings = { version = "0.1", features = ["virtio-v5_0_0"]} vm-memory = { version = "0.5.0", features = ["backend-mmap", "backend-atomic"] } vm-virtio = { path = "../vm-virtio" } diff --git a/block_util/src/lib.rs b/block_util/src/lib.rs index 269c0eef5..1333574f6 100644 --- a/block_util/src/lib.rs +++ b/block_util/src/lib.rs @@ -34,6 +34,8 @@ use std::os::unix::io::AsRawFd; use std::path::Path; use std::result; use std::sync::{Arc, Mutex}; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use virtio_bindings::bindings::virtio_blk::*; use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap}; use vm_virtio::DescriptorChain; @@ -369,7 +371,7 @@ impl Request { } } -#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize)] +#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, Versionize)] #[repr(C, packed)] pub struct VirtioBlockConfig { pub capacity: u64, @@ -394,7 +396,7 @@ pub struct VirtioBlockConfig { } unsafe impl ByteValued for VirtioBlockConfig {} -#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)] +#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, Versionize)] #[repr(C, packed)] pub struct VirtioBlockGeometry { pub cylinders: u16, diff --git a/virtio-devices/Cargo.toml b/virtio-devices/Cargo.toml index 09c7fa44f..78ae2735c 100644 --- a/virtio-devices/Cargo.toml +++ b/virtio-devices/Cargo.toml @@ -26,6 +26,8 @@ seccomp = { git = "https://github.com/firecracker-microvm/firecracker", tag = "v serde = ">=1.0.27" serde_derive = ">=1.0.27" serde_json = ">=1.0.9" +versionize = "0.1.6" +versionize_derive = "0.1.4" vhost = { git = "https://github.com/rust-vmm/vhost", branch = "master", package = "vhost", features = ["vhost-user-master", "vhost-user-slave"] } virtio-bindings = { version = "0.1", features = ["virtio-v5_0_0"]} vm-allocator = { path = "../vm-allocator" } diff --git a/virtio-devices/src/block.rs b/virtio-devices/src/block.rs index 2f825aba5..e0d542da1 100644 --- a/virtio-devices/src/block.rs +++ b/virtio-devices/src/block.rs @@ -31,8 +31,11 @@ use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::sync::{Arc, Barrier}; use std::thread; use std::{collections::HashMap, convert::TryInto}; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use virtio_bindings::bindings::virtio_blk::*; use vm_memory::{ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap}; +use vm_migration::VersionMapped; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vmm_sys_util::eventfd::EventFd; @@ -363,7 +366,7 @@ pub struct Block { rate_limiter_config: Option, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Versionize)] pub struct BlockState { pub disk_path: String, pub disk_nsectors: u64, @@ -372,6 +375,8 @@ pub struct BlockState { pub config: VirtioBlockConfig, } +impl VersionMapped for BlockState {} + impl Block { /// Create a new virtio block device that operates on the given file. #[allow(clippy::too_many_arguments)] @@ -674,11 +679,11 @@ impl Snapshottable for Block { } fn snapshot(&mut self) -> std::result::Result { - Snapshot::new_from_state(&self.id(), &self.state()) + Snapshot::new_from_versioned_state(&self.id(), &self.state()) } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - self.set_state(&snapshot.to_state(&self.id)?); + self.set_state(&snapshot.to_versioned_state(&self.id)?); Ok(()) } } diff --git a/virtio-devices/src/console.rs b/virtio-devices/src/console.rs index a863cf63e..b6dab89dd 100644 --- a/virtio-devices/src/console.rs +++ b/virtio-devices/src/console.rs @@ -21,7 +21,10 @@ use std::result; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use std::sync::{Arc, Barrier, Mutex}; use std::thread; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use vm_memory::{ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap}; +use vm_migration::VersionMapped; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vmm_sys_util::eventfd::EventFd; @@ -40,7 +43,7 @@ const CONFIG_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 4; //Console size feature bit const VIRTIO_CONSOLE_F_SIZE: u64 = 0; -#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize)] +#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, Versionize)] #[repr(C, packed)] pub struct VirtioConsoleConfig { cols: u16, @@ -277,7 +280,7 @@ pub struct Console { seccomp_action: SeccompAction, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Versionize)] pub struct ConsoleState { avail_features: u64, acked_features: u64, @@ -285,6 +288,8 @@ pub struct ConsoleState { in_buffer: Vec, } +impl VersionMapped for ConsoleState {} + impl Console { /// Create a new virtio console device that gets random data from /dev/urandom. pub fn new( @@ -483,11 +488,11 @@ impl Snapshottable for Console { } fn snapshot(&mut self) -> std::result::Result { - Snapshot::new_from_state(&self.id, &self.state()) + Snapshot::new_from_versioned_state(&self.id, &self.state()) } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - self.set_state(&snapshot.to_state(&self.id)?); + self.set_state(&snapshot.to_versioned_state(&self.id)?); Ok(()) } } diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index 815f22d5f..ff1499f13 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -21,11 +21,14 @@ use std::result; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier, RwLock}; use std::thread; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use vm_device::dma_mapping::ExternalDmaMapping; use vm_memory::{ Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryError, GuestMemoryMmap, }; +use vm_migration::VersionMapped; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vmm_sys_util::eventfd::EventFd; @@ -690,7 +693,7 @@ impl EpollHelperHandler for IommuEpollHandler { } } -#[derive(Clone, Copy, Serialize, Deserialize)] +#[derive(Clone, Copy, Serialize, Deserialize, Versionize)] struct Mapping { gpa: u64, size: u64, @@ -738,7 +741,7 @@ pub struct Iommu { seccomp_action: SeccompAction, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Versionize)] struct IommuState { avail_features: u64, acked_features: u64, @@ -746,6 +749,8 @@ struct IommuState { mappings: Vec<(u32, Vec<(u64, Mapping)>)>, } +impl VersionMapped for IommuState {} + impl Iommu { pub fn new(id: String, seccomp_action: SeccompAction) -> io::Result<(Self, Arc)> { let config = VirtioIommuConfig { @@ -989,11 +994,11 @@ impl Snapshottable for Iommu { } fn snapshot(&mut self) -> std::result::Result { - Snapshot::new_from_state(&self.id, &self.state()) + Snapshot::new_from_versioned_state(&self.id, &self.state()) } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - self.set_state(&snapshot.to_state(&self.id)?); + self.set_state(&snapshot.to_versioned_state(&self.id)?); Ok(()) } } diff --git a/virtio-devices/src/mem.rs b/virtio-devices/src/mem.rs index 4d90d27f9..d7b8794cc 100644 --- a/virtio-devices/src/mem.rs +++ b/virtio-devices/src/mem.rs @@ -18,7 +18,6 @@ use super::{ EpollHelperHandler, Queue, VirtioCommon, VirtioDevice, VirtioDeviceType, EPOLL_HELPER_EVENT_LAST, VIRTIO_F_VERSION_1, }; - use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::{VirtioInterrupt, VirtioInterruptType}; use anyhow::anyhow; diff --git a/virtio-devices/src/net.rs b/virtio-devices/src/net.rs index 165459aed..72e78ee40 100644 --- a/virtio-devices/src/net.rs +++ b/virtio-devices/src/net.rs @@ -30,9 +30,12 @@ use std::sync::{Arc, Barrier}; use std::thread; use std::vec::Vec; use std::{collections::HashMap, convert::TryInto}; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use virtio_bindings::bindings::virtio_net::*; use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX; use vm_memory::{ByteValued, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap}; +use vm_migration::VersionMapped; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vmm_sys_util::eventfd::EventFd; @@ -293,7 +296,7 @@ pub struct Net { rate_limiter_config: Option, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Versionize)] pub struct NetState { pub avail_features: u64, pub acked_features: u64, @@ -301,6 +304,8 @@ pub struct NetState { pub queue_size: Vec, } +impl VersionMapped for NetState {} + impl Net { /// Create a new virtio network device with the given TAP interface. #[allow(clippy::too_many_arguments)] @@ -698,11 +703,11 @@ impl Snapshottable for Net { } fn snapshot(&mut self) -> std::result::Result { - Snapshot::new_from_state(&self.id, &self.state()) + Snapshot::new_from_versioned_state(&self.id, &self.state()) } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - self.set_state(&snapshot.to_state(&self.id)?); + self.set_state(&snapshot.to_versioned_state(&self.id)?); Ok(()) } } diff --git a/virtio-devices/src/net_util.rs b/virtio-devices/src/net_util.rs index 3e86dd488..11b98d9b0 100644 --- a/virtio-devices/src/net_util.rs +++ b/virtio-devices/src/net_util.rs @@ -9,6 +9,8 @@ use std::os::raw::c_uint; use std::os::unix::io::AsRawFd; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier}; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use virtio_bindings::bindings::virtio_net::*; use vm_memory::{ ByteValued, Bytes, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryError, GuestMemoryMmap, @@ -23,7 +25,7 @@ const QUEUE_SIZE: usize = 256; const CTRL_QUEUE_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 1; #[repr(C, packed)] -#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize)] +#[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, Versionize)] pub struct VirtioNetConfig { pub mac: [u8; 6], pub status: u16, diff --git a/virtio-devices/src/pmem.rs b/virtio-devices/src/pmem.rs index a83c5685c..89eea4ea9 100644 --- a/virtio-devices/src/pmem.rs +++ b/virtio-devices/src/pmem.rs @@ -24,10 +24,13 @@ use std::result; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier}; use std::thread; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use vm_memory::{ Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryError, GuestMemoryMmap, MmapRegion, }; +use vm_migration::VersionMapped; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vmm_sys_util::eventfd::EventFd; @@ -41,7 +44,7 @@ const VIRTIO_PMEM_RESP_TYPE_EIO: u32 = 1; // New descriptors are pending on the virtio queue. const QUEUE_AVAIL_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 1; -#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)] +#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, Versionize)] #[repr(C)] struct VirtioPmemConfig { start: u64, @@ -266,13 +269,15 @@ pub struct Pmem { _region: MmapRegion, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Versionize)] pub struct PmemState { avail_features: u64, acked_features: u64, config: VirtioPmemConfig, } +impl VersionMapped for PmemState {} + impl Pmem { pub fn new( id: String, @@ -457,11 +462,11 @@ impl Snapshottable for Pmem { } fn snapshot(&mut self) -> std::result::Result { - Snapshot::new_from_state(&self.id, &self.state()) + Snapshot::new_from_versioned_state(&self.id, &self.state()) } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - self.set_state(&snapshot.to_state(&self.id)?); + self.set_state(&snapshot.to_versioned_state(&self.id)?); Ok(()) } } diff --git a/virtio-devices/src/rng.rs b/virtio-devices/src/rng.rs index 732be33c9..bf15bc682 100644 --- a/virtio-devices/src/rng.rs +++ b/virtio-devices/src/rng.rs @@ -18,7 +18,10 @@ use std::result; use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier}; use std::thread; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap}; +use vm_migration::VersionMapped; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vmm_sys_util::eventfd::EventFd; @@ -127,12 +130,14 @@ pub struct Rng { seccomp_action: SeccompAction, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Versionize)] pub struct RngState { pub avail_features: u64, pub acked_features: u64, } +impl VersionMapped for RngState {} + impl Rng { /// Create a new virtio rng device that gets random data from /dev/urandom. pub fn new( @@ -299,11 +304,11 @@ impl Snapshottable for Rng { } fn snapshot(&mut self) -> std::result::Result { - Snapshot::new_from_state(&self.id, &self.state()) + Snapshot::new_from_versioned_state(&self.id, &self.state()) } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - self.set_state(&snapshot.to_state(&self.id)?); + self.set_state(&snapshot.to_versioned_state(&self.id)?); Ok(()) } } diff --git a/virtio-devices/src/watchdog.rs b/virtio-devices/src/watchdog.rs index d70499712..ed12fae42 100644 --- a/virtio-devices/src/watchdog.rs +++ b/virtio-devices/src/watchdog.rs @@ -22,7 +22,10 @@ use std::sync::atomic::AtomicBool; use std::sync::{Arc, Barrier, Mutex}; use std::thread; use std::time::Instant; +use versionize::{VersionMap, Versionize, VersionizeResult}; +use versionize_derive::Versionize; use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap}; +use vm_migration::VersionMapped; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vmm_sys_util::eventfd::EventFd; @@ -164,13 +167,15 @@ pub struct Watchdog { timer: File, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Versionize)] pub struct WatchdogState { pub avail_features: u64, pub acked_features: u64, pub enabled: bool, } +impl VersionMapped for WatchdogState {} + impl Watchdog { /// Create a new virtio watchdog device that will reboot VM if the guest hangs pub fn new( @@ -392,11 +397,11 @@ impl Snapshottable for Watchdog { } fn snapshot(&mut self) -> std::result::Result { - Snapshot::new_from_state(&self.id, &self.state()) + Snapshot::new_from_versioned_state(&self.id, &self.state()) } fn restore(&mut self, snapshot: Snapshot) -> std::result::Result<(), MigratableError> { - self.set_state(&snapshot.to_state(&self.id)?); + self.set_state(&snapshot.to_versioned_state(&self.id)?); Ok(()) } }