code wiki / (root) / nx_lock_reap_core.nx

nx_lock_reap_core.nx source

↩ module page · 117 lines · 5258 B

1// nx_lock_reap_core.nx -- importable CORE of the SOVEREIGN stale-lock reaper (R-ORCH-2a; the 2// BUILD(missing) gap the triage flagged + the exact class that blocked commits this session, now 3// mechanized as an ORGAN instead of the ps|grep|rm shell sin). A workstream that crashes mid-write 4// can leave a stale lock (git index.lock, a WMS lease, cp_deploy.lease, a reconcile lock) blocking 5// every sibling -- exactly what the orchestration north-star must never let a crash cost. This 6// reaps such a lock, but ONLY when it is provably abandoned. 7// 8// FAIL-SAFE BY CONSTRUCTION (the load-bearing property, gate-proven): reap iff the lock EXISTS AND 9// no OWNER process is alive (a /proc cmdline scan for the owner needle -- authoritative for same- 10// kernel NAS/WSL processes) AND it is older than the age threshold. A live-owned lock is NEVER 11// reaped (even if old); a fresh lock is NEVER reaped (a legit in-flight op). Default = do nothing. 12// (Cross-boundary note: a Windows git.exe holding /mnt/c/.git/index.lock is NOT visible in WSL 13// /proc; that case is closed by the sovereign-commit path, not this reaper -- honest scope.) 14// license_tier: ORIGINAL 15import "nx_syscalls.nx" 16import "nx_crashresume_census_core.nx" // ccz_read / ccz_mtime / ccz_slen / ccz_num_at / ccz_cat_* 17const K_MAGIC_65536: i64 = 65536 18const K_MAGIC_8192: i64 = 8192 19 20// unlinkat(AT_FDCWD, path, 0): x86_64 nr 263 passed DIRECTLY (the fsync-74/fstatat-262 precedent). 21func lr_unlink(path: *u8) -> i64 { return __syscall(263, AT_FDCWD, path, 0, 0, 0, 0) } 22 23// exists? (fstatat succeeds) 24func lr_exists(path: *u8) -> i64 { 25 let sb: *u8 = sys_mmap(256) 26 if sys_fstatat(path, sb) < 0 { return 0 } 27 return 1 28} 29 30// age in seconds from mtime; -1 if absent. 31func lr_age_s(path: *u8, now: i64) -> i64 { 32 let mt: i64 = ccz_mtime(path) 33 if mt < 0 { return 0 - 1 } 34 return now - mt 35} 36 37// case-sensitive substring containment (cmdline has NUL separators; needle has no NUL so it's safe). 38func lr_contains(hay: *u8, hn: i64, needle: *u8) -> i64 { 39 let nn: i64 = ccz_slen(needle) 40 if nn == 0 { return 0 } 41 var i: i64 = 0 42 while i + nn <= hn { 43 var k: i64 = 0 44 var ok: i64 = 1 45 while k < nn { if hay[i+k] != needle[k] { ok = 0; k = nn } k = k + 1 } 46 if ok == 1 { return 1 } 47 i = i + 1 48 } 49 return 0 50} 51 52// self pid via /proc/self/stat leading digits. 53func lr_selfpid() -> i64 { 54 let b: *u8 = sys_mmap(256) 55 let n: i64 = ccz_read("/proc/self/stat" as *u8, b, 255) 56 if n <= 0 { return 0 - 1 } 57 let ep: *i64 = sys_mmap(16) as *i64 58 return ccz_num_at(b, n, 0, ep) 59} 60 61// is a live process (other than self, and other than the reaper organ) whose /proc/<pid>/cmdline 62// contains `needle` currently running? Authoritative for same-kernel processes. 63func lr_owner_alive(needle: *u8) -> i64 { 64 let nn: i64 = ccz_slen(needle) 65 if nn == 0 { return 0 } 66 let self: i64 = lr_selfpid() 67 let fd: i64 = sys_openat_rd("/proc" as *u8) 68 if fd < 0 { return 0 } 69 let dbuf: *u8 = sys_mmap(K_MAGIC_65536) 70 let path: *u8 = sys_mmap(256) 71 let clbuf: *u8 = sys_mmap(K_MAGIC_8192) 72 let ep: *i64 = sys_mmap(16) as *i64 73 var found: i64 = 0 74 var run: i64 = 1 75 while run == 1 { 76 let n: i64 = sys_getdents64(fd, dbuf, K_MAGIC_65536) 77 if n <= 0 { run = 0 } else { 78 var off: i64 = 0 79 while off < n { 80 let rec: *u8 = ((dbuf as i64 + off) as *u8) 81 let reclen: i64 = dirent_reclen(rec) 82 if reclen <= 0 { off = n } else { 83 let name: *u8 = dirent_name(rec) 84 if name[0] >= (48 as u8) { if name[0] <= (57 as u8) { 85 let pid: i64 = ccz_num_at(name, ccz_slen(name), 0, ep) 86 if pid != self { 87 var o: i64 = 0 88 let pre: *u8 = "/proc/" as *u8 89 var a: i64 = 0 90 while pre[a] != (0 as u8) { path[o] = pre[a]; o = o + 1; a = a + 1 } 91 a = 0 92 while name[a] != (0 as u8) { path[o] = name[a]; o = o + 1; a = a + 1 } 93 let suf: *u8 = "/cmdline" as *u8 94 a = 0 95 while suf[a] != (0 as u8) { path[o] = suf[a]; o = o + 1; a = a + 1 } 96 path[o] = 0 as u8 97 let cln: i64 = ccz_read(path, clbuf, K_MAGIC_8192) 98 if cln > 0 { if lr_contains(clbuf, cln, needle) == 1 { found = 1; run = 0; off = n } } 99 } 100 } } 101 off = off + reclen 102 } 103 } 104 } 105 } 106 sys_close(fd) 107 return found 108} 109 110// THE decision. Pure. reap iff exists AND not owner-alive AND age > threshold. Everything else -> 0. 111func lr_should_reap(exists: i64, owner_alive: i64, age_s: i64, max_age_s: i64) -> i64 { 112 if exists == 0 { return 0 } 113 if owner_alive == 1 { return 0 } // a live owner holds it -> NEVER reap 114 if age_s < 0 { return 0 } // unknown age -> fail safe 115 if age_s <= max_age_s { return 0 } // fresh -> could be a legit in-flight op 116 return 1 117}