Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

fix(rootfs): mount procfs for uutils coreutils in early chroot (native arm64 builds) - #10270

#10270
Open
lukaszsobala wants to merge 5 commits into
armbian:mainarmbian/build:mainfrom
lukaszsobala:fix/native-arm64-uutils-auxv-chrootlukaszsobala/build:fix/native-arm64-uutils-auxv-chrootCopy head branch name to clipboard
Open

fix(rootfs): mount procfs for uutils coreutils in early chroot (native arm64 builds)#10270
lukaszsobala wants to merge 5 commits into
armbian:mainarmbian/build:mainfrom
lukaszsobala:fix/native-arm64-uutils-auxv-chrootlukaszsobala/build:fix/native-arm64-uutils-auxv-chrootCopy head branch name to clipboard

Conversation

@lukaszsobala

@lukaszsobala lukaszsobala commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Here is a solution to a problem that existed for months but nobody could reproduce so far. I've tested arm64 native builds and x86. Both work correctly.

Problem

Building Ubuntu 26.04 (Resolute) images natively on an arm64 host targeting arm64 fails at the first chroot operation of the rootfs-cache extraction phase:

thread 'main' panicked at rustix/src/backend/linux_raw/param/auxv.rs:269:22:
called `Result::unwrap()` on an `Err` value: ()

lib/functions/rootfs/distro-specific.sh: line 179: Aborted
LC_ALL="C" LANG="C" LANGUAGE="" SUDO_USER="" chroot "${basedir}" /bin/bash -c \
  "ln -fs armbian-archive-keyring.gpg /usr/share/keyrings/armbian.gpg"

Error 134 at lib/functions/rootfs/distro-specific.sh:289
  create_sources_list_and_deploy_repo_key() -> distro-specific.sh:289
  extract_rootfs_artifact()                 -> rootfs/create-cache.sh:190

Root cause

Ubuntu 26.04 ships uutils as the default coreutils. Those binaries are built on rustix, which reads the process auxiliary vector at startup. When the kernel's primary auxv path fails — observed on Rockchip RK3588 vendor BSP kernels — rustix falls back to reading /proc/self/auxv. Inside a bare chroot that file does not exist, producing the unwrap() panic and aborting the very first chroot command run against a freshly-extracted rootfs.

Why it only affects native arm64→arm64 builds

x86 cross-builds are unaffected because qemu-user supplies the auxv directly, so the /proc fallback is never exercised. This only bites native arm64→arm64 builds, where the framework skips qemu setup entirely:

# lib/functions/rootfs/qemu-static.sh
if dpkg-architecture -e "${ARCH}"; then return 0   # native: no qemu deployed

At the extraction phase (extract_rootfs_artifactcreate_sources_list_and_deploy_repo_key "image-early"), mount_chroot() has not run yet, so the target has no procfs — and on native builds there is no qemu to paper over the missing /proc/self/auxv.

Manual reproduction

Against a rootfs extracted outside the build framework, on a native arm64 RK3588 host:

$ sudo chroot /tmp/rtest /bin/ln --version
thread 'main' panicked at rustix/.../auxv.rs:269:22:
called `Result::unwrap()` on an `Err` value: ()
Aborted

$ sudo mount -t proc proc /tmp/rtest/proc
$ sudo chroot /tmp/rtest /bin/ln --version
ln (uutils coreutils) 0.8.0        # works once procfs is present

The fix

Add mount_chroot_proc_for_uutils() (in lib/functions/general/chroot-helpers.sh, next to mount_chroot) and call it from create_sources_list_and_deploy_repo_key() before its chroot commands, tearing it down at the end of the function. The helper:

  • Guards on ${target}/proc/self/auxv — mounts procfs only when it is genuinely absent, so it is a no-op when procfs is already present.
  • Registers teardown with the cleanup-handler registry (add_cleanup_handler / execute_and_remove_cleanup_handler, mirroring the prepare/done idiom in host/mktemp-utils.sh) rather than a bare umount, so the mount is removed even if a later chroot step aborts partway.
  • Uses the framework's run_host_command_logged wrappers and display_alert logging.

Why it's a no-op everywhere else

create_sources_list_and_deploy_repo_key() has three callers:

caller when mounts before it guard result
rootfs-create.sh:201 root mount_chroot @ :167 procfs present → no-op
rootfs-image.sh:41 image-late mount_chroot @ :20 procfs present → no-op
create-cache.sh:190 image-early (none) procfs absent → mounts

Only the image-early path runs bare, and only on native builds does the missing auxv actually panic. On the other two callers mount_chroot() already mounted procfs, so the auxv guard short-circuits and the helper does nothing. Cross-builds keep their existing (working) behavior.

Scope

Narrow: the change is confined to the function that contains the failing chroots (create_sources_list_and_deploy_repo_key) plus a reusable helper. Audit confirmed this function is the only chroot invocation in the extraction phase (write_build_resolv_conf merely writes a file), and placing the guard here makes the function self-sufficient regardless of which caller invoked it.

Notes

  • Does not touch qemu / binfmt_misc — that is a separate concern.
  • No functional change on x86 cross-builds or any post-mount_chroot stage.

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility with Ubuntu 26.04+ when preparing system files inside a fresh chroot.
    • Ensured required process-information access by automatically mounting and later unmounting proc for specific core utilities when needed.
    • Added safeguards so temporary proc mounts are cleaned up reliably, even if the setup process is interrupted midway.

