From 8cdd96809235f9150ecfd263a6d1ed8d940ce8b7 Mon Sep 17 00:00:00 2001 From: Pavel Mores Date: Fri, 11 Oct 2024 16:45:57 +0200 Subject: [PATCH] runtime-rs: support virtio-scsi device in qemu-rs Semantics are lifted straight out of the go runtime for compatibility. We introduce DeviceVirtioScsi to represent a virtio-scsi device and instantiate it if block device driver in the configuration file is set to virtio-scsi. We also introduce ObjectIoThread which is instantiated if the configuration file additionally enables iothreads. Signed-off-by: Pavel Mores --- .../hypervisor/src/qemu/cmdline_generator.rs | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs index b8d0ea6e845b..7e7e32812499 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs @@ -8,6 +8,7 @@ use crate::{kernel_param::KernelParams, Address, HypervisorConfig}; use anyhow::{anyhow, Context, Result}; use async_trait::async_trait; +use kata_types::config::hypervisor::VIRTIO_SCSI; use std::collections::HashMap; use std::fmt::Display; use std::fs::{read_to_string, File}; @@ -1513,6 +1514,66 @@ impl ToQemuParams for QmpSocket { } } +#[derive(Debug)] +struct DeviceVirtioScsi { + bus_type: VirtioBusType, + id: String, + disable_modern: bool, + iothread: String, +} + +impl DeviceVirtioScsi { + fn new(id: &str, disable_modern: bool, bus_type: VirtioBusType) -> Self { + DeviceVirtioScsi { + bus_type, + id: id.to_owned(), + disable_modern, + iothread: "".to_owned(), + } + } + + fn set_iothread(&mut self, iothread: &str) { + self.iothread = iothread.to_owned(); + } +} + +#[async_trait] +impl ToQemuParams for DeviceVirtioScsi { + async fn qemu_params(&self) -> Result> { + let mut params = Vec::new(); + params.push(format!("virtio-scsi-{}", self.bus_type)); + params.push(format!("id={}", self.id)); + if self.disable_modern { + params.push("disable-modern=true".to_owned()); + } + if !self.iothread.is_empty() { + params.push(format!("iothread={}", self.iothread)); + } + Ok(vec!["-device".to_owned(), params.join(",")]) + } +} + +#[derive(Debug)] +struct ObjectIoThread { + id: String, +} + +impl ObjectIoThread { + fn new(id: &str) -> Self { + ObjectIoThread { id: id.to_owned() } + } +} + +#[async_trait] +impl ToQemuParams for ObjectIoThread { + async fn qemu_params(&self) -> Result> { + let mut params = Vec::new(); + params.push("iothread".to_owned()); + params.push(format!("id={}", self.id)); + Ok(vec!["-object".to_owned(), params.join(",")]) + } +} + fn is_running_in_vm() -> Result { let res = read_to_string("/proc/cpuinfo")? .lines() @@ -1596,6 +1657,10 @@ impl<'a> QemuCmdLine<'a> { qemu_cmd_line.add_bridges(config.device_info.default_bridges); } + if config.blockdev_info.block_device_driver == VIRTIO_SCSI { + qemu_cmd_line.add_scsi_controller(); + } + Ok(qemu_cmd_line) } @@ -1637,6 +1702,18 @@ impl<'a> QemuCmdLine<'a> { } } + fn add_scsi_controller(&mut self) { + let mut virtio_scsi = + DeviceVirtioScsi::new("scsi0", should_disable_modern(), bus_type(self.config)); + if self.config.enable_iothreads { + let iothread_id = "scsi-io-thread"; + let iothread = ObjectIoThread::new(iothread_id); + virtio_scsi.set_iothread(iothread_id); + self.devices.push(Box::new(iothread)); + } + self.devices.push(Box::new(virtio_scsi)); + } + pub fn add_virtiofs_share( &mut self, virtiofsd_socket_path: &str,