From: Alyssa Ross <hi@alyssa.is>
To: devel@spectrum-os.org
Cc: Yureka Lilian <yureka@cyberchaos.dev>,
Demi Marie Obenour <demiobenour@gmail.com>
Subject: [PATCH v3 1/3] tools/router: use socket activation
Date: Tue, 9 Dec 2025 13:54:41 +0100 [thread overview]
Message-ID: <20251209125442.719952-2-hi@alyssa.is> (raw)
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 13458 bytes --]
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 <hi@alyssa.is>
---
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 <hi@alyssa.is>
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 <yureka@cyberchaos.dev>
+# SPDX-FileCopyrightText: 2025 Alyssa Ross <hi@alyssa.is>
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 <yureka@cyberchaos.dev>
+// SPDX-FileCopyrightText: 2025 Alyssa Ross <hi@alyssa.is>
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::<GuestMemoryMmap>::new(InterfaceId::Upstream);
--
2.51.0
next reply other threads:[~2025-12-09 12:56 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-09 12:54 Alyssa Ross [this message]
2025-12-09 12:54 ` [PATCH v3 2/3] host/rootfs: put router app sockets in own dir Alyssa Ross
2025-12-14 0:13 ` Alyssa Ross
2025-12-09 12:54 ` [PATCH v3 3/3] host/rootfs: run router as non-root Alyssa Ross
2025-12-14 0:13 ` Alyssa Ross
2025-12-14 0:13 ` [PATCH v3 1/3] tools/router: use socket activation Alyssa Ross
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251209125442.719952-2-hi@alyssa.is \
--to=hi@alyssa.is \
--cc=demiobenour@gmail.com \
--cc=devel@spectrum-os.org \
--cc=yureka@cyberchaos.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://spectrum-os.org/git/crosvm
https://spectrum-os.org/git/doc
https://spectrum-os.org/git/mktuntap
https://spectrum-os.org/git/nixpkgs
https://spectrum-os.org/git/spectrum
https://spectrum-os.org/git/ucspi-vsock
https://spectrum-os.org/git/www
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).