runtime-rs: switch qemu child process management from std to tokio

We'll want to capture qemu's stderr in parallel with normal runtime-rs
execution.  Tokio's primitives make this much easier than std's.  This
also makes child process management more consistent across runtime-rs
(i.e. virtiofsd child process is already launched and managed using tokio).

Some changes were necessary due to tokio functions being slightly different
from their std counterparts.  Child::kill() is now async and Child::id()
now returns an Option.

Signed-off-by: Pavel Mores <pmores@redhat.com>
This commit is contained in:
Pavel Mores 2024-01-30 09:07:14 +01:00
parent b52a398469
commit 684d740122
2 changed files with 14 additions and 11 deletions

View File

@ -17,7 +17,7 @@ use kata_types::{
use persist::sandbox_persist::Persist; use persist::sandbox_persist::Persist;
use std::collections::HashMap; use std::collections::HashMap;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::process::Child; use tokio::process::{Child, Command};
const VSOCK_SCHEME: &str = "vsock"; const VSOCK_SCHEME: &str = "vsock";
@ -104,7 +104,7 @@ impl QemuInner {
//cmdline.add_serial_console("/dev/pts/23"); //cmdline.add_serial_console("/dev/pts/23");
info!(sl!(), "qemu args: {}", cmdline.build().await?.join(" ")); info!(sl!(), "qemu args: {}", cmdline.build().await?.join(" "));
let mut command = std::process::Command::new(&self.config.path); let mut command = Command::new(&self.config.path);
command.args(cmdline.build().await?); command.args(cmdline.build().await?);
info!(sl!(), "qemu cmd: {:?}", command); info!(sl!(), "qemu cmd: {:?}", command);
@ -113,11 +113,11 @@ impl QemuInner {
Ok(()) Ok(())
} }
pub(crate) fn stop_vm(&mut self) -> Result<()> { pub(crate) async fn stop_vm(&mut self) -> Result<()> {
info!(sl!(), "Stopping QEMU VM"); info!(sl!(), "Stopping QEMU VM");
if let Some(ref mut qemu_process) = &mut self.qemu_process { if let Some(ref mut qemu_process) = &mut self.qemu_process {
info!(sl!(), "QemuInner::stop_vm(): kill()'ing qemu"); info!(sl!(), "QemuInner::stop_vm(): kill()'ing qemu");
qemu_process.kill().map_err(anyhow::Error::from) qemu_process.kill().await.map_err(anyhow::Error::from)
} else { } else {
Err(anyhow!("qemu process not running")) Err(anyhow!("qemu process not running"))
} }
@ -164,12 +164,15 @@ impl QemuInner {
pub(crate) async fn get_vmm_master_tid(&self) -> Result<u32> { pub(crate) async fn get_vmm_master_tid(&self) -> Result<u32> {
info!(sl!(), "QemuInner::get_vmm_master_tid()"); info!(sl!(), "QemuInner::get_vmm_master_tid()");
if let Some(qemu_process) = &self.qemu_process { if let Some(qemu_process) = &self.qemu_process {
if let Some(qemu_pid) = qemu_process.id() {
info!( info!(
sl!(), sl!(),
"QemuInner::get_vmm_master_tid(): returning {}", "QemuInner::get_vmm_master_tid(): returning {}", qemu_pid
qemu_process.id()
); );
Ok(qemu_process.id()) Ok(qemu_pid)
} else {
Err(anyhow!("cannot get qemu pid (though it seems running)"))
}
} else { } else {
Err(anyhow!("qemu process not running")) Err(anyhow!("qemu process not running"))
} }

View File

@ -58,7 +58,7 @@ impl Hypervisor for Qemu {
async fn stop_vm(&self) -> Result<()> { async fn stop_vm(&self) -> Result<()> {
let mut inner = self.inner.write().await; let mut inner = self.inner.write().await;
inner.stop_vm() inner.stop_vm().await
} }
async fn pause_vm(&self) -> Result<()> { async fn pause_vm(&self) -> Result<()> {