@@ -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 ,
@@ -72,6 +76,8 @@ pub enum DevicePersistError {
72
76
MmdsConfig ( #[ from] MmdsConfigError ) ,
73
77
/// Entropy: {0}
74
78
Entropy ( #[ from] EntropyError ) ,
79
+ /// virtio-mem: {0}
80
+ VirtioMem ( #[ from] VirtioMemPersistError ) ,
75
81
/// Resource misconfiguration: {0}. Is the snapshot file corrupted?
76
82
ResourcesError ( #[ from] ResourcesError ) ,
77
83
/// Could not activate device: {0}
@@ -125,6 +131,8 @@ pub struct DeviceStates {
125
131
pub mmds : Option < MmdsState > ,
126
132
/// Entropy device state.
127
133
pub entropy_device : Option < VirtioDeviceState < EntropyState > > ,
134
+ /// Memory device state.
135
+ pub memory_device : Option < VirtioDeviceState < VirtioMemState > > ,
128
136
}
129
137
130
138
/// A type used to extract the concrete `Arc<Mutex<T>>` for each of the device
@@ -136,6 +144,7 @@ pub enum SharedDeviceType {
136
144
Balloon ( Arc < Mutex < Balloon > > ) ,
137
145
Vsock ( Arc < Mutex < Vsock < VsockUnixBackend > > > ) ,
138
146
Entropy ( Arc < Mutex < Entropy > > ) ,
147
+ VirtioMem ( Arc < Mutex < VirtioMem > > ) ,
139
148
}
140
149
141
150
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
@@ -549,6 +572,30 @@ impl<'a> Persist<'a> for MMIODeviceManager {
549
572
) ?;
550
573
}
551
574
575
+ if let Some ( memory_state) = & state. memory_device {
576
+ let ctor_args = VirtioMemConstructorArgs :: new ( Arc :: clone ( vm) ) ;
577
+
578
+ let device = Arc :: new ( Mutex :: new ( VirtioMem :: restore (
579
+ ctor_args,
580
+ & memory_state. device_state ,
581
+ ) ?) ) ;
582
+
583
+ constructor_args
584
+ . vm_resources
585
+ . update_from_restored_device ( SharedDeviceType :: VirtioMem ( device. clone ( ) ) ) ?;
586
+
587
+ restore_helper (
588
+ device. clone ( ) ,
589
+ memory_state. device_state . virtio_state . activated ,
590
+ false ,
591
+ device,
592
+ & memory_state. device_id ,
593
+ & memory_state. transport_state ,
594
+ & memory_state. device_info ,
595
+ constructor_args. event_manager ,
596
+ ) ?;
597
+ }
598
+
552
599
Ok ( dev_manager)
553
600
}
554
601
}
@@ -565,6 +612,7 @@ mod tests {
565
612
use crate :: snapshot:: Snapshot ;
566
613
use crate :: vmm_config:: balloon:: BalloonDeviceConfig ;
567
614
use crate :: vmm_config:: entropy:: EntropyDeviceConfig ;
615
+ use crate :: vmm_config:: memory_hotplug:: MemoryHotplugConfig ;
568
616
use crate :: vmm_config:: net:: NetworkInterfaceConfig ;
569
617
use crate :: vmm_config:: vsock:: VsockDeviceConfig ;
570
618
@@ -582,6 +630,7 @@ mod tests {
582
630
&& self . net_devices == other. net_devices
583
631
&& self . vsock_device == other. vsock_device
584
632
&& self . entropy_device == other. entropy_device
633
+ && self . memory_device == other. memory_device
585
634
}
586
635
}
587
636
@@ -666,6 +715,18 @@ mod tests {
666
715
let entropy_config = EntropyDeviceConfig :: default ( ) ;
667
716
insert_entropy_device ( & mut vmm, & mut cmdline, & mut event_manager, entropy_config) ;
668
717
718
+ let memory_hotplug_config = MemoryHotplugConfig {
719
+ total_size_mib : 1024 ,
720
+ block_size_mib : 2 ,
721
+ slot_size_mib : 128 ,
722
+ } ;
723
+ insert_virtio_mem_device (
724
+ & mut vmm,
725
+ & mut cmdline,
726
+ & mut event_manager,
727
+ memory_hotplug_config,
728
+ ) ;
729
+
669
730
Snapshot :: new ( vmm. device_manager . save ( ) )
670
731
. save ( & mut buf. as_mut_slice ( ) )
671
732
. unwrap ( ) ;
@@ -691,7 +752,6 @@ mod tests {
691
752
let _restored_dev_manager =
692
753
MMIODeviceManager :: restore ( restore_args, & device_manager_state. mmio_state ) . unwrap ( ) ;
693
754
694
- // TODO(virtio-mem): add memory-hotplug device when snapshot-restore is implemented
695
755
let expected_vm_resources = format ! (
696
756
r#"{{
697
757
"balloon": {{
@@ -751,7 +811,11 @@ mod tests {
751
811
"entropy": {{
752
812
"rate_limiter": null
753
813
}},
754
- "memory-hotplug": null
814
+ "memory-hotplug": {{
815
+ "total_size_mib": 1024,
816
+ "block_size_mib": 2,
817
+ "slot_size_mib": 128
818
+ }}
755
819
}}"# ,
756
820
_block_files. last( ) . unwrap( ) . as_path( ) . to_str( ) . unwrap( ) ,
757
821
tmp_sock_file. as_path( ) . to_str( ) . unwrap( )
0 commit comments