From 0c11744c50f997b4718eea70a78e347ab4c03335 Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Tue, 6 Feb 2024 06:19:36 +0000 Subject: [PATCH] hypha: protect from panics in the network stack (due to interface going away) --- hypha/bin/controller.rs | 9 ++------- hypha/src/network/mod.rs | 25 ++++++++++++++++++++++--- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/hypha/bin/controller.rs b/hypha/bin/controller.rs index b8e1268..51b04a9 100644 --- a/hypha/bin/controller.rs +++ b/hypha/bin/controller.rs @@ -110,15 +110,10 @@ fn main() -> Result<()> { Commands::List { .. } => { let containers = controller.list()?; let mut table = cli_tables::Table::new(); - let header = vec!["domain", "uuid", "ipv4", "image"]; + let header = vec!["uuid", "ipv4", "image"]; table.push_row(&header)?; for container in containers { - let row = vec![ - container.domid.to_string(), - container.uuid.to_string(), - container.ipv4, - container.image, - ]; + let row = vec![container.uuid.to_string(), container.ipv4, container.image]; table.push_row_string(&row)?; } diff --git a/hypha/src/network/mod.rs b/hypha/src/network/mod.rs index 4ad7909..6c650f0 100644 --- a/hypha/src/network/mod.rs +++ b/hypha/src/network/mod.rs @@ -1,7 +1,8 @@ use std::os::fd::AsRawFd; +use std::panic::UnwindSafe; use std::str::FromStr; -use std::thread; use std::time::Duration; +use std::{panic, thread}; use advmac::MacAddr6; use anyhow::{anyhow, Result}; @@ -21,6 +22,7 @@ pub struct NetworkBackend { } unsafe impl Send for NetworkBackend {} +impl UnwindSafe for NetworkBackend {} pub struct NetworkService { pub network: String, @@ -66,10 +68,25 @@ impl NetworkBackend { } let link = link.unwrap(); handle.link().set(link.header.index).up().execute().await?; + tokio::time::sleep(Duration::from_secs(3)).await; Ok(()) } - pub fn run(&mut self) -> Result<()> { + pub fn run(mut self) -> Result<()> { + let interface = self.interface.clone(); + let result = panic::catch_unwind(move || self.run_maybe_panic()); + + if result.is_err() { + return Err(anyhow!( + "network backend for interface {} encountered an error and is now shutdown", + interface + )); + } + + result.unwrap() + } + + fn run_maybe_panic(&mut self) -> Result<()> { let mac = MacAddr6::random(); let mac = HardwareAddress::Ethernet(EthernetAddress(mac.to_array())); let config = Config::new(mac); @@ -128,14 +145,16 @@ impl NetworkService { spawned.push(name); } - sleep(Duration::from_secs(5)).await; + sleep(Duration::from_secs(2)).await; } } async fn add_network_backend(&mut self, interface: &str) -> Result<()> { let interface = interface.to_string(); let mut network = NetworkBackend::new(&interface, &[&self.network])?; + info!("initializing network backend for interface {}", interface); network.init().await?; + tokio::time::sleep(Duration::from_secs(1)).await; info!("spawning network backend for interface {}", interface); thread::spawn(move || { if let Err(error) = network.run() {