Skip to content

feat(busybox): run before 80base so applets replace host binaries - #2451

Draft
nadzyah wants to merge 2 commits into
dracut-ng:mainfrom
nadzyah:busybox-rust-coreutils
Draft

feat(busybox): run before 80base so applets replace host binaries#2451
nadzyah wants to merge 2 commits into
dracut-ng:mainfrom
nadzyah:busybox-rust-coreutils

Conversation

@nadzyah

@nadzyah nadzyah commented May 20, 2026

Copy link
Copy Markdown
Contributor

Distros that ship large coreutils binaries (e.g. Ubuntu 25.10 with rust-coreutils) inflate the initrd because 80base copies the host's binaries like cp, ls, mv in full.

When the busybox module is included, 80base now skips any name busybox provides as an applet. 81busybox then symlinks those names to /usr/bin/busybox, restoring the smaller initrd footprint.

Bug-Ubuntu: https://bugs.launchpad.net/bugs/2150657

Checklist

  • I have tested it locally
  • I have reviewed and updated any documentation if relevant
  • I am providing new code and test(s) for it

@nadzyah
nadzyah requested a review from a team as a code owner May 20, 2026 10:56
@github-actions github-actions Bot added test Issues related to testing modules Issue tracker for all modules base Issues related to the base module man docs labels May 20, 2026
Comment thread dracut.sh Fixed
@nadzyah
nadzyah force-pushed the busybox-rust-coreutils branch from 3bdbbef to f7663c2 Compare May 20, 2026 11:03
@bdrung

bdrung commented May 20, 2026

Copy link
Copy Markdown
Member

I would prefer a solution that would work without adding the prefer_busybox setting. So use busybox applets in case busybox is included.

I looked at git log --follow --stat modules.d/81busybox/module-setup.sh to see why busybox is included so late and found only:

Commit 4e78a87 ("fix(busybox): install busybox symlinks later in the generation process"). After a search I found the corresponding #536 PR which links to #534. This bug is fixed by commit 95ba032 but the renumbering is unrelated to it.

Commit 3975e26 ("feat(busybox): use busybox --install to install itself") says:

Previous commits in this PR exposed a bug whereby some utilities (e.g. dd) had both a busybox applet version and a coreutils version.

The busybox dracut module should not enforce taking always the busybox version. The busybox --install command is safer option that does not overwrite an existing binary of already exists.

So how about moving busybox from 81busybox to 10busybox and address #2437 to ensure that the modules work with the busybox applets. If modules do not work with the busybox applets, they can do:

[ -L "$binary" ] && rm "$binary"
inst "$binary"

What do you think? @devkontrol @Conan-Kudo

@devkontrol

Copy link
Copy Markdown
Collaborator

I would prefer a solution that would work without adding the prefer_busybox setting.

YES. THIS.

inflate the initrd because 80base copies the host's binaries like cp, ls, mv in full.

On Alpine when both coreutils and busybox are installed (as Alpine packages), I think this is not always the case today. Let's understand when exactly the "expected" initrd generation happening already. So there might be a way to trigger similar kind of code path with Ubuntu as well.

I am not against making additional fixes in dracut to make this scenario more accessible, but adding a new global flag is probably not the best option here.

@nadzyah
nadzyah force-pushed the busybox-rust-coreutils branch from f7663c2 to 06787f2 Compare May 22, 2026 16:15
@github-actions github-actions Bot added the busybox Issues related to the busybox module label May 22, 2026

@bdrung bdrung left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The change looks good to me. I only have some minor remarks.

How long will this test take? Maybe it could be folded into an existing test in case the setup takes some time.

We should prefer busybox over dash in shell-interpreter (separate PR).

What kind of test have you done? Did you compare the initrd size on Ubuntu with this change?

Comment thread modules.d/80base/module-setup.sh
Comment thread test/TEST-83-BUSYBOX-APPLETS/test.sh
Comment thread modules.d/10busybox/module-setup.sh Outdated
Comment thread modules.d/80base/module-setup.sh Outdated
Comment thread test/TEST-83-BUSYBOX-APPLETS/test.sh
Comment thread test/TEST-83-BUSYBOX-APPLETS-WIN/test.sh Outdated
Comment thread test/TEST-83-BUSYBOX-APPLETS-WIN/test.sh Outdated
@nadzyah
nadzyah force-pushed the busybox-rust-coreutils branch from 06787f2 to 4deac43 Compare May 25, 2026 19:36
@github-actions github-actions Bot added the github Issues related to .github label May 25, 2026
@nadzyah
nadzyah force-pushed the busybox-rust-coreutils branch 6 times, most recently from bd3bba0 to d5b2b4a Compare May 26, 2026 16:51
@nadzyah
nadzyah marked this pull request as draft May 26, 2026 18:47
@devkontrol
devkontrol force-pushed the busybox-rust-coreutils branch from d5b2b4a to 3c4ea59 Compare May 26, 2026 22:17
@nadzyah
nadzyah marked this pull request as ready for review May 26, 2026 22:18
Comment thread .github/workflows/integration.yml
@devkontrol

