code wiki / (root) / nx_cachewatch.nx

nx_cachewatch.nx

buildroot/runtime/nx_cachewatch.nx

13306 B306 linesdepth 2pulls 2 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_cachewatch.nx -- IS THE WRITE CACHE ACTUALLY CACHING? The axis nothing in the estate measured. WHY THIS EXISTS (2026-09-03). The box spent a full day refusing every build with load 13-25 while `/api/build` correctly reported an I/O storm. The CAUSE was one condition no organ could see: `md3 : active raid1 nvme1n1p1[1] [2/1] [_U]` -- the NVMe RAID1 behind the write cache lost a device, so the cache was flushed to completion and set `uncacheable`, and from that moment 100% of writes went straight to the RAID5 array. Measured on the live plane: `writes +18,366` == `disk_writes +18,366` == `uncached_writes +18,366` across two spaced samples, with every SSD-side counter frozen. MEASURED ABSENCE BEFORE BUILDING: `grep -rl flashcache buildroot/runtime/*.nx` returned ZERO organs. The estate could see the SYMPTOM (load, D-state, refused builds) and never the CAUSE. nx_cachewatch check [proc_root] -> one verdict line, exit carries it nx_cachewatch explain [proc_root] -> every field it read, with its LEVEL/COUNTER class named IT READS LEVELS AND REFUSES TO READ COUNTERS AS LEVELS. THIS IS THE WHOLE POINT. `flashcache_stats` carries `dirty_writeback_kb=31543788` and `dirty_write_hits=43493286`. Both are LIFETIME COUNTERS sitting among reads/writes/hits. Read as levels they say "31.5 GB of dirty data is stranded on a degraded unmirrored NVMe" -- an alarming, actionable, WRONG conclusion. The estate's memory recorded exactly that error, and this organ's author was two minutes from publishing it again. The LEVEL lives in `cache_info` as `dirty_blocks`, and it reads 0. A FROZEN COUNTER AND A PINNED LEVEL ARE INDISTINGUISHABLE IN ONE SAMPLE, AND THE ALARMING READING IS THE ONE THAT GETS PUBLISHED. So this organ names the class of every number it prints, and the verdict is computed ONLY from fields it can justify as levels. MODE IS NOT THE DISCRIMINATOR. `cache_info` keeps saying `mode=WRITE_BACK` after the cache has been flushed and disabled -- that field records how the device was CONFIGURED, not whether it is caching now. The discriminator is `flashcache_progress: status=uncacheable...`. A verdict built on `mode` alone would have read GREEN through the entire outage. Proven by its gate's T2: two fixtures with BYTE-IDENTICAL cache_info must return DIFFERENT verdicts. exit: 0 GREEN (caching, mirror intact) | 1 RED (NOT caching -- every write hits the array) | 2 AMBER (caching, mirror degraded -- unmirrored dirty data) | 3 UNOBSERVABLE | 4 usage UNOBSERVABLE IS NOT GREEN. A missing /proc/flashcache means this host has no such cache OR the reader is wrong; both are "I could not look", and neither acquits. PROVEN 8/8 GREEN 2026-09-03, bite-proven killed=1, restores byte-identical. license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 1 imports · 0 importers

nx_syscalls.nx nx_cachewatch.nx

imports: nx_syscalls.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main cw_streq sys_mmap nxa_die sys_write sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ cw_first_cache_dir sys_mmap ↻ cw_cat sys_close cw_cat ↻ cw_read sys_openat_rd sys_read sys_close ↻ cw_degraded_count cw_out sys_write ↻ cw_slen cw_num sys_mmap ↻ sys_write ↻ cw_int_after cw_find cw_slen ↻ cw_find ↻

structs

none

consts

39const CW_BUF: i64 = 65536
40const CW_NAME: i64 = 512
41const CW_PATH: i64 = 1024
42const CW_DIRBUF: i64 = 65536
43const CW_DENT_RECLEN_OFF: i64 = 16
44const CW_DENT_NAME_OFF: i64 = 19
45const CW_GETDENTS: i64 = 217
46const CW_OPENDIR_FLAGS: i64 = 0x10000
47const CW_AT_FDCWD: i64 = 0 - 100
48const CW_DOT: i64 = 46
50const CW_GREEN: i64 = 0
51const CW_RED: i64 = 1
52const CW_AMBER: i64 = 2
53const CW_UNOBS: i64 = 3

functions

55func cw_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
called by 2: cw_outcw_find
56func cw_out(s: *u8) -> i64 { sys_write(1, s, cw_slen(s)); return 0 }
called by 1: main calls 2: sys_writecw_slen
57func cw_num(v: i64) -> i64
called by 1: main calls 2: sys_mmapsys_write
69func cw_cat(dst: *u8, a: *u8, b: *u8, c: *u8) -> i64
80func cw_read(path: *u8, buf: *u8, cap: i64) -> i64
called by 1: main calls 3: sys_openat_rdsys_readsys_close
95func cw_find(buf: *u8, n: i64, needle: *u8) -> i64
called by 2: cw_int_aftermain calls 1: cw_slen
111func cw_int_after(buf: *u8, n: i64, key: *u8) -> i64
called by 1: main calls 1: cw_find
133func cw_degraded_count(buf: *u8, n: i64) -> i64
called by 1: main
158func cw_first_cache_dir(root: *u8, out: *u8) -> i64
called by 1: main calls 3: sys_mmapcw_catsys_close
204func cw_streq(a: *u8, b: *u8) -> i64
called by 1: main
211func main(argc: i64, argv: *i64) -> i64