Skip to content

Commit 0a4aa46

Browse files
committed
feat(virtio-mem): implement snapshot/restore
Implements basic snapshot/restore functionality for the dummy virtio-mem device. Signed-off-by: Riccardo Mancini <[email protected]>
1 parent 2970100 commit 0a4aa46

File tree

6 files changed

+276
-6
lines changed

6 files changed

+276
-6
lines changed

src/vmm/src/device_manager/pci_mngr.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use crate::devices::virtio::block::device::Block;
1818
use crate::devices::virtio::block::persist::{BlockConstructorArgs, BlockState};
1919
use crate::devices::virtio::device::VirtioDevice;
2020
use crate::devices::virtio::generated::virtio_ids;
21+
use crate::devices::virtio::mem::VirtioMem;
22+
use crate::devices::virtio::mem::persist::{VirtioMemConstructorArgs, VirtioMemState};
2123
use crate::devices::virtio::net::Net;
2224
use crate::devices::virtio::net::persist::{NetConstructorArgs, NetState};
2325
use crate::devices::virtio::rng::Entropy;
@@ -238,6 +240,8 @@ pub struct PciDevicesState {
238240
pub mmds: Option<MmdsState>,
239241
/// Entropy device state.
240242
pub entropy_device: Option<VirtioDeviceState<EntropyState>>,
243+
/// Memory device state.
244+
pub memory_device: Option<VirtioDeviceState<VirtioMemState>>,
241245
}
242246

243247
pub struct PciDevicesConstructorArgs<'a> {
@@ -384,6 +388,20 @@ impl<'a> Persist<'a> for PciDevices {
384388
transport_state,
385389
})
386390
}
391+
virtio_ids::VIRTIO_ID_MEM => {
392+
let mem_dev = locked_virtio_dev
393+
.as_mut_any()
394+
.downcast_mut::<VirtioMem>()
395+
.unwrap();
396+
let device_state = mem_dev.save();
397+
398+
state.memory_device = Some(VirtioDeviceState {
399+
device_id: mem_dev.id().to_string(),
400+
pci_device_bdf,
401+
device_state,
402+
transport_state,
403+
})
404+
}
387405
_ => unreachable!(),
388406
}
389407
}
@@ -559,6 +577,29 @@ impl<'a> Persist<'a> for PciDevices {
559577
.unwrap()
560578
}
561579

