Skip to content

[platform-modules]: tolerate kernel-headers race during clean#27524

Closed
bhouse-nexthop wants to merge 1 commit into
sonic-net:masterfrom
bhouse-nexthop:bhouse.fix-platform-modules-kernel-headers-race
Closed

[platform-modules]: tolerate kernel-headers race during clean#27524
bhouse-nexthop wants to merge 1 commit into
sonic-net:masterfrom
bhouse-nexthop:bhouse.fix-platform-modules-kernel-headers-race

Conversation

@bhouse-nexthop

Copy link
Copy Markdown
Collaborator

Why I did it

Multiple vendor sonic-platform-modules-* debian/rules files have an override_dh_auto_clean (or override_dh_clean) that iterates over a list of per-platform module dirs and runs:

make -C \$(KERNEL_SRC)/build M=\$(MOD_SRC_DIR)/\${mod}/modules clean

per platform. The iteration takes seconds (Dell has 18 platforms; others fewer). Under parallel builds (e.g. SONIC_BUILD_JOBS=12), another concurrent platform-modules-* recipe can declare the linux-headers-* debs as prerequisites and trigger SONiC's dep_install / dep_uninstall flow. If linux-headers-* is momentarily uninstalled (purge-then-reinstall) while this iteration is mid-flight, the next make -C /lib/modules/\$KVERSION/build ... fails fast with No such file or directory on the build symlink, aborting the entire recipe.

Real-world failure observed during a Broadcom build with SONIC_BUILD_JOBS=12:

make[3]: *** /lib/modules/6.12.41+deb13-sonic-amd64/build: No such file or directory.  Stop.
make[3]: Leaving directory '/sonic/platform/broadcom/sonic-platform-modules-dell'
make[2]: *** [debian/rules:101: override_dh_auto_clean] Error 2
make[1]: *** [Makefile:22: /sonic/target/debs/trixie/platform-modules-z9100_1.1_amd64.deb] Error 2
make: *** [slave.mk:915: target/debs/trixie/platform-modules-z9100_1.1_amd64.deb] Error 1

The clean step's purpose is to remove stale in-tree build artifacts (Module.symvers, *.o, *.mod.c). If a missed clean leaves those behind, the very next override_dh_auto_build regenerates them deterministically from kbuild — a missed clean is harmless. An aborted clean, on the other hand, kills the recipe.

Work item tracking
  • Microsoft ADO (number only): n/a

How I did it

Wrapped each racy make -C \$(KERNEL_SRC)/build M=... clean (or \$(KERNEL_BUILD) M=...) with || true so a transient missing-or-mid-purge kernel-headers package no longer fails the recipe. One-line diff per vendor file, 16 files total.

