@@ -30,6 +30,10 @@ use crate::devices::virtio::net::persist::{
30
30
NetConstructorArgs , NetPersistError as NetError , NetState ,
31
31
} ;
32
32
use crate :: devices:: virtio:: persist:: { MmioTransportConstructorArgs , MmioTransportState } ;
33
+ use crate :: devices:: virtio:: pmem:: device:: Pmem ;
34
+ use crate :: devices:: virtio:: pmem:: persist:: {
35
+ PmemConstructorArgs , PmemPersistError as PmemError , PmemState ,
36
+ } ;
33
37
use crate :: devices:: virtio:: rng:: Entropy ;
34
38
use crate :: devices:: virtio:: rng:: persist:: {
35
39
EntropyConstructorArgs , EntropyPersistError as EntropyError , EntropyState ,
@@ -73,6 +77,8 @@ pub enum DevicePersistError {
73
77
MmdsConfig ( #[ from] MmdsConfigError ) ,
74
78
/// Entropy: {0}
75
79
Entropy ( #[ from] EntropyError ) ,
80
+ /// Pmem: {0}
81
+ Pmem ( #[ from] PmemError ) ,
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
+ /// Pmem device states.
136
+ pub pmem_devices : Vec < VirtioDeviceState < PmemState > > ,
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
+ Pmem ( Arc < Mutex < Pmem > > ) ,
140
149
}
141
150
142
151
pub struct MMIODevManagerConstructorArgs < ' a > {
@@ -336,6 +345,16 @@ impl<'a> Persist<'a> for MMIODeviceManager {
336
345
device_info,
337
346
} ) ;
338
347
}
348
+ virtio_ids:: VIRTIO_ID_PMEM => {
349
+ let pmem = locked_device. as_mut_any ( ) . downcast_mut :: < Pmem > ( ) . unwrap ( ) ;
350
+ let device_state = pmem. save ( ) ;
351
+ states. pmem_devices . push ( VirtioDeviceState {
352
+ device_id,
353
+ device_state,
354
+ transport_state,
355
+ device_info,
356
+ } )
357
+ }
339
358
_ => unreachable ! ( ) ,
340
359
} ;
341
360
@@ -550,6 +569,31 @@ impl<'a> Persist<'a> for MMIODeviceManager {
550
569
) ?;
551
570
}
552
571
572
+ for pmem_state in & state. pmem_devices {
573
+ let device = Arc :: new ( Mutex :: new ( Pmem :: restore (
574
+ PmemConstructorArgs {
575
+ mem,
576
+ vm : vm. as_ref ( ) ,
577
+ } ,
578
+ & pmem_state. device_state ,
579
+ ) ?) ) ;
580
+
581
+ constructor_args
582
+ . vm_resources
583
+ . update_from_restored_device ( SharedDeviceType :: Pmem ( device. clone ( ) ) ) ?;
584
+
585
+ restore_helper (
586
+ device. clone ( ) ,
587
+ pmem_state. device_state . virtio_state . activated ,
588
+ false ,
589
+ device,
590
+ & pmem_state. device_id ,
591
+ & pmem_state. transport_state ,
592
+ & pmem_state. device_info ,
593
+ constructor_args. event_manager ,
594
+ ) ?;
595
+ }
596
+
553
597
Ok ( dev_manager)
554
598
}
555
599
}
@@ -567,6 +611,7 @@ mod tests {
567
611
use crate :: vmm_config:: balloon:: BalloonDeviceConfig ;
568
612
use crate :: vmm_config:: entropy:: EntropyDeviceConfig ;
569
613
use crate :: vmm_config:: net:: NetworkInterfaceConfig ;
614
+ use crate :: vmm_config:: pmem:: PmemConfig ;
570
615
use crate :: vmm_config:: vsock:: VsockDeviceConfig ;
571
616
572
617
impl < T > PartialEq for VirtioDeviceState < T > {
@@ -614,6 +659,7 @@ mod tests {
614
659
let mut buf = vec ! [ 0 ; 65536 ] ;
615
660
// These need to survive so the restored blocks find them.
616
661
let _block_files;
662
+ let _pmem_files;
617
663
let mut tmp_sock_file = TempFile :: new ( ) . unwrap ( ) ;
618
664
tmp_sock_file. remove ( ) . unwrap ( ) ;
619
665
// Set up a vmm with one of each device, and get the serialized DeviceStates.
@@ -666,6 +712,16 @@ mod tests {
666
712
// Add an entropy device.
667
713
let entropy_config = EntropyDeviceConfig :: default ( ) ;
668
714
insert_entropy_device ( & mut vmm, & mut cmdline, & mut event_manager, entropy_config) ;
715
+ // Add a pmem device.
716
+ let pmem_id = String :: from ( "pmem" ) ;
717
+ let pmem_configs = vec ! [ PmemConfig {
718
+ id: pmem_id,
719
+ path_on_host: "" . into( ) ,
720
+ root_device: true ,
721
+ read_only: true ,
722
+ } ] ;
723
+ _pmem_files =
724
+ insert_pmem_devices ( & mut vmm, & mut cmdline, & mut event_manager, pmem_configs) ;
669
725
670
726
Snapshot :: new ( vmm. device_manager . save ( ) )
671
727
. save ( & mut buf. as_mut_slice ( ) )
@@ -751,10 +807,18 @@ mod tests {
751
807
"entropy": {{
752
808
"rate_limiter": null
753
809
}},
754
- "pmem": []
810
+ "pmem": [
811
+ {{
812
+ "id": "pmem",
813
+ "path_on_host": "{}",
814
+ "root_device": true,
815
+ "read_only": true
816
+ }}
817
+ ]
755
818
}}"# ,
756
819
_block_files. last( ) . unwrap( ) . as_path( ) . to_str( ) . unwrap( ) ,
757
- tmp_sock_file. as_path( ) . to_str( ) . unwrap( )
820
+ tmp_sock_file. as_path( ) . to_str( ) . unwrap( ) ,
821
+ _pmem_files. last( ) . unwrap( ) . as_path( ) . to_str( ) . unwrap( ) ,
758
822
) ;
759
823
760
824
assert_eq ! (
0 commit comments