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 950c38fafa..3e3a919ff9 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/cmdline_generator.rs @@ -528,13 +528,11 @@ impl ChardevSocket { } } - #[allow(dead_code)] fn set_server(&mut self, server: bool) -> &mut Self { self.server = server; self } - #[allow(dead_code)] fn set_wait(&mut self, wait: bool) -> &mut Self { self.wait = wait; self @@ -556,6 +554,8 @@ impl ToQemuParams for ChardevSocket { params.push("server=on".to_owned()); if self.wait { params.push("wait=on".to_owned()); + } else { + params.push("wait=off".to_owned()); } } params.append(&mut self.protocol_options.qemu_params().await?); @@ -911,6 +911,57 @@ impl ToQemuParams for NetDevice { } } +#[derive(Debug)] +struct DeviceVirtioSerial { + id: String, + bus_type: VirtioBusType, +} + +impl DeviceVirtioSerial { + fn new(id: &str, bus_type: VirtioBusType) -> DeviceVirtioSerial { + DeviceVirtioSerial { + id: id.to_owned(), + bus_type, + } + } +} + +#[async_trait] +impl ToQemuParams for DeviceVirtioSerial { + async fn qemu_params(&self) -> Result> { + let mut params = Vec::new(); + params.push(format!("virtio-serial-{}", self.bus_type)); + params.push(format!("id={}", self.id)); + Ok(vec!["-device".to_owned(), params.join(",")]) + } +} + +#[derive(Debug)] +struct DeviceVirtconsole { + id: String, + chardev: String, +} + +impl DeviceVirtconsole { + fn new(id: &str, chardev: &str) -> DeviceVirtconsole { + DeviceVirtconsole { + id: id.to_owned(), + chardev: chardev.to_owned(), + } + } +} + +#[async_trait] +impl ToQemuParams for DeviceVirtconsole { + async fn qemu_params(&self) -> Result> { + let mut params = Vec::new(); + params.push("virtconsole".to_owned()); + params.push(format!("id={}", self.id)); + params.push(format!("chardev={}", self.chardev)); + Ok(vec!["-device".to_owned(), params.join(",")]) + } +} + fn is_running_in_vm() -> Result { let res = read_to_string("/proc/cpuinfo")? .lines() @@ -1098,6 +1149,23 @@ impl<'a> QemuCmdLine<'a> { Ok(fds) } + pub fn add_console(&mut self, console_socket_path: &str) { + let serial_dev = DeviceVirtioSerial::new("serial0", self.bus_type()); + self.devices.push(Box::new(serial_dev)); + + let chardev_name = "charconsole0"; + let console_device = DeviceVirtconsole::new("console0", chardev_name); + self.devices.push(Box::new(console_device)); + + let mut console_socket_chardev = ChardevSocket::new(chardev_name); + console_socket_chardev.set_socket_opts(ProtocolOptions::Unix(UnixSocketOpts { + path: console_socket_path.to_owned(), + })); + console_socket_chardev.set_server(true); + console_socket_chardev.set_wait(false); + self.devices.push(Box::new(console_socket_chardev)); + } + pub async fn build(&self) -> Result> { let mut result = Vec::new(); diff --git a/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs b/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs index 23c9bc7ab8..310f75c710 100644 --- a/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs +++ b/src/runtime-rs/crates/hypervisor/src/qemu/inner.rs @@ -18,6 +18,7 @@ use kata_types::{ use persist::sandbox_persist::Persist; use std::collections::HashMap; use std::os::unix::io::AsRawFd; +use std::path::Path; use std::process::Stdio; use tokio::{ io::{AsyncBufReadExt, BufReader}, @@ -128,6 +129,10 @@ impl QemuInner { // `tty` in it to get its device file path and use it as the argument). //cmdline.add_serial_console("/dev/pts/23"); + // Add a console to the devices of the cmdline + let console_socket_path = Path::new(&self.get_jailer_root().await?).join("console.sock"); + cmdline.add_console(console_socket_path.to_str().unwrap()); + info!(sl!(), "qemu args: {}", cmdline.build().await?.join(" ")); let mut command = Command::new(&self.config.path); command.args(cmdline.build().await?);