code wiki / (root) / nx_vsz_watchdog_gate.nx

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}