devkontrol commented May 26, 2026

Copy link
Copy Markdown
Collaborator

Fedora failure for test 83 might be related to #2454, please double-check (see also #2455 (comment)).

@challvy

challvy commented May 27, 2026

Copy link
Copy Markdown

Fedora failure for test 83 might be related to #2454, please double-check (see also #2455 (comment)).

Yes, I think so. @devkontrol Looking at TEST-83 in PR #2451, it checks cp/ls/mv/rm/mkdir/sleep/tr under usr/bin/. My current fix(#2455 #2454 ) only handles sh (the immediate kdump blocker) on Fedora 43.

Is it necessary to normalize all applet paths to /usr/bin/? Patch like this:

diff --git a/modules.d/81busybox/module-setup.sh b/modules.d/81busybox/module-setup.sh
index 402e1fc2..b5767ea6 100755
--- a/modules.d/81busybox/module-setup.sh
+++ b/modules.d/81busybox/module-setup.sh
@@ -30,9 +30,19 @@ install() {
         _path=$(find_binary "$_i")
         [ -z "$_path" ] && continue

+        # 1. Install at host's path (preserves topology, e.g. /sbin/ifconfig)
         # do not remove existing destination files
-        [ -e "${_dstdir}/$_path" ] && continue
-
-        ln_r /usr/bin/busybox "$_path"
+        [ -e "${_dstdir}/$_path" ] || ln_r /usr/bin/busybox "$_path"
+
+        # 2. Ensure canonical /usr/bin/<applet> always exists (POSIX layout).
+        # find_binary's literal path depends on $DRACUT_PATH ordering and may
+        # resolve to e.g. /usr/sbin/sh on Fedora 42+ where the busybox package
+        # places applet symlinks under /usr/sbin/. Standard scripts expect
+        # /usr/bin/<applet> (and #!/bin/sh -> /usr/bin/sh on merged-usr), so
+        # create the canonical symlink unconditionally if absent.
+        local _canonical="/usr/bin/${_path##*/}"
+        [ "$_path" = "$_canonical" ] && continue
+        [ -e "${_dstdir}${_canonical}" ] && continue
+        ln_r /usr/bin/busybox "$_canonical"
     done
 }

@nadzyah
nadzyah force-pushed the busybox-rust-coreutils branch 2 times, most recently from 40c21ba to 55bc281 Compare May 27, 2026 08:38
@devkontrol

Copy link
Copy Markdown
Collaborator

Fedora failure for test 83 might be related to #2454, please double-check (see also #2455 (comment)).

Yes, I think so.

One way to proceed is to exclude test 83 for Fedora in the GitHub Action and deal with it as a follow-up PR.

@nadzyah
nadzyah force-pushed the busybox-rust-coreutils branch from 55bc281 to 67e919e Compare May 27, 2026 19:24
devkontrol
devkontrol previously approved these changes May 28, 2026
Comment thread .github/workflows/daily-basic.yml Outdated
@nadzyah
nadzyah force-pushed the busybox-rust-coreutils branch 2 times, most recently from 0e29c00 to 1b891dd Compare May 29, 2026 15:57
@Conan-Kudo

Copy link
Copy Markdown
Collaborator

"host bloat" is not accurate for the issue. The issue is that you have two separate implementations of UNIX core utilities installed and you want to use different ones for initramfs and the real system. Whether your choices are correct or not are separate issues, but regardless, it isn't "bloat". Please don't misuse words here, because it will confuse people reviewing it later.

@nadzyah

nadzyah commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

"host bloat" is not accurate for the issue. The issue is that you have two separate implementations of UNIX core utilities installed and you want to use different ones for initramfs and the real system. Whether your choices are correct or not are separate issues, but regardless, it isn't "bloat". Please don't misuse words here, because it will confuse people reviewing it later.

