runtime-rs: Add format argument to hotplug_block_device method

Add format argument to hotplug_block_device for flexibly specifying
different block formats.
With this, we can support kinds of formats, currently raw and vmdk are
supported, and some other formats will be supported in future.

Aside the formats, the corresponding handling logics are also required
to properly handle its options needed in QMP blockdev-add.

Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
This commit is contained in:
Alex Lyn
2026-04-07 15:51:17 +08:00
committed by Fabiano Fidêncio
parent 15740439eb
commit c06bc388c2
2 changed files with 46 additions and 17 deletions

View File

@@ -868,6 +868,7 @@ impl QemuInner {
block_device.config.no_drop,
block_device.config.logical_sector_size,
block_device.config.physical_sector_size,
&block_device.config.format,
)
.context("hotplug block device")?;

View File

@@ -6,6 +6,7 @@
use crate::device::pci_path::PciPath;
use crate::qemu::cmdline_generator::{CcwSubChannel, DeviceVirtioNet, Netdev, QMP_SOCKET_FILE};
use crate::utils::get_jailer_root;
use crate::BlockDeviceFormat;
use crate::VcpuThreadIds;
use anyhow::{anyhow, Context, Result};
@@ -14,7 +15,8 @@ use kata_types::rootless::is_rootless;
use nix::sys::socket::{sendmsg, ControlMessage, MsgFlags};
use qapi_qmp::{
self as qmp, BlockdevAioOptions, BlockdevOptions, BlockdevOptionsBase,
BlockdevOptionsGenericFormat, BlockdevOptionsRaw, BlockdevRef, MigrationInfo, PciDeviceInfo,
BlockdevOptionsGenericCOWFormat, BlockdevOptionsGenericFormat, BlockdevOptionsRaw, BlockdevRef,
MigrationInfo, PciDeviceInfo,
};
use qapi_qmp::{migrate, migrate_incoming, migrate_set_capabilities};
use qapi_qmp::{MigrationCapability, MigrationCapabilityStatus};
@@ -644,6 +646,7 @@ impl Qmp {
no_drop: bool,
logical_block_size: u32,
physical_block_size: u32,
format: &BlockDeviceFormat,
) -> Result<(Option<PciPath>, Option<String>)> {
// `blockdev-add`
let node_name = format!("drive-{index}");
@@ -692,27 +695,52 @@ impl Qmp {
}
};
let blockdev_options_raw = BlockdevOptions::raw {
base: BlockdevOptionsBase {
detect_zeroes: None,
cache: None,
discard: None,
force_share: None,
auto_read_only: None,
node_name: Some(node_name.clone()),
read_only: None,
},
raw: BlockdevOptionsRaw {
base: BlockdevOptionsGenericFormat {
file: BlockdevRef::definition(Box::new(blockdev_file)),
let blockdev_options = match format {
BlockDeviceFormat::Raw => BlockdevOptions::raw {
base: BlockdevOptionsBase {
detect_zeroes: None,
cache: None,
discard: None,
force_share: if is_readonly { Some(true) } else { None },
auto_read_only: None,
node_name: Some(node_name.clone()),
read_only: Some(is_readonly),
},
raw: BlockdevOptionsRaw {
base: BlockdevOptionsGenericFormat {
file: BlockdevRef::definition(Box::new(blockdev_file)),
},
offset: None,
size: None,
},
offset: None,
size: None,
},
BlockDeviceFormat::Vmdk => {
info!(
sl!(),
"hotplug_block_device: using VMDK format driver for {}", path_on_host
);
BlockdevOptions::vmdk {
base: BlockdevOptionsBase {
detect_zeroes: None,
cache: None,
discard: None,
force_share: None,
auto_read_only: None,
node_name: Some(node_name.clone()),
read_only: Some(is_readonly),
},
vmdk: BlockdevOptionsGenericCOWFormat {
base: BlockdevOptionsGenericFormat {
file: BlockdevRef::definition(Box::new(blockdev_file)),
},
backing: None,
},
}
}
};
self.qmp
.execute(&qapi_qmp::blockdev_add(blockdev_options_raw))
.execute(&qapi_qmp::blockdev_add(blockdev_options))
.map_err(|e| anyhow!("blockdev-add backend {:?}", e))
.map(|_| ())?;