in src/vmm/src/builder.rs [1294:1467]
fn test_attach_block_devices() {
let mut event_manager = EventManager::new().expect("Unable to create EventManager");
// Use case 1: root block device is not specified through PARTUUID.
{
let drive_id = String::from("root");
let block_configs = vec![CustomBlockConfig::new(
drive_id.clone(),
true,
None,
true,
CacheType::Unsafe,
)];
let mut vmm = default_vmm();
let mut cmdline = default_kernel_cmdline();
insert_block_devices(&mut vmm, &mut cmdline, &mut event_manager, block_configs);
assert!(cmdline.as_str().contains("root=/dev/vda ro"));
assert!(vmm
.mmio_device_manager
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
.is_some());
}
// Use case 2: root block device is specified through PARTUUID.
{
let drive_id = String::from("root");
let block_configs = vec![CustomBlockConfig::new(
drive_id.clone(),
true,
Some("0eaa91a0-01".to_string()),
false,
CacheType::Unsafe,
)];
let mut vmm = default_vmm();
let mut cmdline = default_kernel_cmdline();
insert_block_devices(&mut vmm, &mut cmdline, &mut event_manager, block_configs);
assert!(cmdline.as_str().contains("root=PARTUUID=0eaa91a0-01 rw"));
assert!(vmm
.mmio_device_manager
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
.is_some());
}
// Use case 3: root block device is not added at all.
{
let drive_id = String::from("non_root");
let block_configs = vec![CustomBlockConfig::new(
drive_id.clone(),
false,
Some("0eaa91a0-01".to_string()),
false,
CacheType::Unsafe,
)];
let mut vmm = default_vmm();
let mut cmdline = default_kernel_cmdline();
insert_block_devices(&mut vmm, &mut cmdline, &mut event_manager, block_configs);
assert!(!cmdline.as_str().contains("root=PARTUUID="));
assert!(!cmdline.as_str().contains("root=/dev/vda"));
assert!(vmm
.mmio_device_manager
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
.is_some());
}
// Use case 4: rw root block device and other rw and ro drives.
{
let block_configs = vec![
CustomBlockConfig::new(
String::from("root"),
true,
Some("0eaa91a0-01".to_string()),
false,
CacheType::Unsafe,
),
CustomBlockConfig::new(
String::from("secondary"),
false,
None,
true,
CacheType::Unsafe,
),
CustomBlockConfig::new(
String::from("third"),
false,
None,
false,
CacheType::Unsafe,
),
];
let mut vmm = default_vmm();
let mut cmdline = default_kernel_cmdline();
insert_block_devices(&mut vmm, &mut cmdline, &mut event_manager, block_configs);
assert!(cmdline.as_str().contains("root=PARTUUID=0eaa91a0-01 rw"));
assert!(vmm
.mmio_device_manager
.get_device(DeviceType::Virtio(TYPE_BLOCK), "root")
.is_some());
assert!(vmm
.mmio_device_manager
.get_device(DeviceType::Virtio(TYPE_BLOCK), "secondary")
.is_some());
assert!(vmm
.mmio_device_manager
.get_device(DeviceType::Virtio(TYPE_BLOCK), "third")
.is_some());
// Check if these three block devices are inserted in kernel_cmdline.
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
assert!(cmdline
.as_str()
.contains("virtio_mmio.device=4K@0xd0000000:5 virtio_mmio.device=4K@0xd0001000:6 virtio_mmio.device=4K@0xd0002000:7"));
}
// Use case 5: root block device is rw.
{
let drive_id = String::from("root");
let block_configs = vec![CustomBlockConfig::new(
drive_id.clone(),
true,
None,
false,
CacheType::Unsafe,
)];
let mut vmm = default_vmm();
let mut cmdline = default_kernel_cmdline();
insert_block_devices(&mut vmm, &mut cmdline, &mut event_manager, block_configs);
assert!(cmdline.as_str().contains("root=/dev/vda rw"));
assert!(vmm
.mmio_device_manager
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
.is_some());
}
// Use case 6: root block device is ro, with PARTUUID.
{
let drive_id = String::from("root");
let block_configs = vec![CustomBlockConfig::new(
drive_id.clone(),
true,
Some("0eaa91a0-01".to_string()),
true,
CacheType::Unsafe,
)];
let mut vmm = default_vmm();
let mut cmdline = default_kernel_cmdline();
insert_block_devices(&mut vmm, &mut cmdline, &mut event_manager, block_configs);
assert!(cmdline.as_str().contains("root=PARTUUID=0eaa91a0-01 ro"));
assert!(vmm
.mmio_device_manager
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
.is_some());
}
// Use case 7: root block device is rw with flush enabled
{
let drive_id = String::from("root");
let block_configs = vec![CustomBlockConfig::new(
drive_id.clone(),
true,
None,
false,
CacheType::Writeback,
)];
let mut vmm = default_vmm();
let mut cmdline = default_kernel_cmdline();
insert_block_devices(&mut vmm, &mut cmdline, &mut event_manager, block_configs);
assert!(cmdline.as_str().contains("root=/dev/vda rw"));
assert!(vmm
.mmio_device_manager
.get_device(DeviceType::Virtio(TYPE_BLOCK), drive_id.as_str())
.is_some());
}
}