Skip to content

Commit fe2733b

Browse files
committed
simplify(qemu-static): kernel-counted refcount via flock on binfmt entry
Replace ~250 lines of userspace coordination (per-builder owner files in /run/lock/armbian-native-armhf/owners/, control lock, live-owner counting) with kernel-level flock on /proc/sys/fs/binfmt_misc/qemu-arm itself. Why - The previous design required /run/lock to be a host-bind-mount into every build container, which the current Armbian docker setup does NOT do, defeating the cross-container coordination it was built for. - Five race rounds with Codex accumulated complexity for an edge case the standard Armbian CI matrix does not exercise (one runner per matrix entry, so kernel state is per-runner, no cross-container coordination needed). - A kernel-counted refcount is what we actually need; flock(2) provides it directly on the very kernel object we're coordinating around. How - Each build holds LOCK_SH on /proc/sys/fs/binfmt_misc/qemu-arm via a long-lived fd. Kernel BSD-flock counter is the refcount; the kernel releases the fd on process exit (crash-safe). No per-builder lockfiles, no shared state files, no /run/lock directory tree, just a flock on the kernel object itself. - First-arrival idempotently echoes 0 to disable. Subsequent arrivals observe state==0 and proceed without writing. - On exit, release LOCK_SH; last-out detects via LOCK_EX-LOCK_NB on a fresh fd to the same entry, succeeds iff zero other LOCK_SH holders. The last-out re-enables qemu-arm. - Builders are fully independent: no shared writeable state, no per- builder files, no awareness of each other. Trade-off Prior qemu-arm state is not recorded across independent builds (no shared writeable state by design). Last-out unconditionally re-enables. If an admin deliberately had qemu-arm disabled before any armbian build started, that policy is lost. Rare in practice (default Ubuntu/Debian have it enabled), and was not a strongly-preserved invariant in the earlier implementation either. Subtle bash gotcha fixed in this revision exec {fd}< file 2> /dev/null permanently silences the shell's stderr because exec without a command applies redirections to the current shell. Every later display_alert (which writes to stderr) was silently dropped, including from the cleanup handler. Wrap the exec in { ...; } 2>/dev/null to scope the stderr suppression to the exec command alone. Empirically verified on Hetzner CAX21 (Ubuntu 24.04 kernel 6.8.0-90-generic, binfmt_misc fs): - flock LOCK_SH on /proc/sys/fs/binfmt_misc/qemu-arm works. - LOCK_EX-LOCK_NB while another holds LOCK_SH blocks as expected. - The entry persists through echo 0 (only echo -1 unregisters). - Single-tree build emits all 5 phase markers + last-out restore. - Two independent armbian worktrees concurrent on same host: both enter native armhf path, kernel SH-counter holds qemu-arm disabled across both, first-finished's cleanup correctly suppresses restore (EX-NB blocked by other's SH), last-finished restores qemu-arm to enabled. Net diff: 397 -> 272 lines (-261 / +136). Assisted-by: Claude:claude-opus-4.7
1 parent ca4b442 commit fe2733b

1 file changed

Lines changed: 136 additions & 261 deletions

File tree

0 commit comments

Comments
 (0)