summaryrefslogtreecommitdiff
path: root/9ns/build.zig
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-21 14:13:43 -0300
committerGabriel Schneider <[email protected]>2026-09-21 14:13:43 -0300
commit3a23f6a29e47ace901bd4d82b9db4055fcc12bb9 (patch)
treeb82d6e7c3ebe108434ce00ca75db59cf037917e0 /9ns/build.zig
parentf1b53c1533539aecbf16ad19fd9156deae091f92 (diff)
downloadcloud9-3a23f6a29e47ace901bd4d82b9db4055fcc12bb9.tar.gz
cloud9-3a23f6a29e47ace901bd4d82b9db4055fcc12bb9.zip
post registry + 9ns --mntgen: the /srv translation
cloud9.post: servers post their socket under a name in $XDG_RUNTIME_DIR/9p (post/unpost, posted, dial, Watch) and serve.Runner.listenPosted posts a server by name, unposting on stop. Names are budget-checked against the 108-byte socket path; a claim binds+listens at a private temp path and takes the name with atomic renames under flock (RENAME_NOREPLACE for free names, RENAME_EXCHANGE grab-verify-commit for stale ones): the registry path is never unlinked by a claim, live names refuse with AlreadyPosted, foreign files with NotSocket, and unpost removes only the caller's inode-matched entry. Watch surfaces inotify overflow and a replaced registry dir. 9ns --mntgen [--mount DIR] -- PROGRAM: one FUSE mount at /mnt/9p whose synthetic root lists the posted registry (no connection made); a walk into an unmounted name dials it and runs the existing bridge dispatch in a per-server worker thread, routed by mount index in the node id's top bits (ordinals never reused, cap 4096); a dead server answers EIO on its subtree and is re-dialed on the next walk. The dial watches stop_fd through Tversion (connectWatched). All existing 9ns forms are unchanged. 9proc's unix listener no longer blind-unlinks its path: a foreign non-socket is refused (Occupied), a live server is refused (AlreadyListening), only a refused socket is cleared, and stop() unlinks only the listener's own inode-matched socket. Hardened by adversarial review (GLM 5.3 x2 + DeepSeek V4.1 Flash, all high-thinking): double-bind races on one name (0 in 180k rounds), foreign-file TOCTOU deletions (0 in 4M flips), a 255-byte-name listing panic, inotify queue overflow silently dropped, listenPosted silently overwriting, dial-time Tversion hangs wedging the dispatcher, --debug silently ignored in mntgen, and xattr/statx probes answering EPERM on the synthetic root (broke `ls -l /mnt/9p`). Tests: root 80/80, 9ns 47/47, 9proc 60/60, integration 88/88 + mntgen 37/37, adversarial 213/0, freestanding riscv32 gate green.
Diffstat (limited to '9ns/build.zig')
-rw-r--r--9ns/build.zig6
1 files changed, 4 insertions, 2 deletions
diff --git a/9ns/build.zig b/9ns/build.zig
index 7f2155f..4e8d23b 100644
--- a/9ns/build.zig
+++ b/9ns/build.zig
@@ -52,7 +52,9 @@ pub fn add(b: *std.Build, ctx: Context) Artifacts {
test_step.dependOn(&b.addRunArtifact(b.addTest(.{ .root_module = ns_mod })).step);
// End-to-end suites: real namespaces, real FUSE, a real 9P server.
- const itest = b.step("9ns-itest", "Run 9ns/test/integration.sh (needs unprivileged user namespaces and /dev/fuse)");
+ // integration.sh: the single-connection transports; mntgen.sh: the
+ // posted-registry multi-server mode (registry servers + lazy dial).
+ const itest = b.step("9ns-itest", "Run 9ns/test/integration.sh and 9ns/test/mntgen.sh (needs unprivileged user namespaces and /dev/fuse)");
const adv = b.step("9ns-adv", "Run 9ns/test/adversarial.sh (hostile servers, namespaces, stress; several minutes)");
const demo = ctx.proc_demo orelse {
const fail = b.addFail("9ns-itest and 9ns-adv need the 9proc-demo server (build with -D9proc=true)");
@@ -60,7 +62,7 @@ pub fn add(b: *std.Build, ctx: Context) Artifacts {
adv.dependOn(&fail.step);
return .{ .exe = ns, .test_step = test_step, .itest_step = itest, .adv_step = adv };
};
- inline for (.{ .{ itest, "integration" }, .{ adv, "adversarial" } }) |pair| {
+ inline for (.{ .{ itest, "integration" }, .{ itest, "mntgen" }, .{ adv, "adversarial" } }) |pair| {
const run = b.addSystemCommand(&.{"bash"});
run.addFileArg(b.path("9ns/test/" ++ pair[1] ++ ".sh"));
run.addArtifactArg(ns);