krata: fix guest destruction

This commit is contained in:
Alex Zenla
2024-03-30 03:49:13 +00:00
parent d659b3aa55
commit da9e6cac14
12 changed files with 103 additions and 122 deletions

View File

@ -79,10 +79,11 @@ impl ChannelService {
async fn process(&mut self) -> Result<()> {
self.scan_all_backends().await?;
let mut watch_handle = self.store.create_watch().await?;
self.store
.bind_watch(&watch_handle, "/local/domain/0/backend/console".to_string())
let mut watch_handle = self
.store
.create_watch("/local/domain/0/backend/console")
.await?;
self.store.bind_watch(&watch_handle).await?;
loop {
select! {
x = watch_handle.receiver.recv() => match x {
@ -310,10 +311,11 @@ impl KrataChannelBackendProcessor {
mut receiver: Receiver<Vec<u8>>,
) -> Result<()> {
self.init().await?;
let mut frontend_state_change = self.store.create_watch().await?;
self.store
.bind_watch(&frontend_state_change, format!("{}/state", self.frontend))
let mut frontend_state_change = self
.store
.create_watch(format!("{}/state", self.frontend))
.await?;
self.store.bind_watch(&frontend_state_change).await?;
let (ring_ref, port) = loop {
match frontend_state_change.receiver.recv().await {
@ -382,10 +384,11 @@ impl KrataChannelBackendProcessor {
}
};
let mut self_state_change = self.store.create_watch().await?;
self.store
.bind_watch(&self_state_change, format!("{}/state", self.backend))
let mut self_state_change = self
.store
.create_watch(format!("{}/state", self.backend))
.await?;
self.store.bind_watch(&self_state_change).await?;
loop {
select! {
x = self_state_change.receiver.recv() => match x {

View File

@ -7,15 +7,11 @@ use std::{
use anyhow::{anyhow, Result};
use ipnetwork::IpNetwork;
use log::error;
use loopdev::LoopControl;
use tokio::{
sync::{mpsc::Sender, Mutex},
task::JoinHandle,
};
use tokio::sync::Mutex;
use uuid::Uuid;
use xenclient::XenClient;
use xenstore::{XsdClient, XsdInterface, XsdWatchHandle};
use xenstore::{XsdClient, XsdInterface};
use self::{
autoloop::AutoLoop,
@ -30,7 +26,7 @@ pub mod channel;
pub mod console;
pub mod launch;
pub struct ContainerLoopInfo {
pub struct GuestLoopInfo {
pub device: String,
pub file: String,
pub delete: Option<String>,
@ -45,7 +41,7 @@ pub struct GuestInfo {
pub uuid: Uuid,
pub domid: u32,
pub image: String,
pub loops: Vec<ContainerLoopInfo>,
pub loops: Vec<GuestLoopInfo>,
pub guest_ipv4: Option<IpNetwork>,
pub guest_ipv6: Option<IpNetwork>,
pub guest_mac: Option<String>,
@ -231,7 +227,7 @@ impl RuntimeContext {
Ok(None)
}
fn parse_loop_set(input: &Option<String>) -> Vec<ContainerLoopInfo> {
fn parse_loop_set(input: &Option<String>) -> Vec<GuestLoopInfo> {
let Some(input) = input else {
return Vec::new();
};
@ -242,7 +238,7 @@ impl RuntimeContext {
.map(|x| (x[0].clone(), x[1].clone(), x[2].clone()))
.collect::<Vec<(String, String, String)>>();
sets.iter()
.map(|(device, file, delete)| ContainerLoopInfo {
.map(|(device, file, delete)| GuestLoopInfo {
device: device.clone(),
file: file.clone(),
delete: if delete == "none" {
@ -251,7 +247,7 @@ impl RuntimeContext {
Some(delete.clone())
},
})
.collect::<Vec<ContainerLoopInfo>>()
.collect::<Vec<GuestLoopInfo>>()
}
}
@ -276,29 +272,6 @@ impl Runtime {
launcher.launch(&mut context, request).await
}
pub async fn subscribe_exit_code(
&self,
uuid: Uuid,
sender: Sender<(Uuid, i32)>,
) -> Result<JoinHandle<()>> {
let mut context = self.context.lock().await;
let info = context
.resolve(uuid)
.await?
.ok_or_else(|| anyhow!("unable to resolve guest: {}", uuid))?;
let path = format!("/local/domain/{}/krata/guest/exit-code", info.domid);
let handle = context.xen.store.create_watch().await?;
context.xen.store.bind_watch(&handle, &path).await?;
let watch = ExitCodeWatch {
handle,
sender,
store: context.xen.store.clone(),
uuid,
path,
};
watch.launch().await
}
pub async fn destroy(&self, uuid: Uuid) -> Result<Uuid> {
let mut context = self.context.lock().await;
let info = context
@ -372,44 +345,3 @@ fn path_as_string(path: &Path) -> Result<String> {
.ok_or_else(|| anyhow!("unable to convert path to string"))
.map(|x| x.to_string())
}
struct ExitCodeWatch {
store: XsdClient,
handle: XsdWatchHandle,
uuid: Uuid,
sender: Sender<(Uuid, i32)>,
path: String,
}
impl ExitCodeWatch {
pub async fn launch(mut self) -> Result<JoinHandle<()>> {
Ok(tokio::task::spawn(async move {
if let Err(error) = self.process().await {
error!("failed to watch exit for guest {}: {}", self.uuid, error);
}
}))
}
async fn process(&mut self) -> Result<()> {
loop {
match self.handle.receiver.recv().await {
Some(_) => {
let exit_code_string = self.store.read_string(&self.path).await?;
if let Some(exit_code) = exit_code_string.and_then(|x| i32::from_str(&x).ok()) {
match self.sender.try_send((self.uuid, exit_code)) {
Ok(_) => {}
Err(error) => {
return Err(error.into());
}
}
return Ok(());
}
}
None => {
return Ok(());
}
}
}
}
}