Runtime, Reloading & Systemd
Dynamic credential, CA bundle & peers reloading
Section titled “Dynamic credential, CA bundle & peers reloading”When federation is configured (--peers-file, --fed-cert, --fed-key), xmsg serve reloads
certificates, CA bundles, and peers.json without dropping active connections:
- Periodic SHA-256 polling &
SIGHUP: Every--fed-reload-interval-secs(default30seconds,XMSG_FED_RELOAD_INTERVAL_SECS) — or immediately upon receivingSIGHUP—xmsgchecks the SHA-256 content hashes of--fed-cert,--fed-key,--peers-file, and each peer’scabundle. Content hashing detects atomic symlink swaps (such as Kubernetes..dataSecret rotations) even when symlinkmtimedoes not change. - Atomic swap & fail-closed validation:
xmsgbuilds and validates the complete new TLS acceptor, client credentials, private key match, peer map, and CA trust anchors before swapping. If any file is invalid or mismatched, the reload is aborted, an error is logged, and the previous active configuration stays in service uninterrupted. - Per-request policy re-evaluation: Existing HTTP/1.1 keep-alive connections on
/fed/v2/*re-verify peer membership (current_peers()) and source-IP CIDR policy (from) on every request. In-flight long-polls complete on their pre-reload snapshot (bounded by the 30–60 s wait timeout) before re-evaluating on the next poll.
Systemd socket activation & sd_notify
Section titled “Systemd socket activation & sd_notify”xmsg serve supports Type=notify-reload (ReloadSignal=SIGHUP) and socket activation under
systemd (src/systemd.rs):
- Socket activation (
LISTEN_FDS,LISTEN_PID,LISTEN_FDNAMES): WhenLISTEN_PIDmatchesxmsg serve’s PID andLISTEN_FDS >= 1,xmsgadopts inherited descriptors starting at FD3(SD_LISTEN_FDS_START) and marks eachFD_CLOEXEC. Descriptors are matched by canonicalLISTEN_FDNAMESslot names:fed(--fed-listen)listen(--listen)agent(--agent-sock)register(--register-sock/--leaf-register-sock)http(--http-sock) WhenLISTEN_FDS=1andLISTEN_FDNAMESis unset, the single descriptor is assigned to the sole configured TCP listener (--fed-listenor--listen). Any unknown, duplicate, or unconfigured slot, non-stream/non-listening socket, or bound address/path mismatch fails closed at startup.
- Readiness & reload notifications (
NOTIFY_SOCKET):- Sends
READY=1only after all configured listeners are bound (or adopted) and accepting connections. - Brackets every post-startup reload with
RELOADING=1\nMONOTONIC_USEC=<usec>followed byREADY=1(orREADY=1\nSTATUS=reload failed: <reason>when a reload fails and retains the previous configuration, orREADY=1\nSTATUS=nothing to reloadwhenSIGHUParrives without federation configured). - Sends
STOPPING=1whenSIGTERMorSIGINTinitiates graceful shutdown.
- Sends
Persisted state & SQLite schema version
Section titled “Persisted state & SQLite schema version”The SQLite database (--db-path, default $XDG_STATE_HOME/xmsg/xmsg.db or
~/.local/state/xmsg/xmsg.db) records its schema version in PRAGMA user_version (currently
version 3):
- Version 3: Opened in place, preserving all queued messages, stored replies,
instance_claims, idempotency keys,peer_mailbox, andforwarded_messagesacross restarts. - Below version 3: Message state tables are dropped and recreated at version 3 in a single
transaction while preserving
instance_claims. - Above version 3: Refused at startup naming both versions so a downgrade never corrupts newer
state. To roll back across a schema bump, back up
xmsg.dbbefore upgrading.
Building & verification
Section titled “Building & verification”# Run Rust test suitecargo test --all-targets
# Run Clippy lints and rustfmt checkcargo clippy --all-targets -- -D warningscargo fmt -- --check
# Run shared service client checks & mutation suitecargo test --locked --no-default-features --features client --test shared_clientpython3 scripts/client-graph.pypython3 scripts/client-mutants.py
# Build Nix default package and OCI imagenix build .#default --no-linknix build .#image --no-linknix build -L .#checks.x86_64-linux.image --no-link
# Run full Nix CI suite (module eval, agy/codex hooks, pi/opencode/hermes plugins, shared-client-compat)nix flake check ./ciPalettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).