diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs b/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs index ec7d55c6f2..7a56d6a40b 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs @@ -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")?; diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/qmp.rs b/src/runtime-rs/crates/hypervisor/src/qemu/qmp.rs index a6bde80f26..0d2df9dd6e 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/qmp.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/qmp.rs @@ -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, Option)> { // `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(|_| ())?;