You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bootc: Handle ENOSYS from emulated syscalls in container lint instead of failing (#1481) #311
Task: bootc-dev/bootc#1481. bootc container lint on an arm64 image under QEMU user-mode emulation fails with errno 38 (ENOSYS, set_robust_list) from some checks. Find the lints that fail (see the issue's trace), and make them degrade gracefully: skip the affected check with a clear warning when the error is ENOSYS rather than aborting the run. Check whether the failing call is in bootc or inside cap-std (sunfishcode/cap-std#423); if the only fix is upstream in cap-std, say so in your report and do not hack around it.
Acceptance: a unit test for the ENOSYS-to-skip classification; cargo fmt --check, cargo clippy --all-targets, cargo test pass.
Constraints: code and tests only, no GitHub writes (the coordinator opens the PR); keep the change small and match the surrounding style; commit message in the project's style with a Generated-by: AI trailer, no Signed-off-by.
Triage (21 Oct 2026): valid and reproducible, but the brief points at the wrong syscall and the wrong repository. Needs the operator to pick a direction.
What actually fails. The ENOSYS is from openat2, not set_robust_list. amnabbouti traced it in bootc#1481 (25 Aug 2026): QEMU linux-user 8.2.9 reports unsupported aarch64 syscall 437 (openat2) right before the error, and the same image passes under QEMU 10.2.2. QEMU gained openat2 in linux-user with commit 9651cead (Oct 2024), shipped in 9.2, motivated by the same symptom in bootc-image-builder#619. The original reporter's "fix" was a QEMU built from git master, which already had openat2; the set_robust_list stub was incidental (glibc ignores that call's result).
Where the call lives. Not in bootc. Both failing lints reach cap-std-ext's direct openat2(RESOLVE_NO_XDEV | RESOLVE_BENEATH) in impl_open_dir_noxdev, which maps EXDEV to Ok(None) but passes ENOSYS through:
utf8 is a recursive lint run through walk_configuration().noxdev(), and cap-std-ext's walk_inner opens every child directory with that function.
cap-std-ext already tolerates ENOSYS from statx in is_mountpoint (returns Ok(None)), so there is precedent, but open_dir_noxdev has no fallback. cap-std#423 asks cap-primitives for a RESOLVE_NO_XDEV-aware manual resolver; sunfishcode said cap-std has never offered that, and cap-std#426 is about archiving cap-std, so nothing will come from there. bootc pins cap-std-ext 5.1.2 and cap-primitives 4.0.2; no ENOSYS handling exists in bootc's tree today.
Why this is the operator's call. The brief ("skip the check with a clear warning on ENOSYS") conflicts with cgwalters's own upstream reply (5 Aug 2025), which prefers a stat-plus-dev/inode fallback over not running the lints, and the fallback belongs in coreos/cap-std-ext, which is not in this tracker's dispatch bounds (.github/agentic-job/dispatch.toml lists only the cgwalters-forge/bootc fork). The epic this sits under (#333) is parked. The options:
Close as not planned, with a docs note. QEMU 9.2 and later implement openat2, so the environment fix exists; a line in the lint docs saying "under QEMU user-mode emulation older than 9.2, use --skip var-tmpfiles --skip utf8 or upgrade QEMU" covers the remaining users (Ubuntu 24.04 still ships 8.2). This is the cheapest option and matches cgwalters's "happy to take a patch for that" on documentation.
Fix in cap-std-ext, then bump bootc. In impl_open_dir_noxdev and open_beneath_rdonly, on Errno::NOSYS fall back to a component-by-component openat(O_DIRECTORY | O_NOFOLLOW) with a statxMOUNT_ROOT check (or st_dev comparison) per component, returning Ok(None) on a crossing. That is one cap-std-ext PR plus a bootc dependency bump, and needs coreos/cap-std-ext added to the dispatch bounds or a run by hand.
Do the brief as written in bootc. Catch ErrorKind::Unsupported or Errno::NOSYS in the lint runner and report the lint as skipped with a warning. Smallest change, but it silently weakens utf8 and var-tmpfiles on old emulators, which cgwalters argued against upstream.
Recommendation: option 1, with option 2 if a code fix is wanted. I will not plan anything until one is chosen.
Activity
cgwalters-bot commentedon Oct 22, 2026
✅ dispatch ended well. Result: #311 (comment)
cgwalters-bot commentedon Oct 22, 2026
Triage (21 Oct 2026): valid and reproducible, but the brief points at the wrong syscall and the wrong repository. Needs the operator to pick a direction.
What actually fails. The ENOSYS is from
openat2, notset_robust_list. amnabbouti traced it in bootc#1481 (25 Aug 2026): QEMU linux-user 8.2.9 reports unsupported aarch64 syscall 437 (openat2) right before the error, and the same image passes under QEMU 10.2.2. QEMU gainedopenat2in linux-user with commit 9651cead (Oct 2024), shipped in 9.2, motivated by the same symptom in bootc-image-builder#619. The original reporter's "fix" was a QEMU built from git master, which already hadopenat2; theset_robust_liststub was incidental (glibc ignores that call's result).Where the call lives. Not in bootc. Both failing lints reach cap-std-ext's direct
openat2(RESOLVE_NO_XDEV | RESOLVE_BENEATH)inimpl_open_dir_noxdev, which maps EXDEV toOk(None)but passes ENOSYS through:utf8is a recursive lint run throughwalk_configuration().noxdev(), and cap-std-ext'swalk_inneropens every child directory with that function.var-tmpfilescallsopen_dir_noxdevin crates/tmpfiles/src/lib.rs, and its path resolution goes throughRootDir, whoseopen_beneath_rdonlyis also a bareopenat2(RESOLVE_IN_ROOT).cap-std-ext already tolerates ENOSYS from
statxinis_mountpoint(returnsOk(None)), so there is precedent, butopen_dir_noxdevhas no fallback. cap-std#423 asks cap-primitives for aRESOLVE_NO_XDEV-aware manual resolver; sunfishcode said cap-std has never offered that, and cap-std#426 is about archiving cap-std, so nothing will come from there. bootc pins cap-std-ext 5.1.2 and cap-primitives 4.0.2; no ENOSYS handling exists in bootc's tree today.Why this is the operator's call. The brief ("skip the check with a clear warning on ENOSYS") conflicts with cgwalters's own upstream reply (5 Aug 2025), which prefers a
stat-plus-dev/inode fallback over not running the lints, and the fallback belongs in coreos/cap-std-ext, which is not in this tracker's dispatch bounds (.github/agentic-job/dispatch.tomllists only the cgwalters-forge/bootc fork). The epic this sits under (#333) is parked. The options:openat2, so the environment fix exists; a line in the lint docs saying "under QEMU user-mode emulation older than 9.2, use--skip var-tmpfiles --skip utf8or upgrade QEMU" covers the remaining users (Ubuntu 24.04 still ships 8.2). This is the cheapest option and matches cgwalters's "happy to take a patch for that" on documentation.impl_open_dir_noxdevandopen_beneath_rdonly, onErrno::NOSYSfall back to a component-by-componentopenat(O_DIRECTORY | O_NOFOLLOW)with astatxMOUNT_ROOTcheck (orst_devcomparison) per component, returningOk(None)on a crossing. That is one cap-std-ext PR plus a bootc dependency bump, and needs coreos/cap-std-ext added to the dispatch bounds or a run by hand.ErrorKind::UnsupportedorErrno::NOSYSin the lint runner and report the lint as skipped with a warning. Smallest change, but it silently weakensutf8andvar-tmpfileson old emulators, which cgwalters argued against upstream.Recommendation: option 1, with option 2 if a code fix is wanted. I will not plan anything until one is chosen.