nx_node_beacon.nx
buildroot/runtime/nx_node_beacon.nx
about
nx_node_beacon.nx -- SOVEREIGN per-node resource beacon: the swarm MONITOR keystone.
Reads LIVE /proc utilization with BOUNDED reads (openat + single read + close) and NEVER
sys_read_file -- that call mmaps 4 GiB PER CALL and never frees, which is the documented
supervisor-ENOMEM F-class root (nx_hostctl.nx:311). A beacon is fork-per-pass and short-lived,
so its mmaps free on exit; the bounded reader keeps a single pass cheap regardless.
Composes proven prior art: the /proc parsers from nx_sysload (loadavg/meminfo/conns), the
bounded reader idiom from nx_zombie_audit (za_readfile), and the record assembly helpers from
nx_framed_append (fa_cat/fa_catn/fa_len).
EMITS one POSITIONAL row the mgmt-API /api/nodes emitter parses (mirrors the SVC-row shape):
NODE <name> <cpu_pct> <load_milli> <ncpu> <load_per_core_milli> <mem_used_pct> \
<mem_avail_mb> <mem_total_mb> <conns8443> <ts_us> <temp_mc> <batt_pct>
v2 (SF-R1, swarm-fabric energy groundwork): temp_mc (max millidegC across /sys/class/thermal
zones) + batt_pct (/sys/class/power_supply/BAT*/capacity) APPENDED so the v1 positional prefix
is unchanged (rule 19 additive contract). -1 = source absent on this host (e.g. WSL VM exposes
no thermal/battery) -- honest-absent, never fabricated.
Run:
nx_node_beacon -> SELF-GATE: sample local /proc, print row + verdict, exit 0
nx_node_beacon <name> <path> -> write the NODE row (labelled <name>) to <path> (the snapshot
/api/nodes reads) AND echo it to stdout for hostctl capture
license_tier: ORIGINAL
dependencies 2 imports · 0 importers
imports: nx_syscalls.nxnx_framed_append.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 27 | const NB_MAGIC_1024: i64 = 1024 |
| 28 | const NB_MAGIC_150000: i64 = 150000 |
| 30 | const NB_ROW_CAP: i64 = 512 |
| 31 | const NB_SMALL: i64 = 8192 |
| 32 | const NB_BIG: i64 = 262144 |
| 33 | const NB_CPU_GAP_MS: i64 = 200 |
functions
| 36 | func nb_readproc(path: *u8, buf: *u8, cap: i64) -> i64 |
| 46 | func nb_skip_sp(buf: *u8, n: i64, p: i64) -> i64 |
| 59 | func nb_pdec(buf: *u8, n: i64, p: i64, pend: *i64) -> i64 |
| 74 | func nb_count_sub(buf: *u8, n: i64, needle: *u8, nl: i64) -> i64 |
| 89 | func nb_find_after(buf: *u8, n: i64, key: *u8, klen: i64) -> i64 called by 1: nb_meminfo_kb |
| 106 | func nb_cpu_read(buf: *u8, cap: i64, bo: *i64, to: *i64) -> i64 |
| 129 | func nb_loadavg_milli(buf: *u8) -> i64 |
| 156 | func nb_ncpu(buf: *u8, cap: i64) -> i64 |
| 165 | func nb_meminfo_kb(buf: *u8, n: i64, key: *u8, klen: i64) -> i64 |
| 175 | func nb_thermal_max_mc(buf: *u8) -> i64 |
| 198 | func nb_batt_pct(buf: *u8) -> i64 |
| 219 | func nb_build_row(row: *u8, name: *u8, cpu_pct: i64, load_milli: i64, ncpu: i64, lpc: i64, mem_used_pct: i64, mem_avail_mb: i64, mem_total_mb: i64, conns: i64, ts: i64, temp_mc: i64, batt_pct: i64) -> i64 |
| 237 | func main(argc: i64, argv: *i64) -> i64 |