Two of the affected recipes (aspeed/nexthop, broadcom/nexthop) already have an outer if [ -d \"\$(KERNEL_BUILD)\" ] ... guard, but the dir can still disappear between that check and the actual make execution — the || true closes that race window for them too.

Affected files:

  • platform/aspeed/sonic-platform-modules-nexthop/debian/rules
  • platform/barefoot/sonic-platform-modules-ingrasys/debian/rules
  • platform/barefoot/sonic-platform-modules-netberg/debian/rules
  • platform/broadcom/sonic-platform-modules-dell/debian/rules
  • platform/broadcom/sonic-platform-modules-delta/debian/rules
  • platform/broadcom/sonic-platform-modules-ingrasys/debian/rules
  • platform/broadcom/sonic-platform-modules-inventec/debian/rules
  • platform/broadcom/sonic-platform-modules-mitac/debian/rules
  • platform/broadcom/sonic-platform-modules-nexthop/debian/rules
  • platform/centec/sonic-platform-modules-e582/debian/rules
  • platform/marvell-teralynx/sonic-platform-modules-cel/debian/rules
  • platform/marvell-teralynx/sonic-platform-modules-delta/debian/rules
  • platform/marvell-teralynx/sonic-platform-modules-netberg/debian/rules
  • platform/marvell-teralynx/sonic-platform-modules-supermicro/debian/rules
  • platform/nephos/sonic-platform-modules-accton/debian/rules
  • platform/nephos/sonic-platform-modules-ingrasys/debian/rules

How to verify it

  1. Trigger a parallel build that includes any of the affected platform-modules recipes (e.g. `make PLATFORM=broadcom SONIC_BUILD_JOBS=12 target/sonic-broadcom.bin`).
  2. Without the patch, the race surfaces intermittently — most commonly on Dell (largest iteration) or Delta. Frequency increases with build concurrency.
  3. With the patch in place, the iteration completes even if the kernel-build symlink momentarily disappears; the in-tree artifacts are regenerated by the subsequent build step.

Alternatively, reproduce more deterministically by injecting an artificial sleep into one platform's clean step while another concurrently runs `dpkg --remove linux-headers-$KVERSION-sonic-amd64` then `dpkg --install ...`. Without the patch the clean fails; with the patch it does not.

Which release branch to backport (provide reason below if selected)

n/a (master-only fix; the race exists wherever the parallel-build infra runs).

Tested branch (Please provide the tested image version)

  • master — observed the race fail builds at SONIC_BUILD_JOBS=12 prior to the patch; subsequent retries succeed once past the affected window. Patch eliminates the failure mode without changing the clean output for builds that don't race.

Description for the changelog

`platform-modules`: tolerate concurrent-build races against the linux-headers package during the per-platform clean iteration. Prevents intermittent build failures with `make[3]: *** /lib/modules/$KVERSION/build: No such file or directory` under parallel `SONIC_BUILD_JOBS`.

Link to config_db schema for YANG module changes

n/a

A picture of a cute animal (not mandatory but encouraged)

n/a

Wrap the per-module `make -C $(KERNEL_SRC)/build M=... clean` in
`override_dh_auto_clean` with `|| true` so a concurrent
platform-modules-* recipe's transient uninstall/reinstall of the
linux-headers package can't fail the recipe.

The race:

  1. dpkg-buildpackage runs `debian/rules clean` at the start of
     every build pass.
  2. Each vendor's override_dh_auto_clean iterates over its
     MODULE_DIRS (Dell has 18 platforms, Delta has several, etc.)
     and runs `make -C /lib/modules/$KVERSION/build M=<path> clean`
     per platform. The iteration takes seconds-to-tens-of-seconds.
  3. Under parallel builds, another platform-modules-* recipe may
     declare the linux-headers .debs as prerequisites and trigger
     SONiC's dep_install/uninstall flow concurrently. If the
     linux-headers package is uninstalled (even momentarily,
     between dpkg purge and reinstall) while this iteration is
     mid-flight, the next `make -C /lib/modules/$KVERSION/build`
     fails fast with "No such file or directory" on the build
     symlink, aborting the whole recipe.

The race is real-world reproducible under SONIC_BUILD_JOBS=12 on
master. Observed during a Broadcom build:

    make[3]: *** /lib/modules/6.12.41+deb13-sonic-amd64/build: \
        No such file or directory.  Stop.
    make[2]: *** [debian/rules:101: override_dh_auto_clean] Error 2
    [...]
    make: *** [slave.mk:915: target/debs/trixie/\
        platform-modules-z9100_1.1_amd64.deb] Error 1

The clean step's job is to remove stale build artifacts from the
in-tree module source dirs (Module.symvers, *.o, *.mod.c). If the
kernel build dir is briefly missing and the kernel-make-clean is
skipped, the next `override_dh_auto_build` step rebuilds those
artifacts from scratch anyway — kbuild regenerates them
deterministically. So a missed clean is harmless; an aborted clean
is not.

Patches every vendor `debian/rules` that has the same iteration
pattern:

    platform/aspeed/sonic-platform-modules-nexthop
    platform/barefoot/sonic-platform-modules-ingrasys
    platform/barefoot/sonic-platform-modules-netberg
    platform/broadcom/sonic-platform-modules-dell
    platform/broadcom/sonic-platform-modules-delta
    platform/broadcom/sonic-platform-modules-ingrasys
    platform/broadcom/sonic-platform-modules-inventec
    platform/broadcom/sonic-platform-modules-mitac
    platform/broadcom/sonic-platform-modules-nexthop
    platform/centec/sonic-platform-modules-e582
    platform/marvell-teralynx/sonic-platform-modules-cel
    platform/marvell-teralynx/sonic-platform-modules-delta
    platform/marvell-teralynx/sonic-platform-modules-netberg
    platform/marvell-teralynx/sonic-platform-modules-supermicro
    platform/nephos/sonic-platform-modules-accton
    platform/nephos/sonic-platform-modules-ingrasys

Two of the patched recipes (aspeed/nexthop, broadcom/nexthop)
already have an outer `if [ -d "$(KERNEL_BUILD)" ] ...` guard, but
the dir can disappear between the check and the make execution —
the `|| true` closes that race window for them too.

Signed-off-by: Brad House <bhouse@nexthop.ai>
@bhouse-nexthop bhouse-nexthop requested a review from lguohan as a code owner May 23, 2026 16:51
@mssonicbld

Copy link
Copy Markdown
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@bhouse-nexthop

Copy link
Copy Markdown
Collaborator Author

Withdrawing in favor of sonic-net/saibcm-modules#39, which fixes the actual root cause.

After more investigation, the kernel-headers symlink wasn't disappearing due to dpkg install/uninstall churn or depmod (depmod doesn't touch the build/source symlinks at all). The failure is caused by platform/broadcom/saibcm-modules-dnx/debian/rules (and the same pattern in opennsl-modules-dnx) doing a non-atomic rm /lib/modules/.../build followed by ln -s ... — leaving a millisecond-scale window where the symlink doesn't exist. The sibling non-DNX recipe saibcm-modules/debian/rules already uses ln -sfn (single rename(2) syscall, atomic). The DNX branches just missed picking up that fix.

The || true defensive change in this PR would mask the symptom but also hide legitimate kernel-headers misconfiguration; better to fix the source.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants