diff --git a/Cargo.lock b/Cargo.lock index b596cec..0537202 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -869,6 +869,7 @@ dependencies = [ "serde", "serde_json", "tokio", + "tokio-util", "toml", "tracing", "tracing-subscriber", diff --git a/Cargo.toml b/Cargo.toml index cedfdbd..762f05f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ uucore = { version = "0.5.0", features = ["utmpx"] } zlink = { version = "0.3.0", features = ["introspection"] } clap_complete = "4.5.65" itertools = "0.14.0" +tokio-util = "0.7.18" [features] default = ["systemd"] diff --git a/nix/module.nix b/nix/module.nix index dd56b01..74143b1 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -56,6 +56,7 @@ in { systemd.services.roowho2 = { serviceConfig = { + Type = "notify"; ExecStart = "${lib.getExe' cfg.package "roowhod"} --config ${format.generate "roowho2-config.toml" cfg.settings}"; Restart = "on-failure"; DynamicUser = true; diff --git a/src/bin/roowhod.rs b/src/bin/roowhod.rs index b782b59..731888f 100644 --- a/src/bin/roowhod.rs +++ b/src/bin/roowhod.rs @@ -8,6 +8,7 @@ use std::{ use anyhow::Context; use clap::Parser; use tokio::{net::UdpSocket, sync::RwLock}; +use tokio_util::sync::CancellationToken; use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt}; use roowho2_lib::server::{ @@ -64,6 +65,16 @@ async fn main() -> anyhow::Result<()> { let whod_status_store = Arc::new(RwLock::new(HashMap::new())); + let client_server_token = CancellationToken::new(); + let client_server_token_ = client_server_token.clone(); + tokio::spawn(async move { + client_server_token_.cancelled().await; + tracing::info!("RWHOD client-server is now accepting connections"); + #[cfg(feature = "systemd")] + sd_notify::notify(true, &[sd_notify::NotifyState::Ready]).ok(); + Ok::<(), anyhow::Error>(()) + }); + if config.rwhod.enable { tracing::info!("Starting RWHOD server"); @@ -89,6 +100,7 @@ async fn main() -> anyhow::Result<()> { .try_clone() .context("Failed to clone RWHOD client-server socket fd")?, whod_status_store.clone(), + client_server_token, )); join_set.spawn(ctrl_c_handler()); @@ -126,6 +138,7 @@ async fn rwhod_server( async fn client_server( socket_fd: OwnedFd, whod_status_store: RwhodStatusStore, + startup_token: CancellationToken, ) -> anyhow::Result<()> { // SAFETY: see above let std_socket = @@ -134,6 +147,8 @@ async fn client_server( let zlink_listener = zlink::unix::Listener::try_from(OwnedFd::from(std_socket))?; let client_server_task = varlink_client_server_task(zlink_listener, whod_status_store); + startup_token.cancel(); + client_server_task.await?; Ok(())