diff --git a/vmm/src/api/mod.rs b/vmm/src/api/mod.rs index a62e9dca2..f273da8b0 100644 --- a/vmm/src/api/mod.rs +++ b/vmm/src/api/mod.rs @@ -54,7 +54,9 @@ use vmm_sys_util::eventfd::EventFd; pub use self::dbus::start_dbus_thread; pub use self::http::{start_http_fd_thread, start_http_path_thread}; use crate::Error as VmmError; -use crate::config::{RestoreConfig, RestoredVfioConfig, deserialize_restored_fd}; +use crate::config::{ + RestoreConfig, RestoredVfioConfig, VmMemoryZoneUpdateData, deserialize_restored_fd, +}; use crate::device_tree::DeviceTree; use crate::migration::transport::{ MAX_MIGRATION_CONNECTIONS, TcpAddressParseError, tcp_address_to_server_name, @@ -319,6 +321,9 @@ pub struct VmReceiveMigrationData { // FDs are not serialized and any deserialized value is invalid; see NetConfig::fds. #[serde(default, deserialize_with = "deserialize_restored_fd")] pub iommufd_fd: Option, + /// Optional memory zone update data + #[serde(default)] + pub zone_updates: Vec, } #[derive(Debug, Error)] @@ -381,6 +386,7 @@ impl VmReceiveMigrationData { memory_mode, vfio_fds, iommufd_fd, + zone_updates: vec![], }; data.validate()?; @@ -2089,6 +2095,7 @@ mod unit_tests { memory_mode: MigrationMode::Precopy, vfio_fds: None, iommufd_fd: None, + zone_updates: vec![], } ); @@ -2118,6 +2125,7 @@ mod unit_tests { memory_mode: MigrationMode::Precopy, vfio_fds: None, iommufd_fd: None, + zone_updates: vec![], } ); @@ -2143,6 +2151,7 @@ mod unit_tests { memory_mode: MigrationMode::Precopy, vfio_fds: None, iommufd_fd: None, + ..Default::default() } ); @@ -2158,6 +2167,7 @@ mod unit_tests { memory_mode: MigrationMode::Postcopy, vfio_fds: None, iommufd_fd: None, + ..Default::default() } ); diff --git a/vmm/src/config.rs b/vmm/src/config.rs index bc6d1ef7e..aec8b77d4 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -2808,6 +2808,15 @@ impl FromStr for MemoryRestoreMode { } } +#[derive(Clone, Deserialize, Serialize, Debug, Eq, PartialEq)] +/// Data required for updating memory zone <-> host NUMA node mappings. +pub struct VmMemoryZoneUpdateData { + /// Id of the MemoryZone to update + pub id: String, + /// Host NUMA node to relocate the MemoryZone to + pub host_numa_node: u32, +} + #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)] pub struct RestoredVfioConfig { pub id: String, @@ -2844,6 +2853,8 @@ pub struct RestoreConfig { pub iommufd_fd: Option, #[serde(default)] pub resume: bool, + #[serde(default)] + pub zone_updates: Vec, } impl RestoreConfig { @@ -2928,6 +2939,7 @@ impl RestoreConfig { vfio_fds, iommufd_fd, resume, + zone_updates: vec![], }) } @@ -5196,6 +5208,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" vfio_fds: None, iommufd_fd: None, resume: false, + zone_updates: vec![], } ); assert_eq!( @@ -5221,6 +5234,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" vfio_fds: None, iommufd_fd: None, resume: false, + zone_updates: vec![], } ); assert_eq!( @@ -5233,6 +5247,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" vfio_fds: None, iommufd_fd: None, resume: false, + zone_updates: vec![], } ); assert_eq!( @@ -5245,6 +5260,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" vfio_fds: None, iommufd_fd: None, resume: true, + zone_updates: vec![], } ); assert_eq!( @@ -5268,6 +5284,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" ]), iommufd_fd: Some(7), resume: false, + zone_updates: vec![], } ); // Parsing should fail as source_url is a required field @@ -5382,6 +5399,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" vfio_fds: None, iommufd_fd: None, resume: false, + zone_updates: vec![], }; valid_config.validate(&snapshot_vm_config).unwrap(); @@ -5449,6 +5467,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" vfio_fds: None, iommufd_fd: None, resume: false, + zone_updates: vec![], }; snapshot_vm_config.net = Some(vec![NetConfig { pci_common: PciDeviceCommonConfig { @@ -5468,6 +5487,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" vfio_fds: None, iommufd_fd: None, resume: false, + zone_updates: vec![], }; assert_eq!( invalid_restore_mode.validate(&snapshot_vm_config), @@ -5541,6 +5561,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}" }]), iommufd_fd: Some(6), resume: false, + zone_updates: vec![], }; valid_config.validate(&snapshot_vm_config).unwrap(); diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index c1004395e..bcbf49bcf 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -3082,9 +3082,10 @@ impl RequestHandler for Vmm { .map_err(MigratableError::MigrateReceive)?; info!( - "Receiving migration: receiver_url={},tls={}", + "Receiving migration: receiver_url={},tls={},zone_updates={:?}", receive_data_migration.receiver_url, - receive_data_migration.tls_dir.is_some() + receive_data_migration.tls_dir.is_some(), + receive_data_migration.zone_updates, ); let mut listener = transport::receive_migration_listener( @@ -3927,6 +3928,7 @@ mod unit_tests { memory_mode: MigrationMode::default(), vfio_fds, iommufd_fd, + zone_updates: vec![], } }