nx_deploy_capture_selection_gate.nx source
↩ module page · 90 lines · 4693 B
1// Signal-free selector witness. Reads only this gate's owned child's /proc record.
2// Never invokes proc_kill_by_name, deploy, restart, promotion or any signal primitive.
3import "_hdl_build/nx_hostctl.nx"
4import "nx_gate_verdict.nx"
5const DS_PIPE_STORAGE: i64 = 8
6const DS_INT32_MASK: i64 = 0xffffffff
7const DS_INT32_SHIFT: i64 = 32
8const DS_RELEASE_BYTES: i64 = 1
9const DS_INTEGER_BUFFER: i64 = 32
10
11func ds_write(fd: i64, data: *u8, n: i64) -> i64 {
12 var done: i64=0
13 while done < n {
14 let wrote: i64=sys_write(fd,((data as i64)+done) as *u8,n-done)
15 if wrote <= 0 { return 0-1 }; done=done+wrote
16 }; return 0
17}
18func ds_read(fd: i64, data: *u8, n: i64) -> i64 {
19 var done: i64=0
20 while done < n {
21 let got: i64=sys_read(fd,((data as i64)+done) as *u8,n-done)
22 if got <= 0 { return 0-1 }; done=done+got
23 }; return 0
24}
25func main(argc: i64, argv: *i64) -> i64 {
26 // A unique fixture needle passed as an argument is inherited in the child cmdline.
27 // It need not be a real service name: the production selector scans every argument.
28 if argc != 2 { return 3 }
29 let needle: *u8=argv[1] as *u8
30 let nn: i64=hc_slen(needle)
31 if nn <= 0 || nn >= HC_MAGIC_8192 { return 3 }
32 let ctr: *i64=gv_ctr(); gv_head("DEPLOY-CAPTURE-SELECTION / no signals" as *u8)
33 if sys_ignore_sigpipe() != 0 { return 3 }
34 let ready: *i64=sys_mmap(DS_PIPE_STORAGE) as *i64
35 let release: *i64=sys_mmap(DS_PIPE_STORAGE) as *i64
36 if (ready as i64) <= 0 || (release as i64) <= 0 { return 3 }
37 if sys_pipe2(ready,0) != 0 { return 3 }
38 let rr: i64=ready[0] & DS_INT32_MASK
39 let rw: i64=(ready[0] >> DS_INT32_SHIFT) & DS_INT32_MASK
40 if sys_pipe2(release,0) != 0 { sys_close(rr); sys_close(rw); return 3 }
41 let qr: i64=release[0] & DS_INT32_MASK
42 let qw: i64=(release[0] >> DS_INT32_SHIFT) & DS_INT32_MASK
43 let pid: i64=sys_fork()
44 if pid < 0 { sys_close(rr); sys_close(rw); sys_close(qr); sys_close(qw); return 3 }
45 if pid == 0 {
46 sys_close(rr); sys_close(qw)
47 let result: *i64=sys_mmap(DS_PIPE_STORAGE) as *i64
48 if (result as i64) <= 0 { sys_exit_group(3) }
49 result[0]=nx_setsid()
50 let sent: i64=ds_write(rw,result as *u8,DS_PIPE_STORAGE)
51 sys_close(rw)
52 let released: i64=ds_read(qr,result as *u8,DS_RELEASE_BYTES)
53 sys_close(qr)
54 if sent != 0 || released != 0 { sys_exit_group(3) }
55 sys_exit_group(0)
56 }
57 sys_close(rw); sys_close(qr)
58 let result: *i64=sys_mmap(DS_PIPE_STORAGE) as *i64
59 if (result as i64) <= 0 { sys_close(rr); sys_close(qw); return 3 }
60 let received: i64=ds_read(rr,result as *u8,DS_PIPE_STORAGE)
61 sys_close(rr)
62 gv_check("actual child session transition observed" as *u8,received == 0 && result[0] == pid,ctr)
63 let path: *u8=sys_mmap(SYS_PATH_MAX)
64 let cmdline: *u8=sys_mmap(HC_MAGIC_8192)
65 var selected: i64=0
66 if (path as i64) > 0 && (cmdline as i64) > 0 {
67 let prefix: *u8="/proc/" as *u8
68 var p: i64=0
69 while prefix[p] != (0 as u8) { path[p]=prefix[p]; p=p+1 }
70 // Existing hostctl numeric helper emits to stdout only; use decimal reverse in spare path tail.
71 var number: i64=pid; var digits: i64=0
72 let tmp: *u8=sys_mmap(DS_INTEGER_BUFFER)
73 if (tmp as i64) > 0 {
74 while number > 0 { tmp[digits]=(48+number%10) as u8; number=number/10; digits=digits+1 }
75 while digits > 0 { digits=digits-1; path[p]=tmp[digits]; p=p+1 }
76 let suffix: *u8="/cmdline" as *u8; var j: i64=0
77 while suffix[j] != (0 as u8) { path[p]=suffix[j]; p=p+1; j=j+1 }; path[p]=0 as u8
78 let cn: i64=hc_read_cmdline(path,cmdline,HC_MAGIC_8192)
79 gv_check("owned child proc cmdline read without capacity saturation" as *u8,cn > 0 && cn < HC_MAGIC_8192,ctr)
80 if cn > 0 && cn < HC_MAGIC_8192 { selected=hc_contains(cmdline,cn,needle,nn) }
81 }
82 }
83 gv_check("existing stop predicate selects detached inherited cmdline" as *u8,selected == 1,ctr)
84 gv_puts("fixture_pid=" as *u8); gv_num(pid); gv_puts(" detached_session=" as *u8); gv_num(result[0]); gv_puts(" selector_match=" as *u8); gv_num(selected); gv_puts(" signals_sent=0\n" as *u8)
85 let released: i64=ds_write(qw,"x" as *u8,DS_RELEASE_BYTES); sys_close(qw)
86 gv_check("owned fixture released without signal" as *u8,released == 0,ctr)
87 let waited: i64=sys_wait4(pid,result,0)
88 gv_check("owned child actually reaped with zero exit" as *u8,waited == pid && result[0] == 0,ctr)
89 return gv_verdict("DEPLOY-CAPTURE-SELECTION" as *u8,ctr,"selection witness only; does not kill or prove historical coordinator termination" as *u8)
90}