APPLIED: [SRU][R][PATCH 0/1] linux: dtbs_install fails on Resolute builders due to uutils install(1) EEXIST race under parallel make (LP: #2166356)
Edoardo Canepa
edoardo.canepa at canonical.com
Fri Sep 4 08:09:35 UTC 2026
Applied to R:linux/master-next. Thanks.
On 9/3/26 16:55, Edoardo Canepa wrote:
> BugLink: https://bugs.launchpad.net/bugs/2166356
>
> SRU Justification
>
> [Impact]
>
> Kernel source package builds for Resolute (26.04) fail intermittently
> during dtbs_install on Launchpad builders. The failure surfaces as:
>
> INSTALL .../device-tree/nuvoton/ma35d1-iot-512m.dtb
> INSTALL .../device-tree/nuvoton/ma35d1-som-256m.dtb
> INSTALL .../device-tree/nuvoton/nuvoton-npcm845-evb.dtb
> install: cannot create directory '.../device-tree/nuvoton'
> make[4]: *** [scripts/Makefile.dtbinst:23:
> .../nuvoton/ma35d1-iot-512m.dtb] Error 1
>
> The root cause is a race in the rust-coreutils implementation of
> install(1), which provides /usr/bin/install on Resolute. In uutils'
> `install -D`, parent-directory creation is done by stat_at() followed
> by mkdir_at() without retry: two concurrent invocations sharing a
> parent both observe NotFound before either issues mkdir_at(), the
> loser then receives EEXIST from the kernel and uutils bubbles it up
> as a hard error instead of treating an existing directory as success.
>
> scripts/Makefile.dtbinst hard-codes literal `install -D -m 0644`,
> one invocation per .dtb file:
>
> quiet_cmd_dtb_install = INSTALL $@
> cmd_dtb_install = install -D -m 0644 $< $@
>
> Under `make -j`, every .dtb inside a given vendor directory (e.g.
> device-tree/apple/, device-tree/nuvoton/) races on that directory's
> creation, and the build fails non-deterministically.
>
> Impact:
> - Series: Resolute (26.04) only.
> - Arches: any that enable do_dtbs=true (arm64, armhf); observed
> on arm64 Launchpad builders for linux 7.0.0-37.37.
> - Severity: hard build failure, blocks source package uploads.
>
> [Fix]
>
> Serialise the dtbs_install sub-make by forcing `-j1` for that single
> target in debian/rules.d/2-binary-arch.mk. All other targets in the
> package build ($(bldimg), modules, modules_install, headers_install)
> retain full parallelism via $(conc_level).
>
> A tree-side fix is not viable in the SRU timeframe:
>
> - scripts/Makefile.dtbinst hard-codes the literal `install`; there
> is no $(INSTALL) variable defined anywhere in the tree to hook.
> - Resolute ships no GNU coreutils install(1) that we could point
> to via an override even if the recipe were parametric.
> - Fixing uutils is out of scope; the upstream fix (uutils/coreutils
> PR #12429) is open but unmerged, and will need to land in
> rust-coreutils before Resolute can benefit.
>
> The workaround is intentionally minimal and self-documenting: an
> inline comment references the uutils issues so it can be reverted
> cleanly once #12429 lands in Resolute.
>
> [Test Case]
>
> Reproducer (without the patch):
>
> 1. On a Resolute build environment with rust-coreutils providing
> /usr/bin/install (default), obtain the linux source package
> and run:
> dpkg-buildpackage -B -aarm64 -j$(nproc)
> 2. Repeat 5-10 times. dtbs_install fails intermittently with
> "install: cannot create directory '.../device-tree/<vendor>'"
> and a non-zero exit from make[4].
>
> Verification (with the patch):
>
> 1. Same environment, same command. Run 10 consecutive builds.
> None fail in dtbs_install.
> 2. Confirm the resulting linux-image-* package contains the full
> set of .dtb files under
> usr/lib/firmware/<abi>-<flavour>/device-tree/
> matching the pre-patch layout (diff of installed file lists).
> 3. Wall-clock delta for dtbs_install between $(conc_level) and -j1
> is under 10s on a Launchpad builder (I/O-bound, short target).
>
> Additionally, a successful Launchpad rebuild of the affected source
> (linux 7.0.0-37.37) with the patch applied is the definitive test.
>
> [Where problems could occur]
>
> The change is one line: swap $(conc_level) for -j1 on the single
> `$(kmake) ... dtbs_install` invocation in
> debian/rules.d/2-binary-arch.mk. Scope of risk:
>
> - Build time: dtbs_install runs serially. In practice this is a
> few seconds on arm64/armhf; the target is I/O-bound.
> - No other build stage is touched; all other sub-makes still run
> at $(conc_level).
> - No change to compiler flags, config, ABI, module layout,
> installed artefacts, or package contents.
> - No effect on arches with do_dtbs != true (e.g. amd64), where
> the guarded block is not entered at all.
> - No runtime effect on end users; the change is confined to
> package build.
>
> If regressions do occur, they would manifest at build time (not on
> target systems) and can be reverted trivially by restoring
> $(conc_level).
>
> [Other Info]
>
> Upstream uutils references:
> - uutils/coreutils#12355 — install -D loses some files to EEXIST
> - uutils/coreutils#12429 — install: fix EEXIST race losing files
> in parallel install -D (open PR)
>
> This is a SAUCE patch (packaging-only, no upstream analogue) tagged
> appropriately in the subject. It should be dropped when uutils
> PR #12429 is merged and lands in Resolute's rust-coreutils; the
> revert is a one-line change to restore $(conc_level).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <https://lists.ubuntu.com/archives/kernel-team/attachments/20260904/9386c56e/attachment-0001.sig>
More information about the kernel-team
mailing list