Skip to content

Commit 57046df

Browse files
dianpopaacatangiu
authored andcommitted
vmm: fix bug where no block device...
would get attached if a root block device was not specified. Add related unit tests. Signed-off-by: Diana Popa <[email protected]>
1 parent 7605f64 commit 57046df

File tree

1 file changed

+54
-48
lines changed

1 file changed

+54
-48
lines changed

vmm/src/lib.rs

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ const WRITE_METRICS_PERIOD_SECONDS: u64 = 60;
6969
pub 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

120120
impl 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

Comments
 (0)