@@ -69,6 +69,9 @@ const WRITE_METRICS_PERIOD_SECONDS: u64 = 60;
6969pub enum Error {
7070 ApiChannel ,
7171 ConfigureSystem ( x86_64:: Error ) ,
72+ CreateBlockDevice ( sys_util:: Error ) ,
73+ CreateNetDevice ( devices:: virtio:: Error ) ,
74+ CreateRateLimiter ( std:: io:: Error ) ,
7275 CreateLegacyDevice ( device_manager:: legacy:: Error ) ,
7376 DriveError ( DriveError ) ,
7477 DeviceVmRequest ( sys_util:: Error ) ,
@@ -86,14 +89,11 @@ pub enum Error {
8689 LegacyIOBus ( device_manager:: legacy:: Error ) ,
8790 LogMetrics ( logger:: error:: LoggerError ) ,
8891 MissingKernelConfig ,
89- NetDeviceNew ( devices:: virtio:: Error ) ,
9092 NetDeviceUnconfigured ,
93+ OpenBlockDevice ( std:: io:: Error ) ,
9194 Poll ( std:: io:: Error ) ,
92- RootBlockDeviceNew ( sys_util:: Error ) ,
93- RootDiskImage ( std:: io:: Error ) ,
94- RateLimiterNew ( std:: io:: Error ) ,
95- RegisterBlock ( device_manager:: mmio:: Error ) ,
96- RegisterNet ( device_manager:: mmio:: Error ) ,
95+ RegisterBlockDevice ( device_manager:: mmio:: Error ) ,
96+ RegisterNetDevice ( device_manager:: mmio:: Error ) ,
9797 Serial ( sys_util:: Error ) ,
9898 StdinHandle ( sys_util:: Error ) ,
9999 Terminal ( sys_util:: Error ) ,
@@ -119,7 +119,7 @@ impl std::convert::From<x86_64::Error> for Error {
119119
120120impl std:: convert:: From < kernel_cmdline:: Error > for Error {
121121 fn from ( e : kernel_cmdline:: Error ) -> Error {
122- Error :: RegisterBlock ( device_manager:: mmio:: Error :: Cmdline ( e) )
122+ Error :: RegisterBlockDevice ( device_manager:: mmio:: Error :: Cmdline ( e) )
123123 }
124124}
125125
@@ -526,7 +526,6 @@ impl Vmm {
526526
527527 // Attaches all block devices from the BlockDevicesConfig.
528528 fn attach_block_devices ( & mut self , device_manager : & mut MMIODeviceManager ) -> Result < ( ) > {
529- // If there's no root device, do not attach any other devices. This is a bug!
530529 let block_dev = & self . block_device_configs ;
531530 // We rely on check_health function for making sure kernel_config is not None.
532531 let kernel_config = self . kernel_config . as_mut ( ) . unwrap ( ) ;
@@ -540,45 +539,46 @@ impl Vmm {
540539 kernel_config. cmdline . insert_str ( " ro" ) ?;
541540 }
542541 }
542+ }
543543
544- let epoll_context = & mut self . epoll_context ;
545- for drive_config in self . block_device_configs . config_list . iter ( ) {
546- // Add the root block device from file.
547- let root_image = OpenOptions :: new ( )
548- . read ( true )
549- . write ( !drive_config. is_read_only )
550- . open ( & drive_config. path_on_host )
551- . map_err ( Error :: RootDiskImage ) ?;
552-
553- if drive_config. is_root_device && drive_config. partuuid . is_some ( ) {
554- kernel_config. cmdline . insert_str ( format ! (
555- " root=PARTUUID={}" ,
556- drive_config . get_partuuid ( ) . unwrap ( )
557- ) ) ? ;
558- if drive_config . is_read_only {
559- kernel_config . cmdline . insert_str ( " ro" ) ? ;
560- }
544+ let epoll_context = & mut self . epoll_context ;
545+ for drive_config in self . block_device_configs . config_list . iter ( ) {
546+ // Add the block device from file.
547+ let block_file = OpenOptions :: new ( )
548+ . read ( true )
549+ . write ( !drive_config. is_read_only )
550+ . open ( & drive_config. path_on_host )
551+ . map_err ( Error :: OpenBlockDevice ) ?;
552+
553+ if drive_config. is_root_device && drive_config. get_partuuid ( ) . is_some ( ) {
554+ kernel_config. cmdline . insert_str ( format ! (
555+ " root=PARTUUID={}" ,
556+ //The unwrap is safe as we are firstly checking that partuuid is_some ().
557+ drive_config . get_partuuid ( ) . unwrap ( )
558+ ) ) ? ;
559+ if drive_config . is_read_only {
560+ kernel_config . cmdline . insert_str ( " ro" ) ? ;
561561 }
562-
563- let epoll_config = epoll_context. allocate_virtio_block_tokens ( ) ;
564-
565- let rate_limiter = rate_limiter_description_into_implementation (
566- drive_config. rate_limiter . as_ref ( ) ,
567- ) . map_err ( Error :: RateLimiterNew ) ?;
568- let block_box = Box :: new ( devices:: virtio:: Block :: new (
569- root_image,
570- drive_config. is_read_only ,
571- epoll_config,
572- rate_limiter,
573- ) . map_err ( Error :: RootBlockDeviceNew ) ?) ;
574- device_manager
575- . register_device (
576- block_box,
577- & mut kernel_config. cmdline ,
578- Some ( drive_config. drive_id . clone ( ) ) ,
579- )
580- . map_err ( Error :: RegisterBlock ) ?;
581562 }
563+
564+ let epoll_config = epoll_context. allocate_virtio_block_tokens ( ) ;
565+
566+ let rate_limiter = rate_limiter_description_into_implementation (
567+ drive_config. rate_limiter . as_ref ( ) ,
568+ ) . map_err ( Error :: CreateRateLimiter ) ?;
569+ let block_box = Box :: new ( devices:: virtio:: Block :: new (
570+ block_file,
571+ drive_config. is_read_only ,
572+ epoll_config,
573+ rate_limiter,
574+ ) . map_err ( Error :: CreateBlockDevice ) ?) ;
575+ device_manager
576+ . register_device (
577+ block_box,
578+ & mut kernel_config. cmdline ,
579+ Some ( drive_config. drive_id . clone ( ) ) ,
580+ )
581+ . map_err ( Error :: RegisterBlockDevice ) ?;
582582 }
583583
584584 Ok ( ( ) )
@@ -644,10 +644,10 @@ impl Vmm {
644644
645645 let rx_rate_limiter = rate_limiter_description_into_implementation (
646646 cfg. rx_rate_limiter . as_ref ( ) ,
647- ) . map_err ( Error :: RateLimiterNew ) ?;
647+ ) . map_err ( Error :: CreateRateLimiter ) ?;
648648 let tx_rate_limiter = rate_limiter_description_into_implementation (
649649 cfg. tx_rate_limiter . as_ref ( ) ,
650- ) . map_err ( Error :: RateLimiterNew ) ?;
650+ ) . map_err ( Error :: CreateRateLimiter ) ?;
651651
652652 if let Some ( tap) = cfg. take_tap ( ) {
653653 let net_box = Box :: new ( devices:: virtio:: Net :: new_with_tap (
@@ -656,11 +656,11 @@ impl Vmm {
656656 epoll_config,
657657 rx_rate_limiter,
658658 tx_rate_limiter,
659- ) . map_err ( Error :: NetDeviceNew ) ?) ;
659+ ) . map_err ( Error :: CreateNetDevice ) ?) ;
660660
661661 device_manager
662662 . register_device ( net_box, & mut kernel_config. cmdline , None )
663- . map_err ( Error :: RegisterNet ) ?;
663+ . map_err ( Error :: RegisterNetDevice ) ?;
664664 } else {
665665 return Err ( Error :: NetDeviceUnconfigured ) ;
666666 }
@@ -1829,5 +1829,11 @@ mod tests {
18291829 assert ! ( !vmm. get_kernel_cmdline( ) . contains( "root=PARTUUID=" ) ) ;
18301830 assert ! ( !vmm. get_kernel_cmdline( ) . contains( "root=/dev/vda" ) ) ;
18311831
1832+ // Test that the non root device is attached.
1833+ assert ! (
1834+ device_manager
1835+ . get_address( & non_root_block_device. drive_id)
1836+ . is_some( )
1837+ ) ;
18321838 }
18331839}
0 commit comments