Repository navigation
hisn 0.4.1
hisn v0.4.1
0.4.1 makes run --detach return, completes the ls --json client view, removes the fixed 100 ms waits on session start and stop, and hardens the 0.4.0 seat model.
Highlights
hisn run --detachforks the supervisor, waits for readiness, prints<id> <name|-> readyand exits 0.- A failed start exits 125, with or without
--detach. - Session readiness and
hisn stopare event-driven. No fixed 100 ms poll remains on either path. hisn ls --jsonnow reports live clients and execs (hisn-ls/v2, additive).hisn ls --prunegains--name-prefixand--dry-run.- Observer queries (
ls,inspect,sessioninfo) no longer count as clients, so they cannot keep an idle session alive.
Added
hisn run --detachreturns. The child callssetsidand writes stdio to<session-dir>/supervisor.log(mode 0600). The parent prints RISK lines before forking, because the child's stderr is not the caller's.hisn ls --prune --name-prefix <prefix>prunes only stopped or crashed sessions whose name starts with<prefix>. An unnamed session never matches. Plain--pruneis unchanged.hisn ls --prune --dry-runlists the sessions that would be pruned and removes nothing.hisn ls --jsonadditions (hisn-ls/v2, same schema name):clients: live control connections (uid, pid, label, label_source, connected_since).execs: a live attach appears withattach: true.services,rootfs,members,lease, anddirfields.- For a stopped or crashed session,
clientsis[]and CLIENTS is 0.
- A
sessioninfocontrol op. The supervisor uses it to supply the live client and exec view, whichsession.jsonon disk cannot. hisn exec --client LABEL, the same flag asattach.hisn run --env-file PATH. It readsKEY=VALUElines (blank lines and#comments ignored; validated like--env). Use it for secret-shaped values so they stay out of/proc/<pid>/cmdline.- Leak tests L73 (
ls --prune --name-prefix), L74 (ls --jsonclients) and L75 (run --detachreturns). - Tests
tests/latency.rs,tests/detach_pipes.rsandtests/observers.rs.
Changed
- Readiness polls the control socket with a nonblocking connect and exponential backoff, 1 ms up to 20 ms. A stalled listener cannot block the waiter.
hisn stopwaits on the supervisor's pidfd. Only the no-pidfd fallback polls, with bounded exponential backoff.- A stopped session keeps its name. The name is reusable once
hisn ls --pruneremoves the directory and repairs the index. - Name reservation checks the index, so concurrent
runs are race-free.releasedrops a name only if it still maps to the releasing session's id. hisn stopon a stopped session printsalready stopped. On a crashed one it printscrashed, no supervisor. Both exit 0.hisn inspectredacts[env.set]values whose names matchlooks_secret.touch_leasewritessession.jsononly when the session has a lease.
Fixed
- A failed
run --detachstart returned 1 instead of 125 (refused profile, missingrisk_ack,home.persistrefusal, service readiness timeout). It now exits with the named constantEXIT_START_FAILED(125) in every case. A running session's command status is unchanged. - A detached supervisor inherited the parent's stdout, stderr and ready-pipe write ends. A caller that held those pipes never saw EOF. Go's exec reported
WaitDelay expired before I/O completeand treated a live session as dead. The child now closes every inherited fd except the ready pipe. - RISK lines never reached the caller under
--detach. The parent now prints them before the fork. - Client records were keyed by file descriptor number. The kernel reuses a closed fd at once, so a later connection could replace a live record and a close could remove the wrong one.
clientsstayed at 1 after the connection closed and idle never fired. Connections now have a process-unique id, and the count and records live in one registry. - Observers and bare probes could register as clients and bump
last_activity. Registration now happens only after a request is admitted. A refused request never registers. A disconnect bumps activity only for a counted connection.
Hardening
redact_env_setredacts[env.set]values by parsing the policy TOML.- The host environment is read with
vars_os(). A non-UTF-8 variable no longer panics the supervisor. - Client connect and exec registration take
lease_lock, the same lock the idle check holds. An exec admitted during the idle check is not stopped under it. is_loopback_nsalso rejects0.0.0.0,::,::ffff:127.0.0.0/8and::ffff:0.0.0.0.build_resolv_confrefuses a[net] nameserversoverride that is empty or loopback-only. Before, onlyhisn profile validatedid.- Detached-child fd hygiene: all inherited fds of 3 and above are closed, and 0 to 2 are reopened from
/dev/nulluntil stdio moves tosupervisor.log. - RISK lines are printed before the fork under
--detach.
Compatibility
- The
ls --jsonschema name stayshisn-ls/v2. The changes are additive, and 0.4.0 fields are kept. hisn ls --prunewithout the new flags behaves as in 0.4.0.runwithout--detachis unchanged.- If the
sessioninforequest fails,lsshows emptyclients,execsandservicesfor that session. It does not fail. - 0.4.1-only:
run --detachreturning,--env-file,exec --client,--name-prefix,--dry-run, thesessioninfoop, and the liveclients,execs,servicesandrootfsdata inls --json. - Not tested in the tree: a 0.4.1 client against a running 0.4.0 supervisor.
Known issue carried forward: ttyname() inside an attach still fails. The fix needs a protocol change and a host to verify it. See CHANGELOG and DESIGN section 20.1.
Verified
- Unit tests and
tests/leak/test_l8.pywere run in the build sandbox, per the CHANGELOG. - The build sandbox blocks user namespaces. The leak suite and the
--detachand attach host steps could not run there. - Latency is asserted in
tests/latency.rs: a socket that appears after 8 ms must be observed ready in under 60 ms, an already-ready socket in under 30 ms, and a stop in under 80 ms. A fallback test asserts no fixed 100 ms sleep. The tree holds no trace output. The test prints the measured times, but no trace output is committed, so this note quotes no measured figure. The earlier CHANGELOG figures in microseconds were removed: they cannot describe the 8 ms case, which takes at least 8 ms by construction. - No leak suite result for 0.4.1 is committed. The last recorded one is 308 passed, 0 failed, 6 skipped, 1 weak, for 0.4.0. This note gives no 0.4.1 count. The same applies to two-host seat and audit archival runs: nothing in the tree records them for 0.4.1.
- Host steps to run on rubin:
cargo test --release,HISN_TEST_ROOTFS="$(hisn rootfs path wakil-dev)" make leaktest,hisn run --name t --detach,hisn ls --json,hisn ls --prune --name-prefix wakil-.