@@ -28,6 +28,7 @@ use crate::vmm_config::machine_config::{
2828use crate :: vmm_config:: metrics:: { MetricsConfig , MetricsConfigError , init_metrics} ;
2929use crate :: vmm_config:: mmds:: { MmdsConfig , MmdsConfigError } ;
3030use crate :: vmm_config:: net:: * ;
31+ use crate :: vmm_config:: pmem:: { PmemBuilder , PmemConfig , PmemConfigError } ;
3132use crate :: vmm_config:: serial:: SerialConfig ;
3233use crate :: vmm_config:: vsock:: * ;
3334use crate :: vstate:: memory;
@@ -62,6 +63,8 @@ pub enum ResourcesError {
6263 VsockDevice ( #[ from] VsockConfigError ) ,
6364 /// Entropy device error: {0}
6465 EntropyDevice ( #[ from] EntropyDeviceError ) ,
66+ /// Pmem device error: {0}
67+ PmemDevice ( #[ from] PmemConfigError ) ,
6568}
6669
6770#[ derive( Serialize , Deserialize , PartialEq , Eq , Debug ) ]
@@ -87,6 +90,8 @@ pub struct VmmConfig {
8790 network_interfaces : Vec < NetworkInterfaceConfig > ,
8891 vsock : Option < VsockDeviceConfig > ,
8992 entropy : Option < EntropyDeviceConfig > ,
93+ #[ serde( default , rename = "pmem" ) ]
94+ pmem_devices : Vec < PmemConfig > ,
9095 #[ serde( skip) ]
9196 serial_config : Option < SerialConfig > ,
9297}
@@ -109,6 +114,8 @@ pub struct VmResources {
109114 pub net_builder : NetBuilder ,
110115 /// The entropy device builder.
111116 pub entropy : EntropyDeviceBuilder ,
117+ /// The pmem devices.
118+ pub pmem : PmemBuilder ,
112119 /// The optional Mmds data store.
113120 // This is initialised on demand (if ever used), so that we don't allocate it unless it's
114121 // actually used.
@@ -198,6 +205,10 @@ impl VmResources {
198205 resources. build_entropy_device ( entropy_device_config) ?;
199206 }
200207
208+ for pmem_config in vmm_config. pmem_devices . into_iter ( ) {
209+ resources. build_pmem_device ( pmem_config) ?;
210+ }
211+
201212 if let Some ( serial_cfg) = vmm_config. serial_config {
202213 resources. serial_out_path = serial_cfg. serial_out_path ;
203214 }
@@ -389,6 +400,11 @@ impl VmResources {
389400 self . entropy . insert ( body)
390401 }
391402
403+ /// Builds a pmem device to be attached when the VM starts.
404+ pub fn build_pmem_device ( & mut self , body : PmemConfig ) -> Result < ( ) , PmemConfigError > {
405+ self . pmem . build ( body)
406+ }
407+
392408 /// Setter for mmds config.
393409 pub fn set_mmds_config (
394410 & mut self ,
@@ -515,6 +531,7 @@ impl From<&VmResources> for VmmConfig {
515531 network_interfaces : resources. net_builder . configs ( ) ,
516532 vsock : resources. vsock . config ( ) ,
517533 entropy : resources. entropy . config ( ) ,
534+ pmem_devices : resources. pmem . configs ( ) ,
518535 // serial_config is marked serde(skip) so that it doesnt end up in snapshots.
519536 serial_config : None ,
520537 }
@@ -627,6 +644,7 @@ mod tests {
627644 boot_timer : false ,
628645 mmds_size_limit : HTTP_MAX_PAYLOAD_SIZE ,
629646 entropy : Default :: default ( ) ,
647+ pmem : Default :: default ( ) ,
630648 pci_enabled : false ,
631649 serial_out_path : None ,
632650 }
@@ -636,6 +654,8 @@ mod tests {
636654 fn test_from_json ( ) {
637655 let kernel_file = TempFile :: new ( ) . unwrap ( ) ;
638656 let rootfs_file = TempFile :: new ( ) . unwrap ( ) ;
657+ let scratch_file = TempFile :: new ( ) . unwrap ( ) ;
658+ scratch_file. as_file ( ) . set_len ( 0x1000 ) . unwrap ( ) ;
639659 let default_instance_info = InstanceInfo :: default ( ) ;
640660
641661 // We will test different scenarios with invalid resources configuration and
@@ -1010,6 +1030,14 @@ mod tests {
10101030 "is_read_only": false
10111031 }}
10121032 ],
1033+ "pmem": [
1034+ {{
1035+ "id": "pmem",
1036+ "path_on_host": "{}",
1037+ "root_device": false,
1038+ "read_only": false
1039+ }}
1040+ ],
10131041 "network-interfaces": [
10141042 {{
10151043 "iface_id": "netif",
@@ -1028,6 +1056,7 @@ mod tests {
10281056 }}"# ,
10291057 kernel_file. as_path( ) . to_str( ) . unwrap( ) ,
10301058 rootfs_file. as_path( ) . to_str( ) . unwrap( ) ,
1059+ scratch_file. as_path( ) . to_str( ) . unwrap( ) ,
10311060 ) ;
10321061 let resources = VmResources :: from_json (
10331062 json. as_str ( ) ,
@@ -1640,4 +1669,20 @@ mod tests {
16401669 vm_resources. build_net_device ( new_net_device_cfg) . unwrap ( ) ;
16411670 assert_eq ! ( vm_resources. net_builder. len( ) , 2 ) ;
16421671 }
1672+
1673+ #[ test]
1674+ fn test_set_pmem_device ( ) {
1675+ let mut vm_resources = default_vm_resources ( ) ;
1676+
1677+ let tmp_file = TempFile :: new ( ) . unwrap ( ) ;
1678+ tmp_file. as_file ( ) . set_len ( 0x1000 ) . unwrap ( ) ;
1679+ let cfg = PmemConfig {
1680+ id : "pmem" . to_string ( ) ,
1681+ path_on_host : tmp_file. as_path ( ) . to_str ( ) . unwrap ( ) . to_string ( ) ,
1682+ ..Default :: default ( )
1683+ } ;
1684+ assert_eq ! ( vm_resources. pmem. devices. len( ) , 0 ) ;
1685+ vm_resources. build_pmem_device ( cfg) . unwrap ( ) ;
1686+ assert_eq ! ( vm_resources. pmem. devices. len( ) , 1 ) ;
1687+ }
16431688}
0 commit comments