From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from atuin.qyliss.net (localhost [IPv6:::1]) by atuin.qyliss.net (Postfix) with ESMTP id AEAA217117; Tue, 09 Dec 2025 12:56:17 +0000 (UTC) Received: by atuin.qyliss.net (Postfix, from userid 993) id B0768170A0; Tue, 09 Dec 2025 12:56:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on atuin.qyliss.net X-Spam-Level: X-Spam-Status: No, score=-0.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DMARC_MISSING,FILL_THIS_FORM,PP_MIME_FAKE_ASCII_TEXT, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS autolearn=unavailable autolearn_force=no version=4.0.1 Received: from fout-b6-smtp.messagingengine.com (fout-b6-smtp.messagingengine.com [202.12.124.149]) by atuin.qyliss.net (Postfix) with ESMTPS id 9E01016FEB for ; Tue, 09 Dec 2025 12:56:12 +0000 (UTC) Received: from phl-compute-11.internal (phl-compute-11.internal [10.202.2.51]) by mailfout.stl.internal (Postfix) with ESMTP id 1433D1D0013F; Tue, 9 Dec 2025 07:56:10 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-11.internal (MEProxy); Tue, 09 Dec 2025 07:56:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alyssa.is; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:message-id:mime-version:reply-to:subject:subject:to :to; s=fm3; t=1765284969; x=1765371369; bh=8mhIQBXoo6tXX3Au6YAiN YRCkBcbkKqVNUAy2fk9drM=; b=D1J6cdzyvRCl+Ngr/gxx144hCaYrlhULsFyZc f0ifJ3DJFSYFTzz/ENcNvRrD3mOrK16HFRuUggd0Bu28ZruMvna8LlXVTjVPkmX/ Sm4/85viei1Qj3nsivpVea4B4C/MCrhP/4oOrPOuWw1gSdYDqQvQRE2p4zALheu2 BAJY2F7aznBU/5/CI1+zAjWsXJHlB4c9HHKyyWDU8UKT2C8no0LsUncgZ2g5fs9F zbARhXPHPZr3Krbou7hoHXKH4qn7sl+HI8d5j1FN0tTEHRJqAO3NqR8aRi1nNlem Md1qIW8uPdTsrJeWTXlUoBhXFxIxMg/RYM0HxPo1QvwOeJH/A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:message-id:mime-version:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t= 1765284969; x=1765371369; bh=8mhIQBXoo6tXX3Au6YAiNYRCkBcbkKqVNUA y2fk9drM=; b=p+uaGv6NdFlRBdGCMSvv4p6Kzx+RDT/DNqZB2DkBrNvJPhlVnqT 5OcCwyzaMeLqqpskVYwpcOCd3e7jBv966gvWJHEVbRnJOlA16j4YSTdniC74qpBy pmBgYRv4n/sbp1eDMrb3cZcDjdJrCIK9wH4hT5O0WCp6Gbdo8p//QgJBmoy0J02c pImdRcOw21zmanSW3m4zbI/dI7tbZ+YfG/OsJB33Yl0M4fdrOmm3VeZ58xATLCWg vo3gzkfw7KOjxPPGmE7fXYbKZONUDzS58d5Va0aAnm4P5Awrh2WjhfxiAsICEvVU nkS/j/vNwmajbbhQVx+7ovrIICUmRNMCVRw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgdduleeivdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjug hrpefhvfevufffkffoggfgsedtkeertdertddtnecuhfhrohhmpeetlhihshhsrgcutfho shhsuceohhhisegrlhihshhsrgdrihhsqeenucggtffrrghtthgvrhhnpedvtedtfeffhf ekjeeivedtueehudetkeffhfejueeuuddvgeejvdekteekgfevveenucffohhmrghinhep shhpvggtthhruhhmqdhoshdrohhrghdpghhithhhuhgsrdgtohhmnecuvehluhhsthgvrh fuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhephhhisegrlhihshhsrgdrihhs pdhnsggprhgtphhtthhopeefpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopeihuh hrvghkrgestgihsggvrhgthhgrohhsrdguvghvpdhrtghpthhtohepuggvmhhiohgsvghn ohhurhesghhmrghilhdrtghomhdprhgtphhtthhopeguvghvvghlsehsphgvtghtrhhumh dqohhsrdhorhhg X-ME-Proxy: Feedback-ID: i12284293:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 9 Dec 2025 07:56:08 -0500 (EST) Received: by fw12.qyliss.net (Postfix, from userid 1000) id 01835604E9FB; Tue, 09 Dec 2025 13:55:56 +0100 (CET) From: Alyssa Ross To: devel@spectrum-os.org Subject: [PATCH v3 1/3] tools/router: use socket activation Date: Tue, 9 Dec 2025 13:54:41 +0100 Message-ID: <20251209125442.719952-2-hi@alyssa.is> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: PTYB6L4BPG4X2TRAZ4432W7MVFF4QJR6 X-Message-ID-Hash: PTYB6L4BPG4X2TRAZ4432W7MVFF4QJR6 X-MailFrom: hi@alyssa.is X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-devel.spectrum-os.org-0; header-match-devel.spectrum-os.org-1; header-match-devel.spectrum-os.org-2; header-match-devel.spectrum-os.org-3; header-match-devel.spectrum-os.org-4; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Yureka Lilian , Demi Marie Obenour X-Mailman-Version: 3.3.9 Precedence: list List-Id: Patches and low-level development discussion Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: This means we can use readiness notification to wait until the sockets are created without having to add special functionality for that to the router program, and also means we can do extra system-specific setup to the sockets, like changing their owners, outside of the router. Since the socket paths were the only arguments taken by the router, this also lets us drop the clap dependency entirely. Signed-off-by: Alyssa Ross --- v3: • use anyhow::bail • set sockets to non-blocking in router v2: https://spectrum-os.org/lists/archives/spectrum-devel/20251209110503.674499-2-hi@alyssa.is/ host/rootfs/file-list.mk | 1 + .../service/spectrum-router/notification-fd | 1 + .../spectrum-router/notification-fd.license | 2 + .../template/data/service/spectrum-router/run | 21 ++- tools/router/Cargo.lock | 148 ++++++++++++------ tools/router/Cargo.toml | 2 +- tools/router/src/main.rs | 40 +++-- 7 files changed, 141 insertions(+), 74 deletions(-) create mode 100644 host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/notification-fd create mode 100644 host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/notification-fd.license diff --git a/host/rootfs/file-list.mk b/host/rootfs/file-list.mk index df22bce8..5a043b7b 100644 --- a/host/rootfs/file-list.mk +++ b/host/rootfs/file-list.mk @@ -28,6 +28,7 @@ FILES = \ image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/dbus/notification-fd \ image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/dbus/run \ image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/down \ + image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/notification-fd \ image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/run \ image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-fs/notification-fd \ image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-fs/run \ diff --git a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/notification-fd b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/notification-fd new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/notification-fd @@ -0,0 +1 @@ +5 diff --git a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/notification-fd.license b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/notification-fd.license new file mode 100644 index 00000000..0d3d47ca --- /dev/null +++ b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/notification-fd.license @@ -0,0 +1,2 @@ +SPDX-License-Identifier: CC0-1.0 +SPDX-FileCopyrightText: 2025 Alyssa Ross diff --git a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/run b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/run index 3ba35def..dc1ef900 100755 --- a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/run +++ b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/spectrum-router/run @@ -1,14 +1,30 @@ #!/bin/execlineb -P # SPDX-License-Identifier: EUPL-1.2+ # SPDX-FileCopyrightText: 2025 Yureka Lilian +# SPDX-FileCopyrightText: 2025 Alyssa Ross importas -i VM VM +s6-ipcserver-socketbinder -a 0770 /run/vm/by-id/${VM}/router-driver.sock +fdmove -c 3 0 + +s6-ipcserver-socketbinder -a 0770 /run/vm/by-id/${VM}/router-app.sock +fdmove -c 4 0 + +# Notify readiness. +if { + fdmove -c 5 1 + echo +} + +redirfd -r 0 /dev/null + bwrap --unshare-all --unshare-user --dev-bind / / --setenv RUST_LOG spectrum-router=debug,info + --setenv LISTEN_FDS 2 --tmpfs /tmp --dev /dev --tmpfs /dev/shm @@ -19,6 +35,7 @@ bwrap --ro-bind /lib /lib --bind /run/vm/by-id/${VM} /run/vm/by-id/${VM} -- + +getpid LISTEN_PID + spectrum-router - --app-listen-path /run/vm/by-id/${VM}/router-app.sock - --driver-listen-path /run/vm/by-id/${VM}/router-driver.sock diff --git a/tools/router/Cargo.lock b/tools/router/Cargo.lock index 60d7657b..d0d105aa 100644 --- a/tools/router/Cargo.lock +++ b/tools/router/Cargo.lock @@ -113,6 +113,12 @@ dependencies = [ "wyz", ] +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + [[package]] name = "bytes" version = "1.11.0" @@ -120,44 +126,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] -name = "clap" -version = "4.5.53" +name = "cfg-if" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "colorchoice" @@ -263,12 +235,6 @@ dependencies = [ "slab", ] -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -299,12 +265,33 @@ dependencies = [ "syn", ] +[[package]] +name = "js-sys" +version = "0.3.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "libc" version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +[[package]] +name = "listenfd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b87bc54a4629b4294d0b3ef041b64c40c611097a677d9dc07b2c67739fe39dba" +dependencies = [ + "libc", + "uuid", + "winapi", +] + [[package]] name = "log" version = "0.4.28" @@ -328,6 +315,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + [[package]] name = "once_cell_polyfill" version = "1.70.2" @@ -420,6 +413,12 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + [[package]] name = "serde_core" version = "1.0.228" @@ -462,9 +461,9 @@ version = "0.1.0" dependencies = [ "anyhow", "arrayvec", - "clap", "env_logger", "futures-util", + "listenfd", "log", "tokio", "tokio-stream", @@ -474,12 +473,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "syn" version = "2.0.111" @@ -608,6 +601,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "uuid" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "vhost-device-net" version = "0.1.1" @@ -666,6 +669,51 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +[[package]] +name = "wasm-bindgen" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +dependencies = [ + "unicode-ident", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/tools/router/Cargo.toml b/tools/router/Cargo.toml index 0b969113..cfdf3527 100644 --- a/tools/router/Cargo.toml +++ b/tools/router/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" [dependencies] anyhow = "1.0.100" -clap = { version = "4.5.45", features = ["derive"] } env_logger = "0.11.8" log = { version = "0.4.27", features = ["release_max_level_debug"] } vhost-device-net = "0.1.0" @@ -19,3 +18,4 @@ tokio-stream = "0.1.17" arrayvec = "0.7.6" vm-memory = "0.16" tokio-util = "0.7.17" +listenfd = "1.0.2" diff --git a/tools/router/src/main.rs b/tools/router/src/main.rs index e3aca65a..3b26ddb0 100644 --- a/tools/router/src/main.rs +++ b/tools/router/src/main.rs @@ -1,47 +1,45 @@ // SPDX-License-Identifier: EUPL-1.2+ // SPDX-FileCopyrightText: 2025 Yureka Lilian +// SPDX-FileCopyrightText: 2025 Alyssa Ross pub(crate) mod packet; pub(crate) mod protocol; mod router; mod upstream; -use std::path::PathBuf; - use packet::*; use router::{InterfaceId, Router}; use upstream::Upstream; -use clap::Parser; +use anyhow::bail; use futures_util::{SinkExt, TryStreamExt}; +use listenfd::ListenFd; use log::{error, info}; use tokio::net::UnixListener; use vhost_device_net::{IncomingPacket, VhostDeviceNet}; use vm_memory::GuestMemoryMmap; -#[derive(Parser, Debug)] -#[command()] //version = None, about = None, long_about = None)] -struct Args { - #[arg(long)] - driver_listen_path: PathBuf, - #[arg(long)] - app_listen_path: PathBuf, -} - fn main() -> anyhow::Result<()> { env_logger::init(); - let args = Args::parse(); - for path in [&args.driver_listen_path, &args.app_listen_path] { - let _ = std::fs::remove_file(path); - } - - run_router(args) + run_router() } #[tokio::main(flavor = "current_thread")] -async fn run_router(args: Args) -> anyhow::Result<()> { - let app_listener = UnixListener::bind(&args.app_listen_path)?; - let driver_listener = UnixListener::bind(&args.driver_listen_path)?; +async fn run_router() -> anyhow::Result<()> { + let mut listenfd = ListenFd::from_env(); + + let Some(driver_listener) = listenfd.take_unix_listener(0)? else { + bail!("not activated with driver socket"); + }; + let Some(app_listener) = listenfd.take_unix_listener(1)? else { + bail!("not activated with app socket"); + }; + + driver_listener.set_nonblocking(true)?; + app_listener.set_nonblocking(true)?; + + let driver_listener = UnixListener::from_std(driver_listener)?; + let app_listener = UnixListener::from_std(app_listener)?; let mut router = Router::::new(InterfaceId::Upstream); -- 2.51.0