mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-04-11 14:32:26 +00:00
runtime-rs: allow specifying logical/physical sector size for block devices
Add two new configuration knobs that control the logical and physical sector sizes advertised by virtio-blk devices to the guest: block_device_logical_sector_size (config file) block_device_physical_sector_size (config file) io.katacontainers.config.hypervisor.blk_logical_sector_size (annotation) io.katacontainers.config.hypervisor.blk_physical_sector_size (annotation) The annotation names are abbreviated relative to the config file keys because Kubernetes enforces a 63-character limit on annotation name segments, and the full names would exceed it. Both settings default to 0 (let QEMU decide). When set, they are passed as logical_block_size and physical_block_size in the QMP device_add command during block device hotplug. Setting logical_sector_size smaller then container filesystem block size will cause EINVAL on mount. The physical_sector_size can always be set independently. Values must be 0 or a power of 2 in the range [512, 65536]; other values are rejected with an error at sandbox creation time. Signed-off-by: PiotrProkop <pprokop@nvidia.com>
This commit is contained in:
@@ -284,6 +284,20 @@ pub const KATA_ANNO_CFG_HYPERVISOR_DEFAULT_GPUS: &str =
|
||||
pub const KATA_ANNO_CFG_HYPERVISOR_DEFAULT_GPU_MODEL: &str =
|
||||
"io.katacontainers.config.hypervisor.default_gpu_model";
|
||||
|
||||
/// A sandbox annotation that specifies the logical sector size reported by block devices to the
|
||||
/// guest, in bytes. Common values are 512 and 4096. Set to 0 to use the hypervisor default.
|
||||
/// NOTE: the annotation key uses "blk_logical_sector_size" rather than
|
||||
/// "block_device_logical_sector_size" because Kubernetes enforces a 63-character limit on
|
||||
/// annotation name segments.
|
||||
pub const KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE: &str =
|
||||
"io.katacontainers.config.hypervisor.blk_logical_sector_size";
|
||||
/// A sandbox annotation that specifies the physical sector size reported by block devices to the
|
||||
/// guest, in bytes. Common values are 512 and 4096. Set to 0 to use the hypervisor default.
|
||||
/// NOTE: the annotation key uses "blk_physical_sector_size" rather than
|
||||
/// "block_device_physical_sector_size" because Kubernetes enforces a 63-character limit on
|
||||
/// annotation name segments.
|
||||
pub const KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE: &str =
|
||||
"io.katacontainers.config.hypervisor.blk_physical_sector_size";
|
||||
/// Block device specific annotation for num_queues
|
||||
pub const KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_NUM_QUEUES: &str =
|
||||
"io.katacontainers.config.hypervisor.block_device_num_queues";
|
||||
@@ -973,6 +987,48 @@ impl Annotation {
|
||||
hv.shared_fs.virtio_fs_extra_args.push(arg.to_string());
|
||||
}
|
||||
}
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE => {
|
||||
match self.get_value::<u32>(key) {
|
||||
Ok(v) => {
|
||||
let size = v.unwrap_or_default();
|
||||
if let Err(e) =
|
||||
crate::config::hypervisor::validate_block_device_sector_size(
|
||||
size,
|
||||
)
|
||||
{
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
e.to_string(),
|
||||
));
|
||||
}
|
||||
hv.blockdev_info.block_device_logical_sector_size = size;
|
||||
}
|
||||
Err(_e) => {
|
||||
return Err(u32_err);
|
||||
}
|
||||
}
|
||||
}
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE => {
|
||||
match self.get_value::<u32>(key) {
|
||||
Ok(v) => {
|
||||
let size = v.unwrap_or_default();
|
||||
if let Err(e) =
|
||||
crate::config::hypervisor::validate_block_device_sector_size(
|
||||
size,
|
||||
)
|
||||
{
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
e.to_string(),
|
||||
));
|
||||
}
|
||||
hv.blockdev_info.block_device_physical_sector_size = size;
|
||||
}
|
||||
Err(_e) => {
|
||||
return Err(u32_err);
|
||||
}
|
||||
}
|
||||
}
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_NUM_QUEUES => {
|
||||
match self.get_value::<usize>(key) {
|
||||
Ok(v) => {
|
||||
@@ -1123,6 +1179,18 @@ impl Annotation {
|
||||
}
|
||||
}
|
||||
|
||||
// Validate cross-field constraint: logical sector size must not exceed physical.
|
||||
// Individual sizes are validated inside the loop, but the cross-field check must
|
||||
// run after both annotations have been applied.
|
||||
let logical = hv.blockdev_info.block_device_logical_sector_size;
|
||||
let physical = hv.blockdev_info.block_device_physical_sector_size;
|
||||
if logical != 0 && physical != 0 && logical > physical {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::InvalidData,
|
||||
format!("invalid sector sizes: logical ({logical}) must not be larger than physical ({physical})"),
|
||||
));
|
||||
}
|
||||
|
||||
config.adjust_config()?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -271,6 +271,18 @@ pub struct BlockDeviceInfo {
|
||||
#[serde(default)]
|
||||
pub block_device_cache_noflush: bool,
|
||||
|
||||
/// Specifies the logical sector size, in bytes, reported by block devices to the guest.
|
||||
/// Common values are 512 and 4096. Set to 0 to use the hypervisor default.
|
||||
/// Must be 0 or a power of 2 between 512 and 65536.
|
||||
#[serde(default)]
|
||||
pub block_device_logical_sector_size: u32,
|
||||
|
||||
/// Specifies the physical sector size, in bytes, reported by block devices to the guest.
|
||||
/// Common values are 512 and 4096. Set to 0 to use the hypervisor default.
|
||||
/// Must be 0 or a power of 2 between 512 and 65536.
|
||||
#[serde(default)]
|
||||
pub block_device_physical_sector_size: u32,
|
||||
|
||||
/// If false and nvdimm is supported, use nvdimm device to plug guest image.
|
||||
#[serde(default)]
|
||||
pub disable_image_nvdimm: bool,
|
||||
@@ -400,6 +412,16 @@ impl BlockDeviceInfo {
|
||||
"Invalid vhost-user-store-path {}: {}"
|
||||
)?;
|
||||
|
||||
validate_block_device_sector_size(self.block_device_logical_sector_size)?;
|
||||
validate_block_device_sector_size(self.block_device_physical_sector_size)?;
|
||||
let logical = self.block_device_logical_sector_size;
|
||||
let physical = self.block_device_physical_sector_size;
|
||||
if logical != 0 && physical != 0 && logical > physical {
|
||||
return Err(std::io::Error::other(format!(
|
||||
"invalid sector sizes: logical ({logical}) must not be larger than physical ({physical})"
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -409,6 +431,19 @@ impl BlockDeviceInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/// Validate that a block device sector size is 0 or a power of 2 in [512, 65536].
|
||||
pub fn validate_block_device_sector_size(size: u32) -> Result<()> {
|
||||
if size == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
if !(512..=65536).contains(&size) || (size & (size - 1)) != 0 {
|
||||
return Err(std::io::Error::other(format!(
|
||||
"invalid sector size {size}: must be 0 or a power of 2 between 512 and 65536"
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Guest kernel boot information.
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct BootInfo {
|
||||
@@ -2072,4 +2107,83 @@ mod tests {
|
||||
expected_error_msg
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_block_device_sector_size_valid() {
|
||||
for size in [0, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536] {
|
||||
assert!(
|
||||
validate_block_device_sector_size(size).is_ok(),
|
||||
"expected size {} to be accepted",
|
||||
size
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_block_device_sector_size_not_power_of_two() {
|
||||
for size in [3, 100, 1000, 3000, 5000] {
|
||||
assert!(
|
||||
validate_block_device_sector_size(size).is_err(),
|
||||
"expected non-power-of-2 size {} to be rejected",
|
||||
size
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_block_device_sector_size_below_minimum() {
|
||||
for size in [1, 256] {
|
||||
assert!(
|
||||
validate_block_device_sector_size(size).is_err(),
|
||||
"expected below-minimum size {} to be rejected",
|
||||
size
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_block_device_sector_size_above_maximum() {
|
||||
for size in [131072, 1048576] {
|
||||
assert!(
|
||||
validate_block_device_sector_size(size).is_err(),
|
||||
"expected above-maximum size {} to be rejected",
|
||||
size
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn blockdev_info_with_sectors(logical: u32, physical: u32) -> BlockDeviceInfo {
|
||||
BlockDeviceInfo {
|
||||
block_device_driver: VIRTIO_BLK_PCI.to_string(),
|
||||
block_device_logical_sector_size: logical,
|
||||
block_device_physical_sector_size: physical,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_block_device_sector_sizes_valid() {
|
||||
assert!(blockdev_info_with_sectors(0, 0).validate().is_ok());
|
||||
assert!(blockdev_info_with_sectors(512, 0).validate().is_ok());
|
||||
assert!(blockdev_info_with_sectors(0, 4096).validate().is_ok());
|
||||
assert!(blockdev_info_with_sectors(512, 4096).validate().is_ok());
|
||||
assert!(blockdev_info_with_sectors(4096, 4096).validate().is_ok());
|
||||
assert!(blockdev_info_with_sectors(512, 512).validate().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_validate_block_device_sector_sizes_logical_exceeds_physical() {
|
||||
assert!(
|
||||
blockdev_info_with_sectors(4096, 512).validate().is_err(),
|
||||
"logical > physical should be rejected"
|
||||
);
|
||||
assert!(
|
||||
blockdev_info_with_sectors(4096, 1024).validate().is_err(),
|
||||
"logical > physical should be rejected"
|
||||
);
|
||||
assert!(
|
||||
blockdev_info_with_sectors(65536, 512).validate().is_err(),
|
||||
"logical > physical should be rejected"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,9 @@ mod tests {
|
||||
use kata_types::annotations::{
|
||||
Annotation, KATA_ANNO_CFG_AGENT_CONTAINER_PIPE_SIZE, KATA_ANNO_CFG_AGENT_TRACE,
|
||||
KATA_ANNO_CFG_DISABLE_GUEST_SECCOMP, KATA_ANNO_CFG_ENABLE_PPROF,
|
||||
KATA_ANNO_CFG_EXPERIMENTAL, KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_CACHE_NOFLUSH,
|
||||
KATA_ANNO_CFG_EXPERIMENTAL, KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE,
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE,
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_CACHE_NOFLUSH,
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLOCK_DEV_DRIVER, KATA_ANNO_CFG_HYPERVISOR_DEFAULT_MEMORY,
|
||||
KATA_ANNO_CFG_HYPERVISOR_DEFAULT_VCPUS, KATA_ANNO_CFG_HYPERVISOR_ENABLE_GUEST_SWAP,
|
||||
KATA_ANNO_CFG_HYPERVISOR_ENABLE_HUGEPAGES, KATA_ANNO_CFG_HYPERVISOR_ENABLE_IO_THREADS,
|
||||
@@ -479,4 +481,111 @@ mod tests {
|
||||
let mut config = TomlConfig::load(content).unwrap();
|
||||
assert!(anno.update_config_by_annotation(&mut config).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_device_sector_size_annotations_valid() {
|
||||
let content = include_str!("texture/configuration-anno-0.toml");
|
||||
|
||||
let qemu = QemuConfig::new();
|
||||
qemu.register();
|
||||
|
||||
// Valid: 512 logical, 4096 physical
|
||||
let config = TomlConfig::load(content).unwrap();
|
||||
KataConfig::set_active_config(Some(config), "qemu", "agent0");
|
||||
|
||||
let mut anno_hash = HashMap::new();
|
||||
anno_hash.insert(
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE.to_string(),
|
||||
"512".to_string(),
|
||||
);
|
||||
anno_hash.insert(
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE.to_string(),
|
||||
"4096".to_string(),
|
||||
);
|
||||
let anno = Annotation::new(anno_hash);
|
||||
let mut config = TomlConfig::load(content).unwrap();
|
||||
assert!(anno.update_config_by_annotation(&mut config).is_ok());
|
||||
if let Some(hv) = config.hypervisor.get("qemu") {
|
||||
assert_eq!(hv.blockdev_info.block_device_logical_sector_size, 512);
|
||||
assert_eq!(hv.blockdev_info.block_device_physical_sector_size, 4096);
|
||||
}
|
||||
|
||||
// Valid: 0 means hypervisor default
|
||||
let mut anno_hash = HashMap::new();
|
||||
anno_hash.insert(
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE.to_string(),
|
||||
"0".to_string(),
|
||||
);
|
||||
anno_hash.insert(
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE.to_string(),
|
||||
"0".to_string(),
|
||||
);
|
||||
let anno = Annotation::new(anno_hash);
|
||||
let mut config = TomlConfig::load(content).unwrap();
|
||||
assert!(anno.update_config_by_annotation(&mut config).is_ok());
|
||||
if let Some(hv) = config.hypervisor.get("qemu") {
|
||||
assert_eq!(hv.blockdev_info.block_device_logical_sector_size, 0);
|
||||
assert_eq!(hv.blockdev_info.block_device_physical_sector_size, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_device_sector_size_annotation_invalid_not_power_of_two() {
|
||||
let content = include_str!("texture/configuration-anno-0.toml");
|
||||
|
||||
let qemu = QemuConfig::new();
|
||||
qemu.register();
|
||||
|
||||
let config = TomlConfig::load(content).unwrap();
|
||||
KataConfig::set_active_config(Some(config), "qemu", "agent0");
|
||||
|
||||
let mut anno_hash = HashMap::new();
|
||||
anno_hash.insert(
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE.to_string(),
|
||||
"1000".to_string(),
|
||||
);
|
||||
let anno = Annotation::new(anno_hash);
|
||||
let mut config = TomlConfig::load(content).unwrap();
|
||||
assert!(anno.update_config_by_annotation(&mut config).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_device_sector_size_annotation_invalid_below_minimum() {
|
||||
let content = include_str!("texture/configuration-anno-0.toml");
|
||||
|
||||
let qemu = QemuConfig::new();
|
||||
qemu.register();
|
||||
|
||||
let config = TomlConfig::load(content).unwrap();
|
||||
KataConfig::set_active_config(Some(config), "qemu", "agent0");
|
||||
|
||||
let mut anno_hash = HashMap::new();
|
||||
anno_hash.insert(
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_PHYSICAL_SECTOR_SIZE.to_string(),
|
||||
"256".to_string(),
|
||||
);
|
||||
let anno = Annotation::new(anno_hash);
|
||||
let mut config = TomlConfig::load(content).unwrap();
|
||||
assert!(anno.update_config_by_annotation(&mut config).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_block_device_sector_size_annotation_invalid_above_maximum() {
|
||||
let content = include_str!("texture/configuration-anno-0.toml");
|
||||
|
||||
let qemu = QemuConfig::new();
|
||||
qemu.register();
|
||||
|
||||
let config = TomlConfig::load(content).unwrap();
|
||||
KataConfig::set_active_config(Some(config), "qemu", "agent0");
|
||||
|
||||
let mut anno_hash = HashMap::new();
|
||||
anno_hash.insert(
|
||||
KATA_ANNO_CFG_HYPERVISOR_BLK_LOGICAL_SECTOR_SIZE.to_string(),
|
||||
"131072".to_string(),
|
||||
);
|
||||
let anno = Annotation::new(anno_hash);
|
||||
let mut config = TomlConfig::load(content).unwrap();
|
||||
assert!(anno.update_config_by_annotation(&mut config).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ default_maxvcpus = 64
|
||||
machine_type = "q35"
|
||||
confidential_guest = true
|
||||
rootless = true
|
||||
enable_annotations = ["shared_fs","path", "ctlpath","jailer_path","enable_iothreads","default_memory","memory_slots","enable_mem_prealloc","enable_hugepages","file_mem_backend","enable_virtio_mem","enable_guest_swap","default_vcpus","virtio_fs_extra_args","block_device_driver","vhost_user_store_path","kernel","guest_hook_path","block_device_cache_noflush","virtio_fs_daemon"]
|
||||
enable_annotations = ["shared_fs","path", "ctlpath","jailer_path","enable_iothreads","default_memory","memory_slots","enable_mem_prealloc","enable_hugepages","file_mem_backend","enable_virtio_mem","enable_guest_swap","default_vcpus","virtio_fs_extra_args","block_device_driver","vhost_user_store_path","kernel","guest_hook_path","block_device_cache_noflush","virtio_fs_daemon","blk_logical_sector_size","blk_physical_sector_size"]
|
||||
machine_accelerators="noapic"
|
||||
default_bridges = 2
|
||||
default_memory = 128
|
||||
|
||||
@@ -255,6 +255,16 @@ block_device_cache_direct = false
|
||||
# Default false
|
||||
block_device_cache_noflush = false
|
||||
|
||||
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_logical_sector_size = 0
|
||||
|
||||
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_physical_sector_size = 0
|
||||
|
||||
# Enable iothreads (data-plane) to be used. This causes IO to be
|
||||
# handled in a separate IO thread. This is currently only implemented
|
||||
# for SCSI.
|
||||
|
||||
@@ -245,6 +245,16 @@ block_device_cache_direct = false
|
||||
# Default false
|
||||
block_device_cache_noflush = false
|
||||
|
||||
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_logical_sector_size = 0
|
||||
|
||||
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_physical_sector_size = 0
|
||||
|
||||
# Enable iothreads (data-plane) to be used. This causes IO to be
|
||||
# handled in a separate IO thread. This is currently only implemented
|
||||
# for SCSI.
|
||||
|
||||
@@ -244,6 +244,16 @@ block_device_cache_direct = false
|
||||
# Default false
|
||||
block_device_cache_noflush = false
|
||||
|
||||
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_logical_sector_size = 0
|
||||
|
||||
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_physical_sector_size = 0
|
||||
|
||||
# Enable iothreads (data-plane) to be used. This causes IO to be
|
||||
# handled in a separate IO thread. This is currently only implemented
|
||||
# for SCSI.
|
||||
|
||||
@@ -281,6 +281,16 @@ block_device_cache_direct = false
|
||||
# Default false
|
||||
block_device_cache_noflush = false
|
||||
|
||||
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_logical_sector_size = 0
|
||||
|
||||
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_physical_sector_size = 0
|
||||
|
||||
# Enable iothreads (data-plane) to be used. This causes IO to be
|
||||
# handled in a separate IO thread. This is currently only implemented
|
||||
# for SCSI.
|
||||
|
||||
@@ -256,6 +256,16 @@ block_device_cache_direct = false
|
||||
# Default false
|
||||
block_device_cache_noflush = false
|
||||
|
||||
# Specifies the logical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_logical_sector_size = 0
|
||||
|
||||
# Specifies the physical sector size, in bytes, reported by block devices to the guest.
|
||||
# Common values are 512 and 4096. Set to 0 to use the QEMU/hypervisor default.
|
||||
# Default 0
|
||||
block_device_physical_sector_size = 0
|
||||
|
||||
# Enable iothreads (data-plane) to be used. This causes IO to be
|
||||
# handled in a separate IO thread. This is currently implemented
|
||||
# for virtio-scsi and virtio-blk.
|
||||
|
||||
@@ -112,6 +112,12 @@ pub struct BlockConfig {
|
||||
|
||||
/// block device multi-queue
|
||||
pub num_queues: usize,
|
||||
|
||||
/// Logical sector size in bytes reported to the guest. 0 means use hypervisor default.
|
||||
pub logical_sector_size: u32,
|
||||
|
||||
/// Physical sector size in bytes reported to the guest. 0 means use hypervisor default.
|
||||
pub physical_sector_size: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
|
||||
@@ -866,6 +866,8 @@ impl QemuInner {
|
||||
),
|
||||
block_device.config.is_readonly,
|
||||
block_device.config.no_drop,
|
||||
block_device.config.logical_sector_size,
|
||||
block_device.config.physical_sector_size,
|
||||
)
|
||||
.context("hotplug block device")?;
|
||||
|
||||
|
||||
@@ -642,6 +642,8 @@ impl Qmp {
|
||||
is_direct: Option<bool>,
|
||||
is_readonly: bool,
|
||||
no_drop: bool,
|
||||
logical_block_size: u32,
|
||||
physical_block_size: u32,
|
||||
) -> Result<(Option<PciPath>, Option<String>)> {
|
||||
// `blockdev-add`
|
||||
let node_name = format!("drive-{index}");
|
||||
@@ -719,6 +721,13 @@ impl Qmp {
|
||||
let mut blkdev_add_args = Dictionary::new();
|
||||
blkdev_add_args.insert("drive".to_owned(), node_name.clone().into());
|
||||
|
||||
if logical_block_size > 0 {
|
||||
blkdev_add_args.insert("logical_block_size".to_owned(), logical_block_size.into());
|
||||
}
|
||||
if physical_block_size > 0 {
|
||||
blkdev_add_args.insert("physical_block_size".to_owned(), physical_block_size.into());
|
||||
}
|
||||
|
||||
if block_driver == VIRTIO_SCSI {
|
||||
// Helper closure to decode a flattened u16 SCSI index into an (ID, LUN) pair.
|
||||
let get_scsi_id_lun = |index_u16: u16| -> Result<(u8, u8)> {
|
||||
|
||||
@@ -422,6 +422,8 @@ impl ResourceManagerInner {
|
||||
blkdev_aio: BlockDeviceAio::new(&blkdev_info.block_device_aio),
|
||||
num_queues: blkdev_info.num_queues,
|
||||
queue_size: blkdev_info.queue_size,
|
||||
logical_sector_size: blkdev_info.block_device_logical_sector_size,
|
||||
physical_sector_size: blkdev_info.block_device_physical_sector_size,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
|
||||
@@ -49,6 +49,8 @@ impl BlockVolume {
|
||||
blkdev_aio: BlockDeviceAio::new(&blkdev_info.block_device_aio),
|
||||
num_queues: blkdev_info.num_queues,
|
||||
queue_size: blkdev_info.queue_size,
|
||||
logical_sector_size: blkdev_info.block_device_logical_sector_size,
|
||||
physical_sector_size: blkdev_info.block_device_physical_sector_size,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@ impl RawblockVolume {
|
||||
blkdev_aio: BlockDeviceAio::new(&blkdev_info.block_device_aio),
|
||||
num_queues: blkdev_info.num_queues,
|
||||
queue_size: blkdev_info.queue_size,
|
||||
logical_sector_size: blkdev_info.block_device_logical_sector_size,
|
||||
physical_sector_size: blkdev_info.block_device_physical_sector_size,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user