nx_motion_smoke.nx source
↩ module page · 47 lines · 2795 B
1// nx_motion_smoke.nx -- DIAGNOSE AND GATE THE /motion DAEMON'S LISTEN (2026-09-06, rung MO14 core).
2// The deploy health probe reports NEVER-LISTENED but hides the daemon's OWN stderr, and a daemon cannot be
3// nx_job_run (jlb_denied) to capture it. This oneshot forks the daemon BINARY on a throwaway port with a
4// bounded watchdog (gk_run_capture_ms kills it at the deadline), captures its stdout+stderr, and reports
5// whether it bound -- so 'does the daemon listen' becomes a runnable, gateable check instead of a deploy gamble.
6// nx_motion_smoke [elf] [port] elf defaults to ./nx_motion_serve.elf.new, port to a throwaway 28139
7// exit: 0 LISTENED | 3 BIND-FAILED (port taken / bind refused) | 4 NO-OUTPUT (crashed before printing)
8// Its name carries no control-plane stem, so the async launcher admits it; it binds nothing itself.
9// license_tier: ORIGINAL expect_exit: 0
10import "nx_syscalls.nx"
11import "nx_gatekit_lib.nx"
12
13const SM_CAP: i64 = 65536
14const SM_MS: i64 = 2500
15
16func smw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
17func smn(v: i64) -> i64 {
18 let b: *u8 = sys_mmap(32)
19 var x: i64 = v
20 if x < 0 { b[0] = 45 as u8; sys_write(1, b, 1); x = 0 - x }
21 if x == 0 { b[0] = 48 as u8; sys_write(1, b, 1); return 0 }
22 var d: i64 = 0
23 var y: i64 = x
24 while y > 0 { d = d + 1; y = y / 10 }
25 var i: i64 = d
26 while i > 0 { i = i - 1; b[i] = ((x % 10) + 48) as u8; x = x / 10 }
27 sys_write(1, b, d)
28 return 0
29}
30func main(argc: i64, argv: *i64) -> i64 {
31 var elf: *u8 = "./nx_motion_serve.elf.new" as *u8
32 if argc >= 2 { elf = argv[1] as *u8 }
33 var port: *u8 = "28139" as *u8
34 if argc >= 3 { port = argv[2] as *u8 }
35 let buf: *u8 = sys_mmap(SM_CAP)
36 let ol: *i64 = sys_mmap(16) as *i64
37 ol[0] = 0
38 let rc: i64 = gk_run_capture_ms(elf, port, 0 as *u8, 0 as *u8, 0 as *u8, SM_MS, buf, SM_CAP, ol)
39 smw("MOTION-SMOKE elf=" as *u8); smw(elf); smw(" port=" as *u8); smw(port); smw(" ms=" as *u8); smn(SM_MS); smw(" rc=" as *u8); smn(rc); smw(" out_bytes=" as *u8); smn(ol[0]); smw("\n" as *u8)
40 smw("---- daemon stdout+stderr ----\n" as *u8)
41 if ol[0] > 0 { sys_write(1, buf, ol[0]) }
42 smw("\n---- end ----\n" as *u8)
43 if gk_out_has(buf, ol[0], "listening on loopback" as *u8) == 1 { smw("VERDICT=LISTENED -- the daemon binds; a NEVER-LISTENED deploy is the health-probe edge under load, not this binary\n" as *u8); return 0 }
44 if gk_out_has(buf, ol[0], "LISTEN-FAILED" as *u8) == 1 { smw("VERDICT=BIND-FAILED -- the port was taken or bind refused; the daemon printed its own reason above\n" as *u8); return 3 }
45 smw("VERDICT=NO-OUTPUT -- the daemon printed nothing before the deadline (crashed before listen, or output lost)\n" as *u8)
46 return 4
47}