runtime-rs: Add DeviceVirtioSerial and DeviceVirtconsole

It is observed that virtiofsd exits immediately on s390x
if there is no attached console devices.
This commit resolves the issue by migrating `appendConsole()`
from runtime and being triggered in `start_vm()`.

Signed-off-by: Hyounggyu Choi <Hyounggyu.Choi@ibm.com>
This commit is contained in:
Hyounggyu Choi 2024-02-28 08:33:54 +01:00
parent 2cfe745efb
commit 81aaa34bd6
2 changed files with 75 additions and 2 deletions

View File

@ -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<Vec<String>> {
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<Vec<String>> {
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<bool> {
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<Vec<String>> {
let mut result = Vec::new();

View File

@ -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?);