The wording in question was not introduced by me. The title and commit message were changed during review, and I kept that wording when amending the commit to address subsequent review comments.

I’m happy to change the terminology if “host bloat” is not considered accurate. However, the comment assumes I chose that wording intentionally, which wasn’t the case. A simple suggestion for alternative wording would have been sufficient.

@devkontrol

Copy link
Copy Markdown
Collaborator

The term "bloat" carries a negative connotation. Let's try to avoid it.

When prefer_busybox=yes and the busybox module is included

The PR no longer uses this flag, lets remove it from the PR description.

@devkontrol devkontrol added this to the 112 milestone Jun 15, 2026
@devkontrol devkontrol removed this from the 112 milestone Jul 12, 2026
@nadzyah
nadzyah force-pushed the busybox-rust-coreutils branch from 1b891dd to 60b9562 Compare July 13, 2026 08:55
@nadzyah nadzyah changed the title feat(busybox): run before base so applets win without host bloat feat(busybox): run before 80base so applets replace host binaries Jul 13, 2026
# pre-stage host binaries (e.g. Fedora's 01-dist.conf, see #2454).
# Modules that need the host binary must drop the symlink and reinstall
[ -L "${_dstdir}/$_path" ] && continue
[ -e "${_dstdir}/$_path" ] && rm -f "${_dstdir}/$_path"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should install the additional items from install_optional_items after we ran the modules. Then we would not need to do this workaround here. But let's do this change separately.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Done in #2511

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#2511 is controversial. So replacing existing binaries by symlinks would be controversial as well. So can we not do it in this PR?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This means that the test needs to ignore cat, rm, etc that dracut.conf.d/fedora/01-dist.conf includes via install_optional_items on Fedora.

Comment thread modules.d/80base/module-setup.sh Outdated
@bdrung bdrung mentioned this pull request Jul 21, 2026
3 tasks
@nadzyah
nadzyah force-pushed the busybox-rust-coreutils branch from 60b9562 to 2d5ead8 Compare July 22, 2026 09:05
Comment on lines +109 to +111
# busybox is not installed in the azurelinux image
- container: azurelinux:3.0
test: "83"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This exclusion can be dropped. We have busybox in azurelinux now: 874c545

@collinfunk

Copy link
Copy Markdown

Note that GNU coreutils has supported building as a single binary since 8.23, released 2014-07-18. If your only concern is size, I am not sure why you would need busybox. See:

$ { ./configure --enable-single-binary CFLAGS="$(rpm --eval '%{build_cflags}') -fno-strict-aliasing -fpic"; make -j 16; strip src/coreutils; } > /dev/null 2>&1
$ du --summarize --apparent-size src/coreutils /bin/busybox
1450	src/coreutils
1408	/bin/busybox

nadzyah added 2 commits July 30, 2026 18:09
Distros that ship large coreutils binaries (e.g. Ubuntu 25.10 with
rust-coreutils) inflate the initrd because 80base copies the host's binaries
like cp, ls, mv in full.

Rename modules.d/81busybox to modules.d/10busybox so the busybox module
runs first. It lays down /usr/bin/busybox and applet symlinks before
80base's inst_multiple calls.

The host's util-linux switch_root is still preferred.

Bug-Ubuntu: https://bugs.launchpad.net/bugs/2150657
@bdrung
bdrung force-pushed the busybox-rust-coreutils branch from 2d5ead8 to 9d0ea3d Compare July 30, 2026 16:09
@bdrung

bdrung commented Jul 31, 2026

Copy link
Copy Markdown
Member

Discussion from #2512: we currently cannot use blkid from busybox. The output is different and we use several arguments that are not supported by busybox.

@devkontrol

Copy link
Copy Markdown
Collaborator

Discussion from #2512: we currently cannot use blkid from busybox. The output is different and we use several arguments that are not supported by busybox.

It would be beneficial to have a busybox test case, independently from resolving https://bugs.launchpad.net/bugs/2150657.

Perhaps test case should be factored out into its own PR and for now the test case would check for blkid (or some other applet) coming from busybox (and not for the problematic cp, ls, mv binaried).

One of my concern is that distro's package busybox quite differently (different path, different applets, etc). Thsi test case would allow us to have some experience with busybox in our CI.

@devkontrol
devkontrol marked this pull request as draft August 10, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

base Issues related to the base module busybox Issues related to the busybox module docs github Issues related to .github man modules Issue tracker for all modules test Issues related to testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants