Linux kbuild/kconfig development
 help / color / mirror / Atom feed
* [PATCH RFC] kbuild: enable pipefail for commands where possible
@ 2026-10-14  8:30 Thomas Weißschuh
  2026-10-14 21:40 ` Nathan Chancellor
  2026-10-15  8:36 ` sashiko-bot
  0 siblings, 2 replies; 4+ messages in thread
From: Thomas Weißschuh @ 2026-10-14  8:30 UTC (permalink / raw)
  To: Nathan Chancellor, Nicolas Schier
  Cc: linux-kbuild, linux-kernel, Nam Cao, kernel test robot,
	Thomas Weißschuh

The exit status of a shell pipeline by default only depends on the exit
status of its last command. If an earlier command fails this is silently
ignored. In this case the build continues operating on intermediate
state, potentially leading to confusing follow-up failures.

The 'pipefail' option can be used to exit the pipeline with an error as
soon as a single of its command fails which 'set -e' will elevate to
error exit of the whole command.

'pipefail' has been only standardized in POSIX 2024, but it is supported
by many shells anyways, including bash and dash. To avoid issues with
shells not implementing it, ignore failures silently.

Reported-by: kernel test robot <lkp@intel.com>
Link: https://lore.kernel.org/oe-kbuild-all/202610131613.BpOi6VPp-lkp@intel.com/
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 scripts/Kbuild.include | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 8c311b997e24..1975d2739cdb 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -149,8 +149,11 @@ delete-on-interrupt = \
 		$(foreach sig, HUP INT QUIT TERM PIPE, \
 			trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);))
 
+# try to enable pipefail
+try-pipefail = set -o pipefail || true 2>/dev/null
+
 # print and execute commands
-cmd = @$(if $(cmd_$(1)),set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)
+cmd = @$(if $(cmd_$(1)),$(try-pipefail); set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)
 
 ###
 # if_changed      - execute command if any prerequisite is newer than

---
base-commit: 27286bf096c51df05eec6664f18b945f8dd61c0e
change-id: 20261013-kbuild-error-propagation-8ab5f649ff36

Best regards,
--  
Thomas Weißschuh <thomas.weissschuh@linutronix.de>


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH RFC] kbuild: enable pipefail for commands where possible
  2026-10-14  8:30 [PATCH RFC] kbuild: enable pipefail for commands where possible Thomas Weißschuh
@ 2026-10-14 21:40 ` Nathan Chancellor
  2026-10-15 10:15   ` Thomas Weißschuh
  2026-10-15  8:36 ` sashiko-bot
  1 sibling, 1 reply; 4+ messages in thread
From: Nathan Chancellor @ 2026-10-14 21:40 UTC (permalink / raw)
  To: Thomas Weißschuh
  Cc: Nicolas Schier, linux-kbuild, linux-kernel, Nam Cao,
	kernel test robot

On Wed, Oct 14, 2026 at 10:30:30AM +0200, Thomas Weißschuh wrote:
> The exit status of a shell pipeline by default only depends on the exit
> status of its last command. If an earlier command fails this is silently
> ignored. In this case the build continues operating on intermediate
> state, potentially leading to confusing follow-up failures.
> 
> The 'pipefail' option can be used to exit the pipeline with an error as
> soon as a single of its command fails which 'set -e' will elevate to
> error exit of the whole command.
> 
> 'pipefail' has been only standardized in POSIX 2024, but it is supported
> by many shells anyways, including bash and dash. To avoid issues with
> shells not implementing it, ignore failures silently.
> 
> Reported-by: kernel test robot <lkp@intel.com>
> Link: https://lore.kernel.org/oe-kbuild-all/202610131613.BpOi6VPp-lkp@intel.com/
> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>

This is probably the right thing to do but it makes me nervous. pipefail
is very easy to hold wrong mainly because of SIGPIPE:

  $ cat test.sh
  set -o pipefail

  yes | head -n +50

  $ bash test.sh
  ...

  $ echo $?
  141

and debugging that is unlikely to be obvious (but maybe it will because
the error would be 141).

> ---
>  scripts/Kbuild.include | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
> index 8c311b997e24..1975d2739cdb 100644
> --- a/scripts/Kbuild.include
> +++ b/scripts/Kbuild.include
> @@ -149,8 +149,11 @@ delete-on-interrupt = \
>  		$(foreach sig, HUP INT QUIT TERM PIPE, \
>  			trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);))
>  
> +# try to enable pipefail
> +try-pipefail = set -o pipefail || true 2>/dev/null
> +
>  # print and execute commands
> -cmd = @$(if $(cmd_$(1)),set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)
> +cmd = @$(if $(cmd_$(1)),$(try-pipefail); set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)
>  
>  ###
>  # if_changed      - execute command if any prerequisite is newer than
> 
> ---
> base-commit: 27286bf096c51df05eec6664f18b945f8dd61c0e
> change-id: 20261013-kbuild-error-propagation-8ab5f649ff36
> 
> Best regards,
> --  
> Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> 

-- 
Cheers,
Nathan

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH RFC] kbuild: enable pipefail for commands where possible
  2026-10-14  8:30 [PATCH RFC] kbuild: enable pipefail for commands where possible Thomas Weißschuh
  2026-10-14 21:40 ` Nathan Chancellor
