diff --git a/src/daemon/config.rs b/src/daemon/config.rs new file mode 100644 index 0000000..0a3fb73 --- /dev/null +++ b/src/daemon/config.rs @@ -0,0 +1,12 @@ +/* + * Copyright © 2023 Collabora Ltd. + * Copyright © 2024 Valve Software + * + * SPDX-License-Identifier: MIT + */ + +use anyhow::Result; + +pub(in crate::daemon) async fn read_config() -> Result<()> { + todo!(); +} diff --git a/src/daemon/mod.rs b/src/daemon/mod.rs index 1c42947..dcabd90 100644 --- a/src/daemon/mod.rs +++ b/src/daemon/mod.rs @@ -6,7 +6,7 @@ */ use anyhow::{anyhow, ensure, Result}; -use tokio::signal::unix::{signal, Signal, SignalKind}; +use tokio::signal::unix::{signal, SignalKind}; use tokio::task::JoinSet; use tokio_util::sync::CancellationToken; use tracing::{error, info}; @@ -14,9 +14,11 @@ use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::registry::LookupSpan; use zbus::connection::Connection; +use crate::daemon::config::read_config; use crate::sls::{LogLayer, LogReceiver}; -use crate::{reload, Service}; +use crate::Service; +mod config; mod root; mod user; @@ -26,8 +28,6 @@ pub use user::daemon as user; pub(crate) struct Daemon { services: JoinSet>, token: CancellationToken, - sigterm: Signal, - sigquit: Signal, } impl Daemon { @@ -43,24 +43,18 @@ impl Daemon { let subscriber = subscriber.with(remote_logger); tracing::subscriber::set_global_default(subscriber)?; - let sigterm = signal(SignalKind::terminate())?; - let sigquit = signal(SignalKind::quit())?; - - let mut daemon = Daemon { - services, - token, - sigterm, - sigquit, - }; + let mut daemon = Daemon { services, token }; daemon.add_service(log_receiver); Ok(daemon) } - pub(crate) fn add_service(&mut self, service: S) { - let token = self.token.clone(); + pub(crate) fn add_service(&mut self, service: S) -> CancellationToken { + let token = self.token.child_token(); + let moved_token = token.clone(); self.services - .spawn(async move { service.start(token).await }); + .spawn(async move { service.start(moved_token).await }); + token } pub(crate) async fn run(&mut self) -> Result<()> { @@ -69,18 +63,39 @@ impl Daemon { "Can't run a daemon with no services attached." ); - let mut res = tokio::select! { - e = self.services.join_next() => match e.unwrap() { - Ok(Ok(())) => Ok(()), - Ok(Err(e)) => Err(e), - Err(e) => Err(e.into()) - }, - _ = tokio::signal::ctrl_c() => Ok(()), - e = self.sigterm.recv() => e.ok_or(anyhow!("SIGTERM machine broke")), - _ = self.sigquit.recv() => Err(anyhow!("Got SIGQUIT")), - e = reload() => e, - } - .inspect_err(|e| error!("Encountered error running: {e}")); + let mut res = loop { + let mut sigterm = signal(SignalKind::terminate())?; + let mut sigquit = signal(SignalKind::quit())?; + let mut sighup = signal(SignalKind::hangup())?; + + let res = tokio::select! { + e = self.services.join_next() => match e.unwrap() { + Ok(Ok(())) => Ok(()), + Ok(Err(e)) => Err(e), + Err(e) => Err(e.into()) + }, + _ = tokio::signal::ctrl_c() => break Ok(()), + e = sigterm.recv() => match e { + Some(_) => Ok(()), + None => Err(anyhow!("SIGTERM machine broke")), + }, + e = sighup.recv() => match e { + Some(_) => { + if let Err(error) = read_config().await { + error!("Failed to reload configuration: {error}"); + } + Ok(()) + } + None => Err(anyhow!("SIGHUP machine broke")), + }, + _ = sigquit.recv() => Err(anyhow!("Got SIGQUIT")), + } + .inspect_err(|e| error!("Encountered error running: {e}")); + match res { + Ok(()) => continue, + r => break r, + } + }; self.token.cancel(); info!("Shutting down"); diff --git a/src/lib.rs b/src/lib.rs index 6cc9e04..b0a1827 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,6 @@ use std::future::Future; use std::path::{Path, PathBuf}; use tokio::fs::File; use tokio::io::AsyncWriteExt; -use tokio::signal::unix::{signal, SignalKind}; use tokio_util::sync::CancellationToken; use tracing::{info, warn}; @@ -123,16 +122,6 @@ pub(crate) fn get_appid(pid: u32) -> Result> { } } -async fn reload() -> Result<()> { - loop { - let mut sighup = signal(SignalKind::hangup())?; - sighup - .recv() - .await - .ok_or(anyhow!("SIGHUP handler failed!"))?; - } -} - #[cfg(test)] mod test { use crate::testing;