580+
if let Some(memory_device) = &state.memory_device {
581+
let ctor_args = VirtioMemConstructorArgs::new(Arc::clone(constructor_args.vm));
582+
583+
let device = Arc::new(Mutex::new(
584+
VirtioMem::restore(ctor_args, &memory_device.device_state).unwrap(),
585+
));
586+
587+
constructor_args
588+
.vm_resources
589+
.update_from_restored_device(SharedDeviceType::VirtioMem(device.clone()))
590+
.unwrap();
591+
592+
pci_devices
593+
.restore_pci_device(
594+
constructor_args.vm,
595+
device,
596+
&memory_device.device_id,
597+
&memory_device.transport_state,
598+
constructor_args.event_manager,
599+
)
600+
.unwrap()
601+
}
602+
562603
Ok(pci_devices)
563604
}
564605
}
@@ -576,6 +617,7 @@ mod tests {
576617
use crate::snapshot::Snapshot;
577618
use crate::vmm_config::balloon::BalloonDeviceConfig;
578619
use crate::vmm_config::entropy::EntropyDeviceConfig;
620+
use crate::vmm_config::memory_hotplug::MemoryHotplugConfig;
579621
use crate::vmm_config::net::NetworkInterfaceConfig;
580622
use crate::vmm_config::vsock::VsockDeviceConfig;
581623

@@ -638,6 +680,18 @@ mod tests {
638680
let entropy_config = EntropyDeviceConfig::default();
639681
insert_entropy_device(&mut vmm, &mut cmdline, &mut event_manager, entropy_config);
640682

683+
let memory_hotplug_config = MemoryHotplugConfig {
684+
total_size_mib: 1024,
685+
block_size_mib: 2,
686+
slot_size_mib: 128,
687+
};
688+
insert_virtio_mem_device(
689+
&mut vmm,
690+
&mut cmdline,
691+
&mut event_manager,
692+
memory_hotplug_config,
693+
);
694+
641695
Snapshot::new(vmm.device_manager.save())
642696
.save(&mut buf.as_mut_slice())
643697
.unwrap();
@@ -666,7 +720,6 @@ mod tests {
666720
let _restored_dev_manager =
667721
PciDevices::restore(restore_args, &device_manager_state.pci_state).unwrap();
668722

669-
// TODO(virtio-mem): add memory-hotplug device when snapshot-restore is implemented
670723
let expected_vm_resources = format!(
671724
r#"{{
672725
"balloon": {{
@@ -726,7 +779,11 @@ mod tests {
726779
"entropy": {{
727780
"rate_limiter": null
728781
}},
729-
"memory-hotplug": null
782+
"memory-hotplug": {{
783+
"total_size_mib": 1024,
784+
"block_size_mib": 2,
785+
"slot_size_mib": 128
786+
}}
730787
}}"#,
731788
_block_files.last().unwrap().as_path().to_str().unwrap(),
732789
tmp_sock_file.as_path().to_str().unwrap()

src/vmm/src/device_manager/persist.rs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ use crate::devices::virtio::block::device::Block;
2525
use crate::devices::virtio::block::persist::{BlockConstructorArgs, BlockState};
2626
use crate::devices::virtio::device::VirtioDevice;
2727
use crate::devices::virtio::generated::virtio_ids;
28+
use crate::devices::virtio::mem::VirtioMem;
29+
use crate::devices::virtio::mem::persist::{
30+
VirtioMemConstructorArgs, VirtioMemPersistError, VirtioMemState,
31+
};
2832
use crate::devices::virtio::net::Net;
2933
use crate::devices::virtio::net::persist::{
3034
NetConstructorArgs, NetPersistError as NetError, NetState,
@@ -73,6 +77,8 @@ pub enum DevicePersistError {
7377
MmdsConfig(#[from] MmdsConfigError),
7478
/// Entropy: {0}
7579
Entropy(#[from] EntropyError),
80+
/// virtio-mem: {0}
81+
VirtioMem(#[from] VirtioMemPersistError),
7682
/// Resource misconfiguration: {0}. Is the snapshot file corrupted?
7783
ResourcesError(#[from] ResourcesError),
7884
/// Could not activate device: {0}
@@ -126,6 +132,8 @@ pub struct DeviceStates {
126132
pub mmds: Option<MmdsState>,
127133
/// Entropy device state.
128134
pub entropy_device: Option<VirtioDeviceState<EntropyState>>,
135+
/// Memory device state.
136+
pub memory_device: Option<VirtioDeviceState<VirtioMemState>>,
129137
}
130138

131139
/// A type used to extract the concrete `Arc<Mutex<T>>` for each of the device
@@ -137,6 +145,7 @@ pub enum SharedDeviceType {
137145
Balloon(Arc<Mutex<Balloon>>),
138146
Vsock(Arc<Mutex<Vsock<VsockUnixBackend>>>),
139147
Entropy(Arc<Mutex<Entropy>>),
148+
VirtioMem(Arc<Mutex<VirtioMem>>),
140149
}
141150

142151
pub struct MMIODevManagerConstructorArgs<'a> {
@@ -335,6 +344,20 @@ impl<'a> Persist<'a> for MMIODeviceManager {
335344
device_info,
336345
});
337346
}
347+
virtio_ids::VIRTIO_ID_MEM => {
348+
let mem = locked_device
349+
.as_mut_any()
350+
.downcast_mut::<VirtioMem>()
351+
.unwrap();
352+
let device_state = mem.save();
353+
354+
states.memory_device = Some(VirtioDeviceState {
355+
device_id,
356+
device_state,
357+
transport_state,
358+
device_info,
359+
});
360+
}
338361
_ => unreachable!(),
339362
};
340363

@@ -546,6 +569,30 @@ impl<'a> Persist<'a> for MMIODeviceManager {
546569
)?;
547570
}
548571

572+
if let Some(memory_state) = &state.memory_device {
573+
let ctor_args = VirtioMemConstructorArgs::new(Arc::clone(vm));
574+
575+
let device = Arc::new(Mutex::new(VirtioMem::restore(
576+
ctor_args,
577+
&memory_state.device_state,
578+
)?));
579+
580+
constructor_args
581+
.vm_resources
582+
.update_from_restored_device(SharedDeviceType::VirtioMem(device.clone()))?;
583+
584+
restore_helper(
585+
device.clone(),
586+
memory_state.device_state.virtio_state.activated,
587+
false,
588+
device,
589+
&memory_state.device_id,
590+
&memory_state.transport_state,
591+
&memory_state.device_info,
592+
constructor_args.event_manager,
593+
)?;
594+
}
595+
549596
Ok(dev_manager)
550597
}
551598
}
@@ -562,6 +609,7 @@ mod tests {
562609
use crate::snapshot::Snapshot;
563610
use crate::vmm_config::balloon::BalloonDeviceConfig;
564611
use crate::vmm_config::entropy::EntropyDeviceConfig;
612+
use crate::vmm_config::memory_hotplug::MemoryHotplugConfig;
565613
use crate::vmm_config::net::NetworkInterfaceConfig;
566614
use crate::vmm_config::vsock::VsockDeviceConfig;
567615

@@ -579,6 +627,7 @@ mod tests {
579627
&& self.net_devices == other.net_devices
580628
&& self.vsock_device == other.vsock_device
581629
&& self.entropy_device == other.entropy_device
630+
&& self.memory_device == other.memory_device
582631
}
583632
}
584633

@@ -663,6 +712,18 @@ mod tests {
663712
let entropy_config = EntropyDeviceConfig::default();
664713
insert_entropy_device(&mut vmm, &mut cmdline, &mut event_manager, entropy_config);
665714

715+
let memory_hotplug_config = MemoryHotplugConfig {
716+
total_size_mib: 1024,
717+
block_size_mib: 2,
718+
slot_size_mib: 128,
719+
};
720+
insert_virtio_mem_device(
721+
&mut vmm,
722+
&mut cmdline,
723+
&mut event_manager,
724+
memory_hotplug_config,
725+
);
726+
666727
Snapshot::new(vmm.device_manager.save())
667728
.save(&mut buf.as_mut_slice())
668729
.unwrap();
@@ -687,7 +748,6 @@ mod tests {
687748
let _restored_dev_manager =
688749
MMIODeviceManager::restore(restore_args, &device_manager_state.mmio_state).unwrap();
689750

690-
// TODO(virtio-mem): add memory-hotplug device when snapshot-restore is implemented
691751
let expected_vm_resources = format!(
692752
r#"{{
693753
"balloon": {{
@@ -747,7 +807,11 @@ mod tests {
747807
"entropy": {{
748808
"rate_limiter": null
749809
}},
750-
"memory-hotplug": null
810+
"memory-hotplug": {{
811+
"total_size_mib": 1024,
812+
"block_size_mib": 2,
813+
"slot_size_mib": 128
814+
}}
751815
}}"#,
752816
_block_files.last().unwrap().as_path().to_str().unwrap(),
753817
tmp_sock_file.as_path().to_str().unwrap()

src/vmm/src/devices/virtio/mem/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
mod device;
55
mod event_handler;
6+
pub mod persist;
67

78
use vm_memory::GuestAddress;
89

0 commit comments

Comments
 (0)