66#[ cfg( target_arch = "x86_64" ) ]
77use std:: convert:: TryFrom ;
88use std:: fmt:: Debug ;
9- use std:: io:: { self , Seek , SeekFrom } ;
9+ use std:: io;
1010#[ cfg( feature = "gdb" ) ]
1111use std:: sync:: mpsc;
1212use std:: sync:: { Arc , Mutex } ;
@@ -23,16 +23,14 @@ use linux_loader::loader::elf::PvhBootCapability;
2323use linux_loader:: loader:: pe:: PE as Loader ;
2424use userfaultfd:: Uffd ;
2525use utils:: time:: TimestampUs ;
26- use vm_memory:: ReadVolatile ;
2726#[ cfg( target_arch = "aarch64" ) ]
2827use vm_superio:: Rtc ;
2928use vm_superio:: Serial ;
3029use vmm_sys_util:: eventfd:: EventFd ;
3130
3231#[ cfg( target_arch = "x86_64" ) ]
3332use crate :: acpi;
34- use crate :: arch:: { BootProtocol , EntryPoint , InitrdConfig } ;
35- use crate :: builder:: StartMicrovmError :: Internal ;
33+ use crate :: arch:: { BootProtocol , EntryPoint } ;
3634#[ cfg( target_arch = "aarch64" ) ]
3735use crate :: construct_kvm_mpidrs;
3836use crate :: cpu_config:: templates:: {
@@ -62,17 +60,17 @@ use crate::devices::virtio::rng::Entropy;
6260use crate :: devices:: virtio:: vsock:: { Vsock , VsockUnixBackend } ;
6361#[ cfg( feature = "gdb" ) ]
6462use crate :: gdb;
63+ use crate :: initrd:: { InitrdConfig , InitrdError } ;
6564use crate :: logger:: { debug, error} ;
6665use crate :: persist:: { MicrovmState , MicrovmStateError } ;
6766use crate :: resources:: VmResources ;
6867use crate :: seccomp:: BpfThreadMap ;
6968use crate :: snapshot:: Persist ;
70- use crate :: utils:: u64_to_usize;
7169use crate :: vmm_config:: boot_source:: BootConfig ;
7270use crate :: vmm_config:: instance_info:: InstanceInfo ;
7371use crate :: vmm_config:: machine_config:: { MachineConfig , MachineConfigError } ;
7472use crate :: vstate:: kvm:: Kvm ;
75- use crate :: vstate:: memory:: { GuestAddress , GuestMemory , GuestMemoryMmap } ;
73+ use crate :: vstate:: memory:: { GuestAddress , GuestMemoryMmap } ;
7674use crate :: vstate:: vcpu:: { Vcpu , VcpuConfig , VcpuError } ;
7775use crate :: vstate:: vm:: Vm ;
7876use crate :: { EventManager , Vmm , VmmError , device_manager} ;
@@ -99,10 +97,8 @@ pub enum StartMicrovmError {
9997 CreateVMGenID ( VmGenIdError ) ,
10098 /// Invalid Memory Configuration: {0}
10199 GuestMemory ( crate :: vstate:: memory:: MemoryError ) ,
102- /// Cannot load initrd due to an invalid memory configuration.
103- InitrdLoad ,
104- /// Cannot load initrd due to an invalid image: {0}
105- InitrdRead ( io:: Error ) ,
100+ /// Error with initrd initialization: {0}.
101+ Initrd ( InitrdError ) ,
106102 /// Internal error while starting microVM: {0}
107103 Internal ( #[ from] VmmError ) ,
108104 /// Failed to get CPU template: {0}
@@ -241,7 +237,7 @@ pub fn build_microvm_for_boot(
241237 . map_err ( StartMicrovmError :: GuestMemory ) ?;
242238
243239 let entry_point = load_kernel ( boot_config, & guest_memory) ?;
244- let initrd = load_initrd_from_config ( boot_config, & guest_memory) ?;
240+ let initrd = InitrdConfig :: from_config ( boot_config, & guest_memory) . map_err ( Initrd ) ?;
245241 // Clone the command-line so that a failed boot doesn't pollute the original.
246242 #[ allow( unused_mut) ]
247243 let mut boot_cmdline = boot_config. cmdline . clone ( ) ;
@@ -449,7 +445,7 @@ pub fn build_microvm_from_snapshot(
449445 vm_resources. machine_config . vcpu_count ,
450446 microvm_state. kvm_state . kvm_cap_modifiers . clone ( ) ,
451447 )
452- . map_err ( Internal ) ?;
448+ . map_err ( StartMicrovmError :: Internal ) ?;
453449
454450 #[ cfg( target_arch = "x86_64" ) ]
455451 {
@@ -603,68 +599,6 @@ fn load_kernel(
603599 } )
604600}
605601
606- fn load_initrd_from_config (
607- boot_cfg : & BootConfig ,
608- vm_memory : & GuestMemoryMmap ,
609- ) -> Result < Option < InitrdConfig > , StartMicrovmError > {
610- use self :: StartMicrovmError :: InitrdRead ;
611-
612- Ok ( match & boot_cfg. initrd_file {
613- Some ( f) => Some ( load_initrd (
614- vm_memory,
615- & mut f. try_clone ( ) . map_err ( InitrdRead ) ?,
616- ) ?) ,
617- None => None ,
618- } )
619- }
620-
621- /// Loads the initrd from a file into the given memory slice.
622- ///
623- /// * `vm_memory` - The guest memory the initrd is written to.
624- /// * `image` - The initrd image.
625- ///
626- /// Returns the result of initrd loading
627- fn load_initrd < F > (
628- vm_memory : & GuestMemoryMmap ,
629- image : & mut F ,
630- ) -> Result < InitrdConfig , StartMicrovmError >
631- where
632- F : ReadVolatile + Seek + Debug ,
633- {
634- use self :: StartMicrovmError :: { InitrdLoad , InitrdRead } ;
635-
636- // Get the image size
637- let size = match image. seek ( SeekFrom :: End ( 0 ) ) {
638- Err ( err) => return Err ( InitrdRead ( err) ) ,
639- Ok ( 0 ) => {
640- return Err ( InitrdRead ( io:: Error :: new (
641- io:: ErrorKind :: InvalidData ,
642- "Initrd image seek returned a size of zero" ,
643- ) ) ) ;
644- }
645- Ok ( s) => u64_to_usize ( s) ,
646- } ;
647- // Go back to the image start
648- image. seek ( SeekFrom :: Start ( 0 ) ) . map_err ( InitrdRead ) ?;
649-
650- // Get the target address
651- let address = crate :: arch:: initrd_load_addr ( vm_memory, size) . map_err ( |_| InitrdLoad ) ?;
652-
653- // Load the image into memory
654- let mut slice = vm_memory
655- . get_slice ( GuestAddress ( address) , size)
656- . map_err ( |_| InitrdLoad ) ?;
657-
658- image
659- . read_exact_volatile ( & mut slice)
660- . map_err ( |_| InitrdLoad ) ?;
661-
662- Ok ( InitrdConfig {
663- address : GuestAddress ( address) ,
664- size,
665- } )
666- }
667-
668602/// Sets up the serial device.
669603pub fn setup_serial_device (
670604 event_manager : & mut EventManager ,
@@ -1010,7 +944,6 @@ pub(crate) fn set_stdout_nonblocking() {
1010944
1011945#[ cfg( test) ]
1012946pub ( crate ) mod tests {
1013- use std:: io:: Write ;
1014947
1015948 use linux_loader:: cmdline:: Cmdline ;
1016949 use vmm_sys_util:: tempfile:: TempFile ;
@@ -1024,7 +957,6 @@ pub(crate) mod tests {
1024957 use crate :: devices:: virtio:: { TYPE_BALLOON , TYPE_BLOCK , TYPE_RNG } ;
1025958 use crate :: mmds:: data_store:: { Mmds , MmdsVersion } ;
1026959 use crate :: mmds:: ns:: MmdsNetworkStack ;
1027- use crate :: test_utils:: { single_region_mem, single_region_mem_at} ;
1028960 use crate :: utils:: mib_to_bytes;
1029961 use crate :: vmm_config:: balloon:: { BALLOON_DEV_ID , BalloonBuilder , BalloonDeviceConfig } ;
1030962 use crate :: vmm_config:: boot_source:: DEFAULT_KERNEL_CMDLINE ;
@@ -1270,67 +1202,6 @@ pub(crate) mod tests {
12701202 ) ;
12711203 }
12721204
1273- fn make_test_bin ( ) -> Vec < u8 > {
1274- let mut fake_bin = Vec :: new ( ) ;
1275- fake_bin. resize ( 1_000_000 , 0xAA ) ;
1276- fake_bin
1277- }
1278-
1279- #[ test]
1280- // Test that loading the initrd is successful on different archs.
1281- fn test_load_initrd ( ) {
1282- use crate :: vstate:: memory:: GuestMemory ;
1283- let image = make_test_bin ( ) ;
1284-
1285- let mem_size: usize = image. len ( ) * 2 + crate :: arch:: GUEST_PAGE_SIZE ;
1286-
1287- let tempfile = TempFile :: new ( ) . unwrap ( ) ;
1288- let mut tempfile = tempfile. into_file ( ) ;
1289- tempfile. write_all ( & image) . unwrap ( ) ;
1290-
1291- #[ cfg( target_arch = "x86_64" ) ]
1292- let gm = single_region_mem ( mem_size) ;
1293-
1294- #[ cfg( target_arch = "aarch64" ) ]
1295- let gm = single_region_mem ( mem_size + crate :: arch:: aarch64:: layout:: FDT_MAX_SIZE ) ;
1296-
1297- let res = load_initrd ( & gm, & mut tempfile) ;
1298- let initrd = res. unwrap ( ) ;
1299- assert ! ( gm. address_in_range( initrd. address) ) ;
1300- assert_eq ! ( initrd. size, image. len( ) ) ;
1301- }
1302-
1303- #[ test]
1304- fn test_load_initrd_no_memory ( ) {
1305- let gm = single_region_mem ( 79 ) ;
1306- let image = make_test_bin ( ) ;
1307- let tempfile = TempFile :: new ( ) . unwrap ( ) ;
1308- let mut tempfile = tempfile. into_file ( ) ;
1309- tempfile. write_all ( & image) . unwrap ( ) ;
1310- let res = load_initrd ( & gm, & mut tempfile) ;
1311- assert ! (
1312- matches!( res, Err ( StartMicrovmError :: InitrdLoad ) ) ,
1313- "{:?}" ,
1314- res
1315- ) ;
1316- }
1317-
1318- #[ test]
1319- fn test_load_initrd_unaligned ( ) {
1320- let image = vec ! [ 1 , 2 , 3 , 4 ] ;
1321- let tempfile = TempFile :: new ( ) . unwrap ( ) ;
1322- let mut tempfile = tempfile. into_file ( ) ;
1323- tempfile. write_all ( & image) . unwrap ( ) ;
1324- let gm = single_region_mem_at ( crate :: arch:: GUEST_PAGE_SIZE as u64 + 1 , image. len ( ) * 2 ) ;
1325-
1326- let res = load_initrd ( & gm, & mut tempfile) ;
1327- assert ! (
1328- matches!( res, Err ( StartMicrovmError :: InitrdLoad ) ) ,
1329- "{:?}" ,
1330- res
1331- ) ;
1332- }
1333-
13341205 #[ test]
13351206 fn test_attach_net_devices ( ) {
13361207 let mut event_manager = EventManager :: new ( ) . expect ( "Unable to create EventManager" ) ;
0 commit comments