runtime-rs: Add ccw block device for rootfs

Like nvdimm for x86_64, a block device for s390x should be
treated differently with `virtio-blk-ccw`.
This is to generate a QEMU command line parameter for a block
device by using `-blockdev` and `-device` if the `vm_rootfs_driver`
is set to `virtio-blk-ccw`.

Signed-off-by: Hyounggyu Choi <Hyounggyu.Choi@ibm.com>
This commit is contained in:
Hyounggyu Choi 2024-03-21 08:38:04 +01:00
parent 9b2c08935b
commit 9bcfaad625
5 changed files with 169 additions and 4 deletions

View File

@ -14,8 +14,8 @@ use tokio::sync::{Mutex, RwLock};
use crate::{
vhost_user_blk::VhostUserBlkDevice, BlockConfig, BlockDevice, HybridVsockDevice, Hypervisor,
NetworkDevice, ShareFsDevice, VfioDevice, VhostUserConfig, VhostUserNetDevice, VsockDevice,
KATA_BLK_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE, KATA_NVDIMM_DEV_TYPE, VIRTIO_BLOCK_MMIO,
VIRTIO_BLOCK_PCI, VIRTIO_PMEM,
KATA_BLK_DEV_TYPE, KATA_CCW_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE, KATA_NVDIMM_DEV_TYPE,
VIRTIO_BLOCK_CCW, VIRTIO_BLOCK_MMIO, VIRTIO_BLOCK_PCI, VIRTIO_PMEM,
};
use super::{
@ -447,6 +447,9 @@ impl DeviceManager {
VIRTIO_BLOCK_PCI => {
block_config.driver_option = KATA_BLK_DEV_TYPE.to_string();
}
VIRTIO_BLOCK_CCW => {
block_config.driver_option = KATA_CCW_DEV_TYPE.to_string();
}
VIRTIO_PMEM => {
block_config.driver_option = KATA_NVDIMM_DEV_TYPE.to_string();
is_pmem = true;

View File

@ -20,8 +20,8 @@ pub use vfio::{
pub use vhost_user::{VhostUserConfig, VhostUserDevice, VhostUserType};
pub use vhost_user_net::VhostUserNetDevice;
pub use virtio_blk::{
BlockConfig, BlockDevice, KATA_BLK_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE, KATA_NVDIMM_DEV_TYPE,
VIRTIO_BLOCK_MMIO, VIRTIO_BLOCK_PCI, VIRTIO_PMEM,
BlockConfig, BlockDevice, KATA_BLK_DEV_TYPE, KATA_CCW_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE,
KATA_NVDIMM_DEV_TYPE, VIRTIO_BLOCK_CCW, VIRTIO_BLOCK_MMIO, VIRTIO_BLOCK_PCI, VIRTIO_PMEM,
};
pub use virtio_fs::{
ShareFsConfig, ShareFsDevice, ShareFsMountConfig, ShareFsMountOperation, ShareFsMountType,

View File

@ -15,9 +15,11 @@ use async_trait::async_trait;
/// VIRTIO_BLOCK_PCI indicates block driver is virtio-pci based
pub const VIRTIO_BLOCK_PCI: &str = "virtio-blk-pci";
pub const VIRTIO_BLOCK_MMIO: &str = "virtio-blk-mmio";
pub const VIRTIO_BLOCK_CCW: &str = "virtio-blk-ccw";
pub const VIRTIO_PMEM: &str = "virtio-pmem";
pub const KATA_MMIO_BLK_DEV_TYPE: &str = "mmioblk";
pub const KATA_BLK_DEV_TYPE: &str = "blk";
pub const KATA_CCW_DEV_TYPE: &str = "ccw";
pub const KATA_NVDIMM_DEV_TYPE: &str = "nvdimm";
#[derive(Debug, Clone, Default)]

View File

@ -651,6 +651,154 @@ impl ToQemuParams for DeviceNvdimm {
}
}
#[derive(Debug)]
struct BlockBackend {
driver: String,
id: String,
path: String,
aio: String,
cache_direct: bool,
cache_no_flush: bool,
read_only: bool,
}
impl BlockBackend {
fn new(id: &str, path: &str) -> BlockBackend {
BlockBackend {
driver: "file".to_owned(),
id: id.to_owned(),
path: path.to_owned(),
aio: "threads".to_owned(),
cache_direct: true,
cache_no_flush: false,
read_only: true,
}
}
#[allow(dead_code)]
fn set_driver(&mut self, driver: &str) -> &mut Self {
self.driver = driver.to_owned();
self
}
#[allow(dead_code)]
fn set_aio(&mut self, aio: &str) -> &mut Self {
self.aio = aio.to_owned();
self
}
#[allow(dead_code)]
fn set_cache_direct(&mut self, cache_direct: bool) -> &mut Self {
self.cache_direct = cache_direct;
self
}
#[allow(dead_code)]
fn set_cache_no_flush(&mut self, cache_no_flush: bool) -> &mut Self {
self.cache_no_flush = cache_no_flush;
self
}
#[allow(dead_code)]
fn set_read_only(&mut self, read_only: bool) -> &mut Self {
self.read_only = read_only;
self
}
}
#[async_trait]
impl ToQemuParams for BlockBackend {
async fn qemu_params(&self) -> Result<Vec<String>> {
let mut params = Vec::new();
params.push(format!("driver={}", self.driver));
params.push(format!("node-name=image-{}", self.id));
params.push(format!("filename={}", self.path));
params.push(format!("aio={}", self.aio));
if self.cache_direct {
params.push("cache.direct=on".to_owned());
} else {
params.push("cache.direct=off".to_owned());
}
if self.cache_no_flush {
params.push("cache.no-flush=on".to_owned());
} else {
params.push("cache.no-flush=off".to_owned());
}
if self.read_only {
params.push("auto-read-only=on".to_owned());
} else {
params.push("auto-read-only=off".to_owned());
}
Ok(vec!["-blockdev".to_owned(), params.join(",")])
}
}
#[derive(Debug)]
struct DeviceVirtioBlk {
bus_type: VirtioBusType,
id: String,
scsi: bool,
config_wce: bool,
share_rw: bool,
}
impl DeviceVirtioBlk {
fn new(id: &str, bus_type: VirtioBusType) -> DeviceVirtioBlk {
DeviceVirtioBlk {
bus_type,
id: id.to_owned(),
scsi: false,
config_wce: false,
share_rw: true,
}
}
#[allow(dead_code)]
fn set_scsi(&mut self, scsi: bool) -> &mut Self {
self.scsi = scsi;
self
}
#[allow(dead_code)]
fn set_config_wce(&mut self, config_wce: bool) -> &mut Self {
self.config_wce = config_wce;
self
}
#[allow(dead_code)]
fn set_share_rw(&mut self, share_rw: bool) -> &mut Self {
self.share_rw = share_rw;
self
}
}
#[async_trait]
impl ToQemuParams for DeviceVirtioBlk {
async fn qemu_params(&self) -> Result<Vec<String>> {
let mut params = Vec::new();
params.push(format!("virtio-blk-{}", self.bus_type));
params.push(format!("drive=image-{}", self.id));
if self.scsi {
params.push("scsi=on".to_owned());
} else {
params.push("scsi=off".to_owned());
}
if self.config_wce {
params.push("config-wce=on".to_owned());
} else {
params.push("config-wce=off".to_owned());
}
if self.share_rw {
params.push("share-rw=on".to_owned());
} else {
params.push("share-rw=off".to_owned());
}
params.push(format!("serial=image-{}", self.id));
Ok(vec!["-device".to_owned(), params.join(",")])
}
}
struct VhostVsock {
bus_type: VirtioBusType,
vhostfd: RawFd,
@ -894,6 +1042,14 @@ impl<'a> QemuCmdLine<'a> {
Ok(())
}
pub fn add_block_device(&mut self, device_id: &str, path: &str) -> Result<()> {
self.devices
.push(Box::new(BlockBackend::new(device_id, path)));
self.devices
.push(Box::new(DeviceVirtioBlk::new(device_id, self.bus_type())));
Ok(())
}
#[allow(dead_code)]
pub fn add_serial_console(&mut self, character_device_file_path: &str) {
let serial = Serial::new(character_device_file_path);

View File

@ -103,6 +103,10 @@ impl QemuInner {
&block_dev.config.path_on_host,
block_dev.config.is_readonly,
)?,
"ccw" => cmdline.add_block_device(
block_dev.device_id.as_str(),
&block_dev.config.path_on_host,
)?,
unsupported => {
info!(sl!(), "unsupported block device driver: {}", unsupported)
}