@@ -25,6 +25,10 @@ use crate::devices::virtio::block::device::Block;
25
25
use crate :: devices:: virtio:: block:: persist:: { BlockConstructorArgs , BlockState } ;
26
26
use crate :: devices:: virtio:: device:: VirtioDevice ;
27
27
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
+ } ;
28
32
use crate :: devices:: virtio:: net:: Net ;
29
33
use crate :: devices:: virtio:: net:: persist:: {
30
34
NetConstructorArgs , NetPersistError as NetError , NetState ,
@@ -73,6 +77,8 @@ pub enum DevicePersistError {
73
77
MmdsConfig ( #[ from] MmdsConfigError ) ,
74
78
/// Entropy: {0}
75
79
Entropy ( #[ from] EntropyError ) ,
80
+ /// virtio-mem: {0}
81
+ VirtioMem ( #[ from] VirtioMemPersistError ) ,
76
82
/// Resource misconfiguration: {0}. Is the snapshot file corrupted?
77
83
ResourcesError ( #[ from] ResourcesError ) ,
78
84
/// Could not activate device: {0}
@@ -126,6 +132,8 @@ pub struct DeviceStates {
126
132
pub mmds : Option < MmdsState > ,
127
133
/// Entropy device state.
128
134
pub entropy_device : Option < VirtioDeviceState < EntropyState > > ,
135
+ /// Memory device state.
136
+ pub memory_device : Option < VirtioDeviceState < VirtioMemState > > ,
129
137
}
130
138
131
139
/// A type used to extract the concrete `Arc<Mutex<T>>` for each of the device
@@ -137,6 +145,7 @@ pub enum SharedDeviceType {
137
145
Balloon ( Arc < Mutex < Balloon > > ) ,
138
146
Vsock ( Arc < Mutex < Vsock < VsockUnixBackend > > > ) ,
139
147
Entropy ( Arc < Mutex < Entropy > > ) ,
148
+ VirtioMem ( Arc < Mutex < VirtioMem > > ) ,
140
149
}
141
150
142
151
pub struct MMIODevManagerConstructorArgs < ' a > {
@@ -335,6 +344,20 @@ impl<'a> Persist<'a> for MMIODeviceManager {
335
344
device_info,
336
345
} ) ;
337
346
}
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
+ }
338
361
_ => unreachable ! ( ) ,
339
362
} ;
340
363
@@ -546,6 +569,30 @@ impl<'a> Persist<'a> for MMIODeviceManager {
546
569
) ?;
547
570
}
548
571
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
+
549
596
Ok ( dev_manager)
550
597
}
551
598
}
@@ -562,6 +609,7 @@ mod tests {
562
609
use crate :: snapshot:: Snapshot ;
563
610
use crate :: vmm_config:: balloon:: BalloonDeviceConfig ;
564
611
use crate :: vmm_config:: entropy:: EntropyDeviceConfig ;
612
+ use crate :: vmm_config:: memory_hotplug:: MemoryHotplugConfig ;
565
613
use crate :: vmm_config:: net:: NetworkInterfaceConfig ;
566
614
use crate :: vmm_config:: vsock:: VsockDeviceConfig ;
567
615
@@ -579,6 +627,7 @@ mod tests {
579
627
&& self . net_devices == other. net_devices
580
628
&& self . vsock_device == other. vsock_device
581
629
&& self . entropy_device == other. entropy_device
630
+ && self . memory_device == other. memory_device
582
631
}
583
632
}
584
633
@@ -663,6 +712,18 @@ mod tests {
663
712
let entropy_config = EntropyDeviceConfig :: default ( ) ;
664
713
insert_entropy_device ( & mut vmm, & mut cmdline, & mut event_manager, entropy_config) ;
665
714
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
+
666
727
Snapshot :: new ( vmm. device_manager . save ( ) )
667
728
. save ( & mut buf. as_mut_slice ( ) )
668
729
. unwrap ( ) ;
@@ -687,7 +748,6 @@ mod tests {
687
748
let _restored_dev_manager =
688
749
MMIODeviceManager :: restore ( restore_args, & device_manager_state. mmio_state ) . unwrap ( ) ;
689
750
690
- // TODO(virtio-mem): add memory-hotplug device when snapshot-restore is implemented
691
751
let expected_vm_resources = format ! (
692
752
r#"{{
693
753
"balloon": {{
@@ -747,7 +807,11 @@ mod tests {
747
807
"entropy": {{
748
808
"rate_limiter": null
749
809
}},
750
- "memory-hotplug": null
810
+ "memory-hotplug": {{
811
+ "total_size_mib": 1024,
812
+ "block_size_mib": 2,
813
+ "slot_size_mib": 128
814
+ }}
751
815
}}"# ,
752
816
_block_files. last( ) . unwrap( ) . as_path( ) . to_str( ) . unwrap( ) ,
753
817
tmp_sock_file. as_path( ) . to_str( ) . unwrap( )
0 commit comments