runtime-rs: Add BlockModern support in Dragonball VMM

Extend add_block_device with num_queues and queue_size parameters
to support multi-queue virtio-blk configuration, and add BlockModern
hotplug/hotunplug handler that extracts config from
Arc<Mutex<BlockDeviceModern>>, passes the new parameters to
add_block_device, and updates pci_path on successful hotplug.

And we will use BlockDeviceModern to handle block device instead of
Legacy BlockDevice.

Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
This commit is contained in:
Alex Lyn
2026-06-26 20:25:19 +08:00
committed by Fabiano Fidêncio
parent 65d580c2b0
commit 525b68e332

View File

@@ -62,31 +62,67 @@ impl DragonballInner {
Ok(DeviceType::Vfio(hostdev))
}
DeviceType::Block(mut block) => {
let use_pci_bus = if block.config.driver_option == KATA_BLK_DEV_TYPE {
DeviceType::BlockModern(block_device) => {
let (
device_id,
path_on_host,
is_readonly,
no_drop,
is_direct,
driver_option,
) = {
let dev = block_device.lock().await;
let cfg = &dev.config;
(
dev.device_id.clone(),
cfg.path_on_host.clone(),
cfg.is_readonly,
cfg.no_drop,
cfg.is_direct,
cfg.driver_option.clone(),
)
};
let use_pci_bus = if driver_option == KATA_BLK_DEV_TYPE {
Some(true)
} else {
None
};
info!(
sl!(),
"BlockModern hotplug: device_id={}, path={}, driver={}, readonly={}",
device_id,
path_on_host,
driver_option,
is_readonly,
);
let guest_device_id = self
.add_block_device(
block.config.path_on_host.as_str(),
block.device_id.as_str(),
block.config.is_readonly,
block.config.no_drop,
block.config.is_direct,
&path_on_host,
&device_id,
is_readonly,
no_drop,
is_direct,
use_pci_bus,
)
.context("add block device")?;
.context("add block modern device")?;
info!(
sl!(),
"BlockModern hotplug result: device_id={}, guest_device_id={:?}",
device_id, guest_device_id
);
if let Some(slot) = guest_device_id {
if slot > 0 {
block.config.pci_path = Some(PciPath::try_from(slot as u32)?);
let mut dev = block_device.lock().await;
dev.config.pci_path = Some(PciPath::try_from(slot as u32)?);
}
}
Ok(DeviceType::Block(block))
Ok(DeviceType::BlockModern(block_device))
}
DeviceType::VhostUserBlk(block) => {
self.add_block_device(
@@ -131,9 +167,11 @@ impl DragonballInner {
Ok(())
}
DeviceType::Block(block) => self
.remove_block_drive(block.device_id.as_str())
.context("remove block drive"),
DeviceType::BlockModern(block_device) => {
let device_id = block_device.lock().await.device_id.clone();
self.remove_block_drive(&device_id)
.context("remove block modern drive")
}
DeviceType::Vfio(hostdev) => {
let primary_device = hostdev.devices.first().unwrap().clone();
let hostdev_id = primary_device.hostdev_id;
@@ -251,7 +289,7 @@ impl DragonballInner {
let blk_cfg = BlockDeviceConfigInfo {
drive_id: id.to_string(),
device_type: BlockDeviceType::get_type(path),
path_on_host: PathBuf::from(jailed_drive),
path_on_host: PathBuf::from(jailed_drive.clone()),
is_direct: is_direct.unwrap_or(self.config.blockdev_info.block_device_cache_direct),
no_drop,
is_read_only: read_only,
@@ -259,9 +297,24 @@ impl DragonballInner {
rate_limiter: Some(block_rate_limit),
..Default::default()
};
self.vmm_instance
info!(
sl!(),
"add_block_device: id={}, path={}, device_type={:?}, use_pci_bus={:?}, vm_running={}",
id,
jailed_drive,
BlockDeviceType::get_type(path),
use_pci_bus,
self.state == VmmState::VmRunning
);
let result = self
.vmm_instance
.insert_block_device(blk_cfg, Duration::from_millis(DEFAULT_HOTPLUG_TIMEOUT))
.context("insert block device")
.context("insert block device");
match &result {
Ok(guest_id) => info!(sl!(), "add_block_device success: id={}, guest_id={:?}", id, guest_id),
Err(e) => error!(sl!(), "add_block_device failed: id={}, error={:?}", id, e),
}
result
}
fn remove_block_drive(&mut self, id: &str) -> Result<()> {