From 89e4f1a23dbca42c3aae62ef12dc858d4f61c1b5 Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Fri, 23 Feb 2024 05:26:32 +0000 Subject: [PATCH] controller: implement automatic exit when process has exited --- controller/src/console.rs | 6 ++--- controller/src/ctl/console.rs | 29 +++++++++++++++++++--- libs/xen/xenstore/src/bus.rs | 45 ++++------------------------------- 3 files changed, 34 insertions(+), 46 deletions(-) diff --git a/controller/src/console.rs b/controller/src/console.rs index 3177eb3..f487c3e 100644 --- a/controller/src/console.rs +++ b/controller/src/console.rs @@ -5,7 +5,7 @@ use std::{ use anyhow::Result; use futures::future::join_all; -use log::warn; +use log::debug; use std::process::exit; use termion::raw::IntoRawMode; use tokio::{ @@ -34,7 +34,7 @@ impl XenConsole { let stdout = unsafe { File::from_raw_fd(terminal.as_raw_fd()) }; let reader_task = tokio::task::spawn(async move { if let Err(error) = XenConsole::copy_stdout(stdout, self.xen_read_handle).await { - warn!("failed to copy console output: {}", error); + debug!("failed to copy console output: {}", error); } }); let writer_task = tokio::task::spawn(async move { @@ -44,7 +44,7 @@ impl XenConsole { ) .await { - warn!("failed to intercept stdin: {}", error); + debug!("failed to intercept stdin: {}", error); } }); diff --git a/controller/src/ctl/console.rs b/controller/src/ctl/console.rs index 3a84d62..d162ab3 100644 --- a/controller/src/ctl/console.rs +++ b/controller/src/ctl/console.rs @@ -1,5 +1,11 @@ -use anyhow::{anyhow, Result}; +use std::{process::exit, time::Duration}; +use anyhow::{anyhow, Result}; +use log::warn; +use tokio::time::sleep; +use xenstore::client::XsdInterface; + +use super::destroy::ControllerDestroy; use crate::console::XenConsole; use super::ControllerContext; @@ -22,7 +28,24 @@ impl ControllerConsole<'_> { let domid = info.domid; let tty = self.context.xen.get_console_path(domid).await?; let console = XenConsole::new(&tty).await?; - console.attach().await?; - Ok(()) + + let dom_path = self.context.xen.store.get_domain_path(domid).await?; + + tokio::task::spawn(async move { + if let Err(error) = console.attach().await { + warn!("failed to attach to console: {}", error); + } + }); + + let exit_code_path = format!("{}/krata/guest/exit-code", dom_path); + loop { + let Some(code) = self.context.xen.store.read_string(&exit_code_path).await? else { + sleep(Duration::from_secs(1)).await; + continue; + }; + let mut destroy = ControllerDestroy::new(self.context); + destroy.perform(&domid.to_string()).await?; + exit(code.parse::()?); + } } } diff --git a/libs/xen/xenstore/src/bus.rs b/libs/xen/xenstore/src/bus.rs index fd1a5ad..a69d679 100644 --- a/libs/xen/xenstore/src/bus.rs +++ b/libs/xen/xenstore/src/bus.rs @@ -1,14 +1,11 @@ use crate::error::{Error, Result}; use crate::sys::{XsdMessageHeader, XSD_ERROR}; use std::ffi::CString; -use std::fs::{self, metadata, File}; +use std::fs::{metadata, File}; use std::io::{Read, Write}; use std::mem::size_of; -use std::os::unix::fs::FileTypeExt; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio::net::UnixStream; -const XEN_BUS_PATHS: &[&str] = &["/dev/xen/xenbus", "/var/run/xenstored/socket"]; +const XEN_BUS_PATHS: &[&str] = &["/dev/xen/xenbus"]; fn find_bus_path() -> Option { for path in XEN_BUS_PATHS { @@ -20,37 +17,16 @@ fn find_bus_path() -> Option { None } -#[async_trait::async_trait] -trait XsdTransport { - async fn xsd_write_all(&mut self, buf: &[u8]) -> Result<()>; - async fn xsd_read_exact(&mut self, buf: &mut [u8]) -> Result<()>; -} - -#[async_trait::async_trait] -impl XsdTransport for UnixStream { - async fn xsd_write_all(&mut self, buf: &[u8]) -> Result<()> { - Ok(self.write_all(buf).await?) - } - - async fn xsd_read_exact(&mut self, buf: &mut [u8]) -> Result<()> { - self.read_exact(buf).await?; - Ok(()) - } -} - pub struct XsdFileTransport { handle: File, } impl XsdFileTransport { - pub fn new(path: &str) -> Result { + fn new(path: &str) -> Result { let handle = File::options().read(true).write(true).open(path)?; Ok(XsdFileTransport { handle }) } -} -#[async_trait::async_trait] -impl XsdTransport for XsdFileTransport { async fn xsd_read_exact(&mut self, buf: &mut [u8]) -> Result<()> { Ok(self.handle.read_exact(buf)?) } @@ -63,7 +39,7 @@ impl XsdTransport for XsdFileTransport { } pub struct XsdSocket { - handle: Box, + handle: XsdFileTransport, } #[derive(Debug)] @@ -103,19 +79,8 @@ impl XsdSocket { Some(path) => path, None => return Err(Error::BusNotFound), }; - - let metadata = fs::metadata(&path)?; - let file_type = metadata.file_type(); - if file_type.is_socket() { - let stream = UnixStream::connect(&path).await?; - return Ok(XsdSocket { - handle: Box::new(stream), - }); - } let transport = XsdFileTransport::new(&path)?; - Ok(XsdSocket { - handle: Box::new(transport), - }) + Ok(XsdSocket { handle: transport }) } pub async fn send(&mut self, tx: u32, typ: u32, buf: &[u8]) -> Result {