…e builds)

Ubuntu 26.04 (resolute) ships uutils as the default coreutils. Those
binaries are built on rustix, which reads the process auxiliary vector at
startup. When the kernel's primary auxv path fails -- observed on arm64
vendor/BSP kernels such as Rockchip RK3588 -- rustix falls back to reading
/proc/self/auxv. Inside a bare chroot that file does not exist, so the
binary panics:

    thread 'main' panicked at rustix/.../auxv.rs:269:22:
    called `Result::unwrap()` on an `Err` value: ()

This aborts the very first chroot command run against a freshly-extracted
rootfs, during the rootfs-cache extraction phase:

    chroot "${basedir}" /bin/bash -c \
      "ln -fs armbian-archive-keyring.gpg /usr/share/keyrings/armbian.gpg"
    -> Aborted (Error 134)

qemu-user cross-builds are immune: qemu supplies the guest auxv directly,
so the /proc fallback is never taken. It only bites native (e.g.
arm64->arm64) builds, where the framework skips qemu entirely and no
mounts have been set up yet at this early stage.

create_sources_list_and_deploy_repo_key() runs chroot commands before the
normal mount_chroot() has mounted procfs (for the "image-early" caller in
extract_rootfs_artifact). Add mount_chroot_proc_for_uutils(), which mounts
procfs into the target only when it is absent (guarded on
${target}/proc/self/auxv), and registers teardown with the cleanup-handler
registry so the mount is removed even if a later chroot step aborts. It is
a no-op for the "root"/"image-late" callers where mount_chroot() already
mounted procfs, keeping cross-builds and later stages unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 5399be5b-a9de-4efa-b253-ec6f4bdeaa6e

📥 Commits

Reviewing files that changed from the base of the PR and between 713d90b and 7b7ffab.

📒 Files selected for processing (1)
  • lib/functions/general/chroot-helpers.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/functions/general/chroot-helpers.sh

📝 Walkthrough

Walkthrough

Adds conditional procfs mounting for Ubuntu 26.04+ uutils coreutils chroot operations, registers cleanup for abort paths, and unmounts procfs on successful completion.

Changes

uutils procfs support

Layer / File(s) Summary
Procfs mount and cleanup helpers
lib/functions/general/chroot-helpers.sh
Adds helpers to detect usable procfs, mount it when needed, register teardown, and remove the cleanup handler after completion.
Chroot setup integration
lib/functions/rootfs/distro-specific.sh
Mounts procfs before repository and chroot setup, then performs the corresponding cleanup at function completion.

Estimated code review effort: 3 (Moderate) | ~15–30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant create_sources_list_and_deploy_repo_key
  participant mount_chroot_proc_for_uutils
  participant target_chroot
  participant cleanup_handler
  create_sources_list_and_deploy_repo_key->>mount_chroot_proc_for_uutils: Request procfs setup
  mount_chroot_proc_for_uutils->>target_chroot: Check /proc/self/auxv
  mount_chroot_proc_for_uutils->>target_chroot: Mount procfs when unavailable
  mount_chroot_proc_for_uutils->>cleanup_handler: Register teardown callback
  create_sources_list_and_deploy_repo_key->>cleanup_handler: Complete procfs cleanup
  cleanup_handler->>target_chroot: Unmount procfs if mounted
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: mounting procfs for uutils coreutils in the early chroot to support native arm64 builds.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size/medium PR with more then 50 and less then 250 lines 08 Milestone: Third quarter release Needs review Seeking for review Framework Framework components labels Jul 24, 2026
@lukaszsobala
lukaszsobala marked this pull request as ready for review July 24, 2026 15:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/functions/general/chroot-helpers.sh`:
- Around line 127-128: Update lib/functions/general/chroot-helpers.sh lines
127-128 by assigning target_proc="${target}/proc" and passing "${target_proc@Q}"
to both run_host_command_logged calls. At lines 150-150, pass the complete proc
path as "${target_proc@Q}" before the existing || true tokens, preserving the
command behavior while protecting paths containing whitespace or shell
metacharacters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 75594674-17dd-44d4-b644-283e097cda88

📥 Commits

Reviewing files that changed from the base of the PR and between 6e101ef and 713d90b.

📒 Files selected for processing (2)
  • lib/functions/general/chroot-helpers.sh
  • lib/functions/rootfs/distro-specific.sh

Comment thread lib/functions/general/chroot-helpers.sh Outdated
lukaszsobala and others added 2 commits July 24, 2026 21:42
run_host_command_logged re-parses its arguments through `bash -e -o
pipefail -c "$*"`, so paths are word-split a second time by that inner
shell. An unquoted "${target}/proc" containing whitespace or shell
metacharacters would break the mkdir/mount/umount invocations. Quote the
path with @q, matching the framework's convention for command strings that
pass through run_host_command_logged. Addresses CodeRabbit review feedback
on PR armbian#10270.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lukaszsobala

Copy link
Copy Markdown
Contributor Author

Armbian rebuilt after applying the coderabbit fixes, still builds on both x86 and arm64

@lukaszsobala

Copy link
Copy Markdown
Contributor Author

Any chance for a review?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

08 Milestone: Third quarter release Framework Framework components Needs review Seeking for review size/medium PR with more then 50 and less then 250 lines

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.