@ 2026-10-15  8:36 ` sashiko-bot
  1 sibling, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-10-15  8:36 UTC (permalink / raw)
  To: Thomas Weißschuh, Nathan Chancellor, Nicolas Schier
  Cc: linux-kbuild, Nam Cao, kernel test robot

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] kbuild: global pipefail breaks early-exit grep -q pipelines
- [Medium] kbuild: try-pipefail redirection fails to silence errors on unsupported shells
--

commit 144ca777192e6140faa2332a17fb19531eec93bd
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>

kbuild: enable pipefail for commands where possible

Enables the shell pipefail option for Kbuild commands where supported, so
that failures of earlier commands in a pipeline are not silently ignored.

Link: https://lore.kernel.org/oe-kbuild-all/202610131613.BpOi6VPp-lkp@intel.com/

> diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
> index 8c311b997e246..1975d2739cdb0 100644
> --- a/scripts/Kbuild.include
> +++ b/scripts/Kbuild.include
> @@ -149,8 +149,11 @@ delete-on-interrupt = \
>  		$(foreach sig, HUP INT QUIT TERM PIPE, \
>  			trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);))
>  
> +# try to enable pipefail
> +try-pipefail = set -o pipefail || true 2>/dev/null

[Severity: Medium]
In POSIX shell grammar, the || operator separates simple commands, meaning
the 2>/dev/null redirection applies exclusively to the true command, not
the set command.

Will this cause build log pollution with 'Illegal option' errors for almost
every compiled file on systems where the shell lacks pipefail support (such
as older versions of dash or minimal busybox ash)?

>  # print and execute commands
> -cmd = @$(if $(cmd_$(1)),set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)
> +cmd = @$(if $(cmd_$(1)),$(try-pipefail); set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)

[Severity: High]
Kbuild relies on shell conditionals using pipelines that terminate early,
such as the module symbol version generation in scripts/Makefile.build:

if $(NM) $@ 2>/dev/null | grep -q ' __export_symbol_'; then

When grep -q finds a match, it immediately closes its standard input and
exits with 0, causing the upstream command to receive SIGPIPE and exit
with a non-zero status.

With set -o pipefail injected globally into cmd, the pipeline will evaluate
to the non-zero status of the upstream command (e.g., 141), causing the
condition to evaluate to false.

Does this silently disable critical build-time validation and logic, such
as module symbol versioning or vDSO dynamic relocation checks?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261014-kbuild-error-propagation-v1-1-573adaa0a076@linutronix.de?part=1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH RFC] kbuild: enable pipefail for commands where possible
  2026-10-14 21:40 ` Nathan Chancellor
@ 2026-10-15 10:15   ` Thomas Weißschuh
  0 siblings, 0 replies; 4+ messages in thread
From: Thomas Weißschuh @ 2026-10-15 10:15 UTC (permalink / raw)
  To: Nathan Chancellor
  Cc: Nicolas Schier, linux-kbuild, linux-kernel, Nam Cao,
	kernel test robot

On Wed, Oct 14, 2026 at 02:40:43PM -0700, Nathan Chancellor wrote:
> On Wed, Oct 14, 2026 at 10:30:30AM +0200, Thomas Weißschuh wrote:
> > The exit status of a shell pipeline by default only depends on the exit
> > status of its last command. If an earlier command fails this is silently
> > ignored. In this case the build continues operating on intermediate
> > state, potentially leading to confusing follow-up failures.
> > 
> > The 'pipefail' option can be used to exit the pipeline with an error as
> > soon as a single of its command fails which 'set -e' will elevate to
> > error exit of the whole command.
> > 
> > 'pipefail' has been only standardized in POSIX 2024, but it is supported
> > by many shells anyways, including bash and dash. To avoid issues with
> > shells not implementing it, ignore failures silently.
> > 
> > Reported-by: kernel test robot <lkp@intel.com>
> > Link: https://lore.kernel.org/oe-kbuild-all/202610131613.BpOi6VPp-lkp@intel.com/
> > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> 
> This is probably the right thing to do but it makes me nervous. pipefail
> is very easy to hold wrong mainly because of SIGPIPE:
> 
>   $ cat test.sh
>   set -o pipefail
> 
>   yes | head -n +50
> 
>   $ bash test.sh
>   ...
> 
>   $ echo $?
>   141
> 
> and debugging that is unlikely to be obvious (but maybe it will because
> the error would be 141).

It actually breaks modversions quite badly. And it is not obvious to debug
as that uses the pipe in an `if` statement which swallows the 141 silently.

Not sure what to do here.

Maybe we just provide `try-pipefail` so users can opt-in where it makes sense.


Also

try-pipefail = set -o pipefail || true 2>/dev/null

should have been

try-pipefail = set -o pipefail 2>/dev/null || true

> > ---
> >  scripts/Kbuild.include | 5 ++++-
> >  1 file changed, 4 insertions(+), 1 deletion(-)
> > 
> > diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
> > index 8c311b997e24..1975d2739cdb 100644
> > --- a/scripts/Kbuild.include
> > +++ b/scripts/Kbuild.include
> > @@ -149,8 +149,11 @@ delete-on-interrupt = \
> >  		$(foreach sig, HUP INT QUIT TERM PIPE, \
> >  			trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);))
> >  
> > +# try to enable pipefail
> > +try-pipefail = set -o pipefail || true 2>/dev/null
> > +
> >  # print and execute commands
> > -cmd = @$(if $(cmd_$(1)),set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)
> > +cmd = @$(if $(cmd_$(1)),$(try-pipefail); set -e; $($(quiet)log_print) $(delete-on-interrupt) $(cmd_$(1)),:)
> >  
> >  ###
> >  # if_changed      - execute command if any prerequisite is newer than

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-15 10:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-14  8:30 [PATCH RFC] kbuild: enable pipefail for commands where possible Thomas Weißschuh
2026-10-14 21:40 ` Nathan Chancellor
2026-10-15 10:15   ` Thomas Weißschuh
2026-10-15  8:36 ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox