From: "Darrick J. Wong" <djwong@kernel.org>
To: Zorro Lang <zlang@redhat.com>
Cc: dchinner@redhat.com, fstests@vger.kernel.org, linux-xfs@vger.kernel.org
Subject: Re: [PATCH v3.1 14/34] common: fix pkill by running test program in a separate session
Date: Sat, 15 Feb 2025 08:54:47 -0800 [thread overview]
Message-ID: <20250215165447.GH21799@frogsfrogsfrogs> (raw)
In-Reply-To: <20250215132232.tva2tsmobpttbn6z@dell-per750-06-vm-08.rhts.eng.pek2.redhat.com>
On Sat, Feb 15, 2025 at 09:22:32PM +0800, Zorro Lang wrote:
> On Fri, Feb 14, 2025 at 01:13:07PM -0800, Darrick J. Wong wrote:
> > From: Darrick J. Wong <djwong@kernel.org>
> >
> > Run each test program with a separate session id so that we can tell
> > pkill to kill all processes of a given name, but only within our own
> > session id. This /should/ suffice to run multiple fstests on the same
> > machine without one instance shooting down processes of another
> > instance.
> >
> > This fixes a general problem with using "pkill --parent" -- if the
> > process being targeted is not a direct descendant of the bash script
> > calling pkill, then pkill will not do anything. The scrub stress tests
> > make use of multiple background subshells, which is how a ^C in the
> > parent process fails to result in fsx/fsstress being killed.
> >
> > This is necessary to fix SOAK_DURATION runtime constraints for all the
> > scrub stress tests. However, there is a cost -- the test program no
> > longer runs with the same controlling tty as ./check, which means that
> > ^Z doesn't work and SIGINT/SIGQUIT are set to SIG_IGN. IOWs, if a test
> > wants to kill its subprocesses, it must use another signal such as
> > SIGPIPE. Fortunately, bash doesn't whine about children dying due to
> > fatal signals if the children run in a different session id.
> > Unfortunately we have to let it run the test as a background process for
> > bash to handle SIGINT, and SIGSTOP no longer works properly.
> >
> > This solution is a bit crap, and I have a better solution for it in the
> > next patch that uses private pid and mount namespaces. Unfortunately,
> > that solution adds new minimum requirements for running fstests and
> > removing previously supported configurations abruptly during a bug fix
> > is not appropriate behavior.
> >
> > I also explored alternate designs, and this was the least unsatisfying:
> >
> > a) Setting the process group didn't work because background subshells
> > are assigned a new group id.
> >
> > b) Constraining the pkill/pgrep search to a cgroup could work, but it
> > seems that procps has only recently (~2023) gained the ability to filter
> > on a cgroup. Furthermore, we'd have to set up a cgroup in which to run
> > the fstest. The last decade has been rife with user bug reports
> > complaining about chaos resulting from multiple pieces of software (e.g.
> > Docker, systemd, etc.) deciding that they own the entire cgroup
> > structure without having any means to enforce that statement. We should
> > not wade into that mess.
> >
> > c) Putting test subprocesses in a systemd sub-scope and telling systemd
> > to kill the sub-scope could work because ./check can already use it to
> > ensure that all child processes of a test are killed. However, this is
> > an *optional* feature, which means that we'd have to require systemd.
> >
> > d) Constraining the pkill/pgrep search to a particular pid namespace
> > could work, but we already have tests that set up their own mount
> > namespaces, which means the constrained pgrep will not find all child
> > processes of a test. Though this hasn't been born out through testing?
> >
> > e) Constraining to any other type of namespace (uts, pid, etc) might not
> > work because those namespaces might not be enabled. However, combining
> > a private pid and mount namespace to isolate tests from each other seems
> > to work better than session ids. This is coming in a subsequent patch,
> > but to avoid breaking older systems, we will use this as an immediately
> > deprecated fallback.
> >
> > f) Revert check-parallel and go back to one fstests instance per system.
> > Zorro already chose not to revert.
> >
> > So. Change _run_seq to create a the ./$seq process with a new session
> > id, update _su calls to use the same session as the parent test, update
> > all the pkill sites to use a wrapper so that we only target processes
> > created by *this* instance of fstests, and update SIGINT to SIGPIPE.
> >
> > Cc: <fstests@vger.kernel.org> # v2024.12.08
> > Fixes: 8973af00ec212f ("fstests: cleanup fsstress process management")
> > Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> > Reviewed-by: Dave Chinner <dchinner@redhat.com>
> > ---
> > v13.1: add tools/Makefile bit per maintainer request
> > ---
> > check | 40 ++++++++++++++++++++++++++++++++++------
> > common/fuzzy | 6 +++---
> > common/rc | 6 ++++--
> > tools/Makefile | 5 ++++-
> > tools/run_setsid | 22 ++++++++++++++++++++++
> > 5 files changed, 67 insertions(+), 12 deletions(-)
> > create mode 100755 tools/run_setsid
> >
> > diff --git a/check b/check
> > index 6f68ebd47c75c1..ef8a8c3b31b3e6 100755
> > --- a/check
> > +++ b/check
> > @@ -698,18 +698,46 @@ _adjust_oom_score -500
> > # systemd doesn't automatically remove transient scopes that fail to terminate
> > # when systemd tells them to terminate (e.g. programs stuck in D state when
> > # systemd sends SIGKILL), so we use reset-failed to tear down the scope.
> > +#
> > +# Use setsid to run the test program with a separate session id so that we
> > +# can pkill only the processes started by this test.
> > _run_seq() {
> > - local cmd=(bash -c "test -w ${OOM_SCORE_ADJ} && echo 250 > ${OOM_SCORE_ADJ}; exec ./$seq")
> > + local res
> > + unset CHILDPID
> > + unset FSTESTS_ISOL # set by tools/run_seq_*
> >
> > if [ -n "${HAVE_SYSTEMD_SCOPES}" ]; then
> > local unit="$(systemd-escape "fs$seq").scope"
> > systemctl reset-failed "${unit}" &> /dev/null
> > - systemd-run --quiet --unit "${unit}" --scope "${cmd[@]}"
> > + systemd-run --quiet --unit "${unit}" --scope \
> > + ./tools/run_setsid "./$seq" &
> > + CHILDPID=$!
> > + wait
> > res=$?
> > + unset CHILDPID
> > systemctl stop "${unit}" &> /dev/null
> > - return "${res}"
> > else
> > - "${cmd[@]}"
> > + # bash won't run the SIGINT trap handler while there are
> > + # foreground children in a separate session, so we must run
> > + # the test in the background and wait for it.
> > + ./tools/run_setsid "./$seq" &
> > + CHILDPID=$!
> > + wait
> > + res=$?
> > + unset CHILDPID
> > + fi
> > +
> > + return $res
> > +}
> > +
> > +_kill_seq() {
> > + if [ -n "$CHILDPID" ]; then
> > + # SIGPIPE will kill all the children (including fsstress)
> > + # without bash logging fatal signal termination messages to the
> > + # console
> > + pkill -PIPE --session "$CHILDPID"
> > + wait
> > + unset CHILDPID
> > fi
> > }
> >
> > @@ -718,9 +746,9 @@ _prepare_test_list
> > fstests_start_time="$(date +"%F %T")"
> >
> > if $OPTIONS_HAVE_SECTIONS; then
> > - trap "_summary; exit \$status" 0 1 2 3 15
> > + trap "_kill_seq; _summary; exit \$status" 0 1 2 3 15
> > else
> > - trap "_wrapup; exit \$status" 0 1 2 3 15
> > + trap "_kill_seq; _wrapup; exit \$status" 0 1 2 3 15
> > fi
> >
> > function run_section()
> > diff --git a/common/fuzzy b/common/fuzzy
> > index e3e1838b5fee12..f4cc5e5c848f9f 100644
> > --- a/common/fuzzy
> > +++ b/common/fuzzy
> > @@ -1205,9 +1205,9 @@ _scratch_xfs_stress_scrub_cleanup() {
> >
> > echo "Killing stressor processes at $(date)" >> $seqres.full
> > _kill_fsstress
> > - _pkill -PIPE --parent $$ xfs_io >> $seqres.full 2>&1
> > - _pkill -PIPE --parent $$ fsx >> $seqres.full 2>&1
> > - _pkill -PIPE --parent $$ xfs_scrub >> $seqres.full 2>&1
> > + _pkill --echo -PIPE xfs_io >> $seqres.full 2>&1
> > + _pkill --echo -PIPE fsx >> $seqres.full 2>&1
> > + _pkill --echo -PIPE xfs_scrub >> $seqres.full 2>&1
> >
> > # Tests are not allowed to exit with the scratch fs frozen. If we
> > # started a fs freeze/thaw background loop, wait for that loop to exit
> > diff --git a/common/rc b/common/rc
> > index bc64e080fe1fc1..f2fbe15104d7ba 100644
> > --- a/common/rc
> > +++ b/common/rc
> > @@ -33,7 +33,7 @@ _test_sync()
> > # Kill only the processes started by this test.
> > _pkill()
> > {
> > - pkill "$@"
> > + pkill --session 0 "$@"
> > }
> >
> > # Common execution handling for fsstress invocation.
> > @@ -2732,9 +2732,11 @@ _require_user_exists()
> > [ "$?" == "0" ] || _notrun "$user user not defined."
> > }
> >
> > +# Run all non-root processes in the same session as the root. Believe it or
> > +# not, passing $SHELL in this manner works both for "su" and "su -c cmd".
> > _su()
> > {
> > - su "$@"
> > + su --session-command $SHELL "$@"
> > }
> >
> > # check if a user exists and is able to execute commands.
> > diff --git a/tools/Makefile b/tools/Makefile
> > index 3ee532a7e563a9..4e42db4ad8b12d 100644
> > --- a/tools/Makefile
> > +++ b/tools/Makefile
> > @@ -6,12 +6,15 @@ TOPDIR = ..
> > include $(TOPDIR)/include/builddefs
> >
> > TOOLS_DIR = tools
> > +helpers=\
>
> This looks good to me, just not sure if it would be better to use
> uppercase letters (HELPERS) at here, as I saw other variables in
> xfstests' Makefile are uppercase.
I picked lowercase for this variable because I thought it would be a
local variable that should only ever exist within the scope of
tools/Makefile. IOWs, I don't see needing to export it to subprocesses.
> Anyway, that's not big change. If you agree, I can help to change
> that when I merge it.
<shrug> I'm ok with you changing it.
> Reviewed-by: Zorro Lang <zlang@redhat.com>
Thanks!
--D
> Thanks,
> Zorro
>
> > + run_setsid
> >
> > include $(BUILDRULES)
> >
> > -default:
> > +default: $(helpers)
> >
> > install: default
> > $(INSTALL) -m 755 -d $(PKG_LIB_DIR)/$(TOOLS_DIR)
> > + $(INSTALL) -m 755 $(helpers) $(PKG_LIB_DIR)/$(TOOLS_DIR)
> >
> > install-dev install-lib:
> > diff --git a/tools/run_setsid b/tools/run_setsid
> > new file mode 100755
> > index 00000000000000..5938f80e689255
> > --- /dev/null
> > +++ b/tools/run_setsid
> > @@ -0,0 +1,22 @@
> > +#!/bin/bash
> > +
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2025 Oracle. All Rights Reserved.
> > +#
> > +# Try starting things in a new process session so that test processes have
> > +# something with which to filter only their own subprocesses.
> > +
> > +if [ -n "${FSTESTS_ISOL}" ]; then
> > + # Allow the test to become a target of the oom killer
> > + oom_knob="/proc/self/oom_score_adj"
> > + test -w "${oom_knob}" && echo 250 > "${oom_knob}"
> > +
> > + exec "$@"
> > +fi
> > +
> > +if [ -z "$1" ] || [ "$1" = "--help" ]; then
> > + echo "Usage: $0 command [args...]"
> > + exit 1
> > +fi
> > +
> > +FSTESTS_ISOL=setsid exec setsid "$0" "$@"
> >
>
>
next prev parent reply other threads:[~2025-02-15 16:54 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-12 3:30 [PATCHSET v3] fstests: random fixes for v2025.02.02 Darrick J. Wong
2025-02-12 3:30 ` [PATCH 01/34] generic/476: fix fsstress process management Darrick J. Wong
2025-02-12 3:31 ` [PATCH 02/34] metadump: make non-local function variables more obvious Darrick J. Wong
2025-02-12 3:31 ` [PATCH 03/34] metadump: fix cleanup for v1 metadump testing Darrick J. Wong
2025-02-12 3:31 ` [PATCH 04/34] generic/019: don't fail if fio crashes while shutting down Darrick J. Wong
2025-02-12 3:31 ` [PATCH 05/34] fuzzy: do not set _FSSTRESS_PID when exercising fsx Darrick J. Wong
2025-02-12 3:32 ` [PATCH 06/34] common/rc: revert recursive unmount in _clear_mount_stack Darrick J. Wong
2025-02-12 3:32 ` [PATCH 07/34] common/dump: don't replace pids arbitrarily Darrick J. Wong
2025-02-12 3:32 ` [PATCH 08/34] common/populate: correct the parent pointer name creation formulae Darrick J. Wong
2025-02-12 3:33 ` [PATCH 09/34] generic/759,760: fix MADV_COLLAPSE detection and inclusion Darrick J. Wong
2025-02-12 18:31 ` Joanne Koong
2025-02-12 3:33 ` [PATCH 10/34] generic/759,760: skip test if we can't set up a hugepage for IO Darrick J. Wong
2025-02-12 18:39 ` Joanne Koong
2025-02-12 3:33 ` [PATCH 11/34] common/rc: create a wrapper for the su command Darrick J. Wong
2025-02-12 3:33 ` [PATCH 12/34] fuzzy: kill subprocesses with SIGPIPE, not SIGINT Darrick J. Wong
2025-02-12 4:45 ` Dave Chinner
2025-02-12 6:05 ` Darrick J. Wong
2025-02-12 6:10 ` Darrick J. Wong
2025-02-12 3:34 ` [PATCH 13/34] common/rc: hoist pkill to a helper function Darrick J. Wong
2025-02-12 3:34 ` [PATCH 14/34] common: fix pkill by running test program in a separate session Darrick J. Wong
2025-02-14 17:34 ` Zorro Lang
2025-02-14 17:56 ` Darrick J. Wong
2025-02-14 20:50 ` Theodore Ts'o
2025-02-14 21:11 ` Darrick J. Wong
2025-02-15 13:34 ` Zorro Lang
2025-02-14 21:12 ` [PATCH 13.99/34] tools: add a Makefile " Darrick J. Wong
2025-02-15 13:16 ` Zorro Lang
2025-02-14 21:13 ` [PATCH v3.1 14/34] common: fix pkill by running test program in a " Darrick J. Wong
2025-02-15 13:22 ` Zorro Lang
2025-02-15 16:54 ` Darrick J. Wong [this message]
2025-02-12 3:34 ` [PATCH 15/34] check: run tests in a private pid/mount namespace Darrick J. Wong
2025-02-14 17:36 ` Zorro Lang
2025-02-14 21:13 ` [PATCH v3.1 " Darrick J. Wong
2025-02-25 11:27 ` Shinichiro Kawasaki
2025-02-25 15:49 ` Darrick J. Wong
2025-02-25 21:29 ` Dave Chinner
2025-02-26 2:13 ` Shinichiro Kawasaki
2025-02-26 2:18 ` Darrick J. Wong
2025-02-12 3:34 ` [PATCH 16/34] check: deprecate using process sessions to isolate test instances Darrick J. Wong
2025-02-12 3:35 ` [PATCH 17/34] common/rc: don't copy fsstress to $TEST_DIR Darrick J. Wong
2025-02-12 3:35 ` [PATCH 18/34] unmount: resume logging of stdout and stderr for filtering Darrick J. Wong
2025-02-12 3:35 ` [PATCH 19/34] mkfs: don't hardcode log size Darrick J. Wong
2025-02-12 3:35 ` [PATCH 20/34] common/rc: return mount_ret in _try_scratch_mount Darrick J. Wong
2025-02-12 3:36 ` [PATCH 21/34] preamble: fix missing _kill_fsstress Darrick J. Wong
2025-02-12 3:36 ` [PATCH 22/34] generic/650: revert SOAK DURATION changes Darrick J. Wong
2025-02-12 3:36 ` [PATCH 23/34] generic/032: fix pinned mount failure Darrick J. Wong
2025-02-12 3:36 ` [PATCH 24/34] fuzzy: stop __stress_scrub_fsx_loop if fsx fails Darrick J. Wong
2025-02-12 3:37 ` [PATCH 25/34] fuzzy: don't use readarray for xfsfind output Darrick J. Wong
2025-02-12 3:37 ` [PATCH 26/34] fuzzy: always stop the scrub fsstress loop on error Darrick J. Wong
2025-02-12 3:37 ` [PATCH 27/34] fuzzy: port fsx and fsstress loop to use --duration Darrick J. Wong
2025-02-12 4:47 ` Dave Chinner
2025-02-12 3:37 ` [PATCH 28/34] fix _require_scratch_duperemove ordering Darrick J. Wong
2025-02-12 3:38 ` [PATCH 29/34] fsstress: fix a memory leak Darrick J. Wong
2025-02-12 3:38 ` [PATCH 30/34] fsx: fix leaked log file pointer Darrick J. Wong
2025-02-12 3:38 ` [PATCH 31/34] misc: don't put nr_cpus into the fsstress -n argument Darrick J. Wong
2025-02-12 3:39 ` [PATCH 32/34] common/config: add $here to FSSTRESS_PROG Darrick J. Wong
2025-02-12 3:39 ` [PATCH 33/34] config: add FSX_PROG variable Darrick J. Wong
2025-02-12 3:39 ` [PATCH 34/34] build: initialize stack variables to zero by default Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250215165447.GH21799@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=dchinner@redhat.com \
--cc=fstests@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=zlang@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox