nx_vsz_watchdog_gate.nx source
↩ module page · 95 lines · 5328 B
1// nx_vsz_watchdog_gate.nx -- gate for the VSZ-watchdog CORE (outage MODE 2 permanent fix). Teeth: conf-row
2// parsing (comment/blank/malformed/zero-gb all DROPPED fail-safe), VmSize parse from a real-format status
3// fixture, the kill decision (below-threshold / unknown-vsz / cooldown-active all -> NO KILL; only sane+over+
4// cooled -> kill), needle containment, and LIVE /proc/self reads (selfpid>0, own VmSize>0). The CLI's walk+kill
5// is deliberately NOT exercised here (killing real pids in a gate = reckless); the live kill path is proven
6// on the NAS against a synthetic mmap-pig. license_tier: ORIGINAL expect_exit: 0
7import "nx_syscalls.nx"
8import "nx_vsz_watchdog_core.nx"
9
10func g_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
11func g_putn(v: i64) -> i64 {
12 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
13 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m }
14 let d: *u8 = sys_mmap(24); var k: i64 = 0
15 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
16 let o: *u8 = sys_mmap(24); var wi: i64 = 0
17 while wi < k { o[wi] = d[k-1-wi]; wi = wi + 1 }
18 sys_write(1, o, k)
19 return 0
20}
21func g_chk(st: *i64, ok: i64, label: *u8) -> i64 {
22 if ok == 1 { st[0] = st[0] + 1; g_puts(" PASS " as *u8) } else { st[1] = st[1] + 1; g_puts(" FAIL " as *u8) }
23 g_puts(label); g_puts("\n" as *u8)
24 return 0
25}
26func g_scpy(dst: *u8, src: *u8) -> i64 { var i: i64 = 0; while src[i] != (0 as u8) { dst[i] = src[i]; i = i + 1 } dst[i] = 0 as u8; return i }
27
28func main() -> i64 {
29 let st: *i64 = sys_mmap(32) as *i64; st[0] = 0; st[1] = 0
30 g_puts("=== nx_vsz_watchdog_gate: MODE-2 permanent fix core (decide-death-only, fail-safe) ===\n\n" as *u8)
31 let rp: *i64 = sys_mmap(16) as *i64
32 let buf: *u8 = sys_mmap(4096)
33
34 // T1 conf row parse: valid row -> needle NUL'd in place + gb
35 var n: i64 = g_scpy(buf, "nx_mgmt_api.elf 32" as *u8)
36 var gb: i64 = vw_parse_row(buf, 0, n, rp)
37 var ok: i64 = 0
38 if gb == 32 { if rp[0] == 0 { if vw_slen((buf as i64 + rp[0]) as *u8) == 15 { ok = 1 } } }
39 g_chk(st, ok, "T1 row parse: needle+gb extracted, needle NUL-terminated in place" as *u8)
40
41 // T2 fail-safe rows: comment / blank / no-gb / gb=0 ALL dropped
42 ok = 1
43 n = g_scpy(buf, "# a comment 99" as *u8)
44 if vw_parse_row(buf, 0, n, rp) != (0 - 1) { ok = 0 }
45 n = g_scpy(buf, " " as *u8)
46 if vw_parse_row(buf, 0, n, rp) != (0 - 1) { ok = 0 }
47 n = g_scpy(buf, "lonely_needle" as *u8)
48 if vw_parse_row(buf, 0, n, rp) != (0 - 1) { ok = 0 }
49 n = g_scpy(buf, "name 0" as *u8)
50 if vw_parse_row(buf, 0, n, rp) != (0 - 1) { ok = 0 }
51 g_chk(st, ok, "T2 comment/blank/no-gb/zero-gb rows all DROPPED (fail-safe, no 0-threshold kill)" as *u8)
52
53 // T3 VmSize parse from a real-format status fixture
54 n = g_scpy(buf, "Name:\tnx_mgmt_api.el\nUmask:\t0022\nState:\tS (sleeping)\nVmPeak:\t167980148 kB\nVmSize:\t167980148 kB\nVmRSS:\t 182792 kB\n" as *u8)
55 ok = 0
56 if vw_vmsize_parse(buf, n) == 167980148 { ok = 1 }
57 g_chk(st, ok, "T3 VmSize parse from status fixture = 167980148 kB (the real 160GB incident value)" as *u8)
58
59 // T4 VmSize absent -> -1 (never kill on parse failure)
60 n = g_scpy(buf, "Name:\tx\nState:\tS\n" as *u8)
61 ok = 0
62 if vw_vmsize_parse(buf, n) == (0 - 1) { ok = 1 }
63 g_chk(st, ok, "T4 status without VmSize -> -1 (no kill on unknown)" as *u8)
64
65 // T5 the kill decision: ONLY sane+over+cooled kills
66 ok = 1
67 if vw_should_kill(167980148, 32, 0, 100000, 600) != 1 { ok = 0 } // 160GB > 32GB, cooled -> KILL
68 if vw_should_kill(4204152, 32, 0, 100000, 600) != 0 { ok = 0 } // 4.2GB fresh -> no
69 if vw_should_kill(167980148, 32, 99700, 100000, 600) != 0 { ok = 0 } // cooldown active (300s ago) -> no
70 if vw_should_kill(0 - 1, 32, 0, 100000, 600) != 0 { ok = 0 } // vsz unknown -> no
71 if vw_should_kill(167980148, 0, 0, 100000, 600) != 0 { ok = 0 } // insane threshold -> no
72 g_chk(st, ok, "T5 kill decision: over+cooled=KILL; fresh/cooldown/unknown/bad-threshold=NO" as *u8)
73
74 // T6 containment: needle in a NUL-separated cmdline; absent needle -> 0
75 let cl: *u8 = sys_mmap(128)
76 var o: i64 = g_scpy(cl, "./nx_mgmt_api.elf" as *u8)
77 cl[o] = 0 as u8
78 let o2: i64 = o + 1 + g_scpy((cl as i64 + o + 1) as *u8, "18098" as *u8)
79 ok = 0
80 if vw_contains(cl, o2, "nx_mgmt_api.elf" as *u8, 15) == 1 { if vw_contains(cl, o2, "zzz_not_there" as *u8, 13) == 0 { ok = 1 } }
81 g_chk(st, ok, "T6 cmdline containment across NUL-separated argv; absent needle -> 0" as *u8)
82
83 // T7 LIVE /proc: selfpid > 0 and own VmSize > 0
84 let sp: i64 = vw_selfpid()
85 let kb: i64 = vw_vmsize_kb_of("self" as *u8)
86 g_puts(" (live: selfpid=" as *u8); g_putn(sp); g_puts(" own VmSize kB=" as *u8); g_putn(kb); g_puts(")\n" as *u8)
87 ok = 0
88 if sp > 0 { if kb > 0 { ok = 1 } }
89 g_chk(st, ok, "T7 LIVE /proc/self: pid + VmSize both read (real kernel format)" as *u8)
90
91 g_puts("\nPASS=" as *u8); g_putn(st[0]); g_puts(" FAIL=" as *u8); g_putn(st[1]); g_puts("\n" as *u8)
92 if st[1] > 0 { g_puts("GATE RED\n" as *u8); return 1 }
93 g_puts("GATE GREEN -- decide-death core fail-safe; live kill path proven separately vs the NAS mmap-pig\n" as *u8)
94 return 0
95}