From patchwork Mon Oct 24 11:31:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 9212 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp459213wru; Mon, 24 Oct 2022 06:39:06 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4+fQr+1wA9HNXust6c+R8THxvEIyMEkjcLiIQJOEgiKHRgTg1A5TIOX3xePz2a4AK2kqdc X-Received: by 2002:a05:6402:298d:b0:451:5fc5:d423 with SMTP id eq13-20020a056402298d00b004515fc5d423mr30327380edb.102.1666618746454; Mon, 24 Oct 2022 06:39:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666618746; cv=none; d=google.com; s=arc-20160816; b=mkdQFRUfwx2NTlNN5gQqRP13DtnvghklHZf8CsDTucN8zLG/qZxyCLdpBQXSK6xPkO ubn+blzObPGU61FT3FpMxB85FW26YaPKIlNCyAJIzAcP2RAQ5qlQe6PalWFYDVeAvTrg 4cjmA3U10t3sp6ZXzFQZ+Smd5wNp9/yzHtd1aKeH+F7McwmvQ8hn/zAAaiq/HX/qfRAm pQ16umhJUiZP5K/zJ6agHYgEEzwrEOQNlbpq0Nrnp4MVpYEl/3UkXuJsY+wWpBluhuQI nfda+vVgzEEFfSbZ2Icq6Y1tUABJ60vSxLjYkNGG3hKUkzNp8JySnNcBjqSKzToplfN+ RuaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=y3KBfCbCkTcOHLQw9ec194aTM3TVURTTsOGO+zjPtzs=; b=g5VAik2z2jbU6xX+DqsInsF5xPF+oGM13IdJMnpI5ABreyLrD2wQ/t5+VcdW9+vyrm FR49zk/Y7Gdj8oLDtEHQ+QurS+9/tnblH8TnPftVbrgDMSQq3EHf1Q4MwWxNStM0OqKB 2qQMltJbEqIzSZL4YmDMVCWkvMH0SGCecRZzE5zrgL51reDpxq+24sVotC5m5f2ZLz6V 1q/UXLfVXyHSzzk+SG3AjfrOW+On0ZFEjorXq3L49D8iQDth5MaCflF7ZHlsf9iUNaUe /2dQePumkhNGqhng+PSmvVLhTNfPoLGbnhD9sxnn8a1unk0Ujh/caGMalE4XRYlw4wNS d6IQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=MZNhZ3Iv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id t20-20020a1709066bd400b00783698dd8b4si23925144ejs.722.2022.10.24.06.38.41; Mon, 24 Oct 2022 06:39:06 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=MZNhZ3Iv; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236245AbiJXNfH (ORCPT + 99 others); Mon, 24 Oct 2022 09:35:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236269AbiJXNaS (ORCPT ); Mon, 24 Oct 2022 09:30:18 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C9F6ACA1D; Mon, 24 Oct 2022 05:33:28 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id E3C2361253; Mon, 24 Oct 2022 12:29:33 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 00613C433C1; Mon, 24 Oct 2022 12:29:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1666614573; bh=KwHi/Yz77vH5JpUvmQEm94H2dp2DiOF5mtJWc1mS1c4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MZNhZ3Iv9UOVknSDqrSkz1BqGsfCIp8aHDmcMom18AX7FcPo1/DHOM5sguaavMoXY WZJspw0Vw5rcou1mpUXHwMTa1ijv/cUrj1vqBwLxkucjpPjC11oEynyFivCsJE4n1Z eN5XHY60BNmJXH4kUw8L3FpO/wwoAGNSAa+sBlLA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ingo Molnar , Rob Herring , Masahiro Yamada , Nicolas Schier , Sasha Levin Subject: [PATCH 5.10 285/390] kbuild: remove the target in signal traps when interrupted Date: Mon, 24 Oct 2022 13:31:22 +0200 Message-Id: <20221024113035.087700162@linuxfoundation.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221024113022.510008560@linuxfoundation.org> References: <20221024113022.510008560@linuxfoundation.org> User-Agent: quilt/0.67 MIME-Version: 1.0 X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747576418716830714?= X-GMAIL-MSGID: =?utf-8?q?1747576418716830714?= From: Masahiro Yamada [ Upstream commit a7f3257da8a86b96fb9bf1bba40ae0bbd7f1885a ] When receiving some signal, GNU Make automatically deletes the target if it has already been changed by the interrupted recipe. If the target is possibly incomplete due to interruption, it must be deleted so that it will be remade from scratch on the next run of make. Otherwise, the target would remain corrupted permanently because its timestamp had already been updated. Thanks to this behavior of Make, you can stop the build any time by pressing Ctrl-C, and just run 'make' to resume it. Kbuild also relies on this feature, but it is equivalently important for any build systems that make decisions based on timestamps (if you want to support Ctrl-C reliably). However, this does not always work as claimed; Make immediately dies with Ctrl-C if its stderr goes into a pipe. [Test Makefile] foo: echo hello > $@ sleep 3 echo world >> $@ [Test Result] $ make # hit Ctrl-C echo hello > foo sleep 3 ^Cmake: *** Deleting file 'foo' make: *** [Makefile:3: foo] Interrupt $ make 2>&1 | cat # hit Ctrl-C echo hello > foo sleep 3 ^C$ # 'foo' is often left-over The reason is because SIGINT is sent to the entire process group. In this example, SIGINT kills 'cat', and 'make' writes the message to the closed pipe, then dies with SIGPIPE before cleaning the target. A typical bad scenario (as reported by [1], [2]) is to save build log by using the 'tee' command: $ make 2>&1 | tee log This can be problematic for any build systems based on Make, so I hope it will be fixed in GNU Make. The maintainer of GNU Make stated this is a long-standing issue and difficult to fix [3]. It has not been fixed yet as of writing. So, we cannot rely on Make cleaning the target. We can do it by ourselves, in signal traps. As far as I understand, Make takes care of SIGHUP, SIGINT, SIGQUIT, and SITERM for the target removal. I added the traps for them, and also for SIGPIPE just in case cmd_* rule prints something to stdout or stderr (but I did not observe an actual case where SIGPIPE was triggered). [Note 1] The trap handler might be worth explaining. rm -f $@; trap - $(sig); kill -s $(sig) $$ This lets the shell kill itself by the signal it caught, so the parent process can tell the child has exited on the signal. Generally, this is a proper manner for handling signals, in case the calling program (like Bash) may monitor WIFSIGNALED() and WTERMSIG() for WCE although this may not be a big deal here because GNU Make handles SIGHUP, SIGINT, SIGQUIT in WUE and SIGTERM in IUE. IUE - Immediate Unconditional Exit WUE - Wait and Unconditional Exit WCE - Wait and Cooperative Exit For details, see "Proper handling of SIGINT/SIGQUIT" [4]. [Note 2] Reverting 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files") would directly address [1], but it only saves if_changed_dep. As reported in [2], all commands that use redirection can potentially leave an empty (i.e. broken) target. [Note 3] Another (even safer) approach might be to always write to a temporary file, and rename it to $@ at the end of the recipe. > $(tmp-target) mv $(tmp-target) $@ It would require a lot of Makefile changes, and result in ugly code, so I did not take it. [Note 4] A little more thoughts about a pattern rule with multiple targets (or a grouped target). %.x %.y: %.z When interrupted, GNU Make deletes both %.x and %.y, while this solution only deletes $@. Probably, this is not a big deal. The next run of make will execute the rule again to create $@ along with the other files. [1]: https://lore.kernel.org/all/YLeot94yAaM4xbMY@gmail.com/ [2]: https://lore.kernel.org/all/20220510221333.2770571-1-robh@kernel.org/ [3]: https://lists.gnu.org/archive/html/help-make/2021-06/msg00001.html [4]: https://www.cons.org/cracauer/sigint.html Fixes: 392885ee82d3 ("kbuild: let fixdep directly write to .*.cmd files") Reported-by: Ingo Molnar Reported-by: Rob Herring Signed-off-by: Masahiro Yamada Tested-by: Ingo Molnar Reviewed-by: Nicolas Schier Signed-off-by: Sasha Levin --- scripts/Kbuild.include | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include index 0d6e11820791..25696de8114a 100644 --- a/scripts/Kbuild.include +++ b/scripts/Kbuild.include @@ -179,8 +179,29 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),\ quiet_redirect := silent_redirect := exec >/dev/null; +# Delete the target on interruption +# +# GNU Make automatically deletes the target if it has already been changed by +# the interrupted recipe. So, you can safely stop the build by Ctrl-C (Make +# will delete incomplete targets), and resume it later. +# +# However, this does not work when the stderr is piped to another program, like +# $ make >&2 | tee log +# Make dies with SIGPIPE before cleaning the targets. +# +# To address it, we clean the target in signal traps. +# +# Make deletes the target when it catches SIGHUP, SIGINT, SIGQUIT, SIGTERM. +# So, we cover them, and also SIGPIPE just in case. +# +# Of course, this is unneeded for phony targets. +delete-on-interrupt = \ + $(if $(filter-out $(PHONY), $@), \ + $(foreach sig, HUP INT QUIT TERM PIPE, \ + trap 'rm -f $@; trap - $(sig); kill -s $(sig) $$$$' $(sig);)) + # printing commands -cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(cmd_$(1)) +cmd = @set -e; $(echo-cmd) $($(quiet)redirect) $(delete-on-interrupt) $(cmd_$(1)) ### # if_changed - execute command if any prerequisite is newer than