* [LTP] [PATCH v3] shell: enable OOM protection by default
@ 2026-08-04 9:22 Andrea Cervesato
2026-08-04 9:25 ` Andrea Cervesato via ltp
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Andrea Cervesato @ 2026-08-04 9:22 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add TST_OOM_PROTECTION to activate/deactivate OOM protection in shell
tests. When enabled, the shell harness shields itself from the OOM
killer and runs the test in a child process, so it survives memory
pressure and can still report results (e.g. during memcg stress tests).
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Under Li's idea, implement a OOM protection mechanism for the shell
tests so we can avoid OOM for memcg stress tests.
---
Changes in v3:
- simplify oom code
- enable OOM protection by default
- Link to v2: https://lore.kernel.org/20260730-shell_oom_protection-v2-0-be1de2baa83d@suse.com
Changes in v2:
- update shell OOM protection functional test
- Link to v1: https://lore.kernel.org/20260713-shell_oom_protection-v1-0-b732e8647894@suse.com
---
doc/developers/writing_tests.rst | 3 +++
lib/newlib_tests/runtest.sh | 1 +
lib/newlib_tests/shell/tst_oom_protection.sh | 31 ++++++++++++++++++++++++
testcases/lib/tst_test.sh | 35 +++++++++++++++++++++++++++-
4 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/doc/developers/writing_tests.rst b/doc/developers/writing_tests.rst
index 4db57898fcf08b83e68be996f666e91c418838fc..2d5bc294083fa2b89212714f0a6c5e5c3f22777a 100644
--- a/doc/developers/writing_tests.rst
+++ b/doc/developers/writing_tests.rst
@@ -549,6 +549,9 @@ LTP C And Shell Test API Comparison
* - not applicable
- TST_FS_TYPE
+ * - not applicable
+ - TST_OOM_PROTECTION
+
.. list-table::
:header-rows: 1
diff --git a/lib/newlib_tests/runtest.sh b/lib/newlib_tests/runtest.sh
index 71808ef8b8d5545f52d6014bc070145f952915e9..7e2d0a2ac329fc1d825c2fe0b6f7c09d4f2b0064 100755
--- a/lib/newlib_tests/runtest.sh
+++ b/lib/newlib_tests/runtest.sh
@@ -44,6 +44,7 @@ shell/tst_check_driver.sh
shell/tst_check_kconfig0[1-5].sh
shell/tst_mount_device.sh
shell/tst_mount_device_tmpfs.sh
+shell/tst_oom_protection.sh
shell/tst_skip_filesystems.sh
shell/net/*.sh}"
diff --git a/lib/newlib_tests/shell/tst_oom_protection.sh b/lib/newlib_tests/shell/tst_oom_protection.sh
new file mode 100755
index 0000000000000000000000000000000000000000..22993511c64845712e4fa9fc942e9869121d7e0b
--- /dev/null
+++ b/lib/newlib_tests/shell/tst_oom_protection.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2026 Linux Test Project
+
+TST_TESTFUNC=do_test
+
+read_oom_score_adj() {
+ cat "/proc/$1/oom_score_adj" 2>/dev/null
+}
+
+do_test() {
+ local harness_score child_score
+
+ harness_score=$(read_oom_score_adj "$$")
+
+ if [ "$harness_score" = -1000 ]; then
+ tst_res TPASS "shell harness is protected from OOM by default"
+
+ child_score=$(tst_oom_unprotect read_oom_score_adj self)
+ if [ "$child_score" = 0 ]; then
+ tst_res TPASS "unprotected child process has oom_score_adj reset to 0"
+ else
+ tst_res TFAIL "unprotected child process oom_score_adj is $child_score, expected 0"
+ fi
+ else
+ tst_res TCONF "shell harness OOM protection unavailable"
+ fi
+}
+
+. tst_test.sh
+tst_run
diff --git a/testcases/lib/tst_test.sh b/testcases/lib/tst_test.sh
index b3e7e29bbf7b52de4cb65665751005cb4df156a8..70fa19e4dadfdceb92821a02fbce7cf6686d9c4e 100644
--- a/testcases/lib/tst_test.sh
+++ b/testcases/lib/tst_test.sh
@@ -15,6 +15,7 @@ export TST_CONF=0
export TST_COUNT=1
export TST_ITERATIONS=1
export TST_TMPDIR_RHOST=0
+export TST_OOM_PROTECTION="${TST_OOM_PROTECTION:-1}"
export TST_LIB_LOADED=1
# see testcases/lib/tst_runas.c
@@ -28,6 +29,34 @@ export TST_USR_GID="${LTP_USR_GID:-65534}"
trap "tst_brk TBROK 'test interrupted'" INT
trap "unset _tst_setup_timer_pid; tst_brk TBROK 'test terminated'" TERM
+_tst_set_oom_score_adj()
+{
+ local value="$1"
+ local path="/proc/self/oom_score_adj"
+
+ [ -e "$path" ] || return 0
+
+ echo "$value" > "$path" 2>/dev/null || return 0
+}
+
+_tst_enable_oom_protection()
+{
+ _tst_set_oom_score_adj -1000
+}
+
+_tst_disable_oom_protection()
+{
+ _tst_set_oom_score_adj 0
+}
+
+tst_oom_unprotect()
+{
+ _tst_disable_oom_protection
+ if [ $# -gt 0 ]; then
+ "$@"
+ fi
+}
+
_tst_do_cleanup()
{
if [ -n "$TST_DO_CLEANUP" -a -n "$TST_CLEANUP" -a -z "$LTP_NO_CLEANUP" ]; then
@@ -681,12 +710,16 @@ tst_run()
local _tst_pattern='[='\''"} \t\/:`$\;|].*'
local ret
+ if [ "$TST_OOM_PROTECTION" = 1 ]; then
+ _tst_enable_oom_protection
+ fi
+
if [ -n "$TST_TEST_PATH" ]; then
for _tst_i in $(grep '^[^#]*\<TST_' "$TST_TEST_PATH" | sed "s/.*TST_//; s/$_tst_pattern//"); do
case "$_tst_i" in
ALL_FILESYSTEMS|DISABLE_APPARMOR|DISABLE_SELINUX);;
SETUP|CLEANUP|TESTFUNC|ID|CNT|MIN_KVER);;
- OPTS|USAGE|PARSE_ARGS|POS_ARGS);;
+ OPTS|USAGE|PARSE_ARGS|POS_ARGS|OOM_PROTECTION);;
NEEDS_ROOT|NEEDS_TMPDIR|TMPDIR|NEEDS_DEVICE|DEVICE);;
NEEDS_CMDS|NEEDS_MODULE|MODPATH|DATAROOT);;
NEEDS_DRIVERS|FS_TYPE|MNTPOINT|MNT_PARAMS);;
---
base-commit: 51f722d233efa06304b1d178e24a01048cf80f10
change-id: 20260713-shell_oom_protection-6221ab825220
Best regards,
--
Andrea Cervesato <andrea.cervesato@suse.com>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [LTP] [PATCH v3] shell: enable OOM protection by default
2026-08-04 9:22 [LTP] [PATCH v3] shell: enable OOM protection by default Andrea Cervesato
@ 2026-08-04 9:25 ` Andrea Cervesato via ltp
2026-08-04 10:40 ` [LTP] " linuxtestproject.agent
2026-08-04 13:17 ` [LTP] [PATCH v3] " Petr Vorel
2 siblings, 0 replies; 7+ messages in thread
From: Andrea Cervesato via ltp @ 2026-08-04 9:25 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project, Li Wang
Hi Li, Petr,
I updated the patch and simplified it a bit. Maybe I missed something,
but it looks good enough now. Let me know if you still have some
feedbacks. It's somehow a new v1 :-)
--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [LTP] shell: enable OOM protection by default
2026-08-04 9:22 [LTP] [PATCH v3] shell: enable OOM protection by default Andrea Cervesato
2026-08-04 9:25 ` Andrea Cervesato via ltp
@ 2026-08-04 10:40 ` linuxtestproject.agent
2026-08-04 11:30 ` Andrea Cervesato via ltp
2026-08-04 13:17 ` [LTP] [PATCH v3] " Petr Vorel
2 siblings, 1 reply; 7+ messages in thread
From: linuxtestproject.agent @ 2026-08-04 10:40 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi Andrea,
On Aug 4, 2026, Andrea Cervesato wrote:
> shell: enable OOM protection by default
> + if [ "$TST_OOM_PROTECTION" = 1 ]; then
> + _tst_enable_oom_protection
> + fi
Major: Could the test body run in an unprotected child here, as it does in
the C harness?
This sets -1000 on the same shell that later executes the test functions, so
all workloads forked by existing tests inherit OOM protection. For example,
memcg_limit_in_bytes.sh reaches test_proc_kill() and starts memcg_process in
the background. Linux 7.2 copies oom_score_adj on fork, and its cgroup
documentation says that tasks with -1000 are never killed. That path will
therefore report that memcg_process was not killed instead of observing the
expected cgroup OOM kill.
The commit message says that the test runs in a child, but this patch does not
create that boundary. tst_oom_unprotect() is only called by the new self-test,
so it does not reset the existing workload launch sites.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [LTP] shell: enable OOM protection by default
2026-08-04 10:40 ` [LTP] " linuxtestproject.agent
@ 2026-08-04 11:30 ` Andrea Cervesato via ltp
0 siblings, 0 replies; 7+ messages in thread
From: Andrea Cervesato via ltp @ 2026-08-04 11:30 UTC (permalink / raw)
To: linuxtestproject.agent; +Cc: ltp
Hi,
> Major: Could the test body run in an unprotected child here, as it does in
> the C harness?
>
> This sets -1000 on the same shell that later executes the test functions, so
> all workloads forked by existing tests inherit OOM protection. For example,
> memcg_limit_in_bytes.sh reaches test_proc_kill() and starts memcg_process in
> the background. Linux 7.2 copies oom_score_adj on fork, and its cgroup
> documentation says that tasks with -1000 are never killed. That path will
> therefore report that memcg_process was not killed instead of observing the
> expected cgroup OOM kill.
>
> The commit message says that the test runs in a child, but this patch does not
> create that boundary. tst_oom_unprotect() is only called by the new self-test,
> so it does not reset the existing workload launch sites.
the review is correct, I will sent a new version.
--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [LTP] [PATCH v3] shell: enable OOM protection by default
2026-08-04 9:22 [LTP] [PATCH v3] shell: enable OOM protection by default Andrea Cervesato
2026-08-04 9:25 ` Andrea Cervesato via ltp
2026-08-04 10:40 ` [LTP] " linuxtestproject.agent
@ 2026-08-04 13:17 ` Petr Vorel
2 siblings, 0 replies; 7+ messages in thread
From: Petr Vorel @ 2026-08-04 13:17 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: Linux Test Project
Hi Andrea,
> Add TST_OOM_PROTECTION to activate/deactivate OOM protection in shell
> tests. When enabled, the shell harness shields itself from the OOM
> killer and runs the test in a child process, so it survives memory
> pressure and can still report results (e.g. during memcg stress tests).
C API just enables OOM protection unconditionally. Why we allow to disable it?
Also, I would not allow to disable it until any test actually needs that.
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> Under Li's idea, implement a OOM protection mechanism for the shell
Li would deserve his credit via Suggested-by: :). And it's not only for the
credit itself, but (maybe more important) when there is something later on
others know whom to ask for the details.
> tests so we can avoid OOM for memcg stress tests.
Ah, it's for memcg stress tests. Maybe people in the future appreciate to know
this, IMHO it should be part of the commit message.
> ---
> Changes in v3:
> - simplify oom code
> - enable OOM protection by default
> - Link to v2: https://lore.kernel.org/20260730-shell_oom_protection-v2-0-be1de2baa83d@suse.com
> Changes in v2:
> - update shell OOM protection functional test
> - Link to v1: https://lore.kernel.org/20260713-shell_oom_protection-v1-0-b732e8647894@suse.com
> ---
> doc/developers/writing_tests.rst | 3 +++
> lib/newlib_tests/runtest.sh | 1 +
> lib/newlib_tests/shell/tst_oom_protection.sh | 31 ++++++++++++++++++++++++
> testcases/lib/tst_test.sh | 35 +++++++++++++++++++++++++++-
> 4 files changed, 69 insertions(+), 1 deletion(-)
> diff --git a/doc/developers/writing_tests.rst b/doc/developers/writing_tests.rst
> index 4db57898fcf08b83e68be996f666e91c418838fc..2d5bc294083fa2b89212714f0a6c5e5c3f22777a 100644
> --- a/doc/developers/writing_tests.rst
> +++ b/doc/developers/writing_tests.rst
> @@ -549,6 +549,9 @@ LTP C And Shell Test API Comparison
> * - not applicable
> - TST_FS_TYPE
> + * - not applicable
> + - TST_OOM_PROTECTION
If we really want to keep the variable, I'd for C part instead of "not
applicable" wrote:
_equivalent of OOM protection enabled in C API (tst_enable_oom_protection())_
And, more important, if we add new variable to tst_test.sh, IMHO it should be
documented in the only docs we have for it: doc/old/Shell-Test-API.asciidoc.
> diff --git a/lib/newlib_tests/runtest.sh b/lib/newlib_tests/runtest.sh
> index 71808ef8b8d5545f52d6014bc070145f952915e9..7e2d0a2ac329fc1d825c2fe0b6f7c09d4f2b0064 100755
> --- a/lib/newlib_tests/runtest.sh
> +++ b/lib/newlib_tests/runtest.sh
> @@ -44,6 +44,7 @@ shell/tst_check_driver.sh
> shell/tst_check_kconfig0[1-5].sh
> shell/tst_mount_device.sh
> shell/tst_mount_device_tmpfs.sh
> +shell/tst_oom_protection.sh
+1
> shell/tst_skip_filesystems.sh
> shell/net/*.sh}"
> diff --git a/lib/newlib_tests/shell/tst_oom_protection.sh b/lib/newlib_tests/shell/tst_oom_protection.sh
> new file mode 100755
> index 0000000000000000000000000000000000000000..22993511c64845712e4fa9fc942e9869121d7e0b
> --- /dev/null
> +++ b/lib/newlib_tests/shell/tst_oom_protection.sh
> @@ -0,0 +1,31 @@
> +#!/bin/sh
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +# Copyright (c) 2026 Linux Test Project
> +
> +TST_TESTFUNC=do_test
> +
> +read_oom_score_adj() {
> + cat "/proc/$1/oom_score_adj" 2>/dev/null
Why this masking stderr? It should be always OK to read.
> +}
> +
> +do_test() {
> + local harness_score child_score
> +
> + harness_score=$(read_oom_score_adj "$$")
> +
> + if [ "$harness_score" = -1000 ]; then
> + tst_res TPASS "shell harness is protected from OOM by default"
> +
> + child_score=$(tst_oom_unprotect read_oom_score_adj self)
> + if [ "$child_score" = 0 ]; then
> + tst_res TPASS "unprotected child process has oom_score_adj reset to 0"
> + else
> + tst_res TFAIL "unprotected child process oom_score_adj is $child_score, expected 0"
> + fi
> + else
> + tst_res TCONF "shell harness OOM protection unavailable"
> + fi
> +}
> +
> +. tst_test.sh
> +tst_run
> diff --git a/testcases/lib/tst_test.sh b/testcases/lib/tst_test.sh
> index b3e7e29bbf7b52de4cb65665751005cb4df156a8..70fa19e4dadfdceb92821a02fbce7cf6686d9c4e 100644
> --- a/testcases/lib/tst_test.sh
> +++ b/testcases/lib/tst_test.sh
> @@ -15,6 +15,7 @@ export TST_CONF=0
> export TST_COUNT=1
> export TST_ITERATIONS=1
> export TST_TMPDIR_RHOST=0
> +export TST_OOM_PROTECTION="${TST_OOM_PROTECTION:-1}"
> export TST_LIB_LOADED=1
> # see testcases/lib/tst_runas.c
> @@ -28,6 +29,34 @@ export TST_USR_GID="${LTP_USR_GID:-65534}"
> trap "tst_brk TBROK 'test interrupted'" INT
> trap "unset _tst_setup_timer_pid; tst_brk TBROK 'test terminated'" TERM
> +_tst_set_oom_score_adj()
> +{
> + local value="$1"
> + local path="/proc/self/oom_score_adj"
> +
> + [ -e "$path" ] || return 0
If you don't reuse the return value you can use just "return"
Also, C API in set_oom_score_adj() warns:
tst_res(TINFO, "oom_score_adj does not exist, skipping the adjustment");
> +
> + echo "$value" > "$path" 2>/dev/null || return 0
Do we want to hide "permission denied"? C API in set_oom_score_adj() uses
capability. If you want to really match the behavior with C API, you could
create C binary helper testcases/lib/tst_*.c which would just call
set_oom_score_adj(). But I'd be pragmatic, if the tests which needs it have
TST_NEEDS_ROOT=1 (and memcg_lib.sh sets it), you might just write shell code
which will behave similar like C code (except using capability, of course).
I would not hide "permission denied". At least similarly match C API in
set_oom_score_adj():
if ! echo "$value" > "$path"; then
tst_res TWARN "Can't adjust score"
fi
I.e. no masking stderr), return is not used. And even if you want to use
function return value, $? will be taken from echo, e.g.:
$ echo foo > /asdf; echo $?
bash: /asdf: Permission denied
1
> +}
> +
> +_tst_enable_oom_protection()
> +{
> + _tst_set_oom_score_adj -1000
> +}
> +
> +_tst_disable_oom_protection()
> +{
> + _tst_set_oom_score_adj 0
> +}
> +
> +tst_oom_unprotect()
> +{
> + _tst_disable_oom_protection
> + if [ $# -gt 0 ]; then
> + "$@"
Because there is only single use of tst_oom_unprotect(), I would call
"read_oom_score_adj self" here. More readable, more secure ("$@" is kind of
eval).
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 7+ messages in thread
* [LTP] [PATCH v4] shell: enable OOM protection by default
@ 2026-08-10 11:13 Andrea Cervesato
2026-08-10 13:10 ` [LTP] " linuxtestproject.agent
0 siblings, 1 reply; 7+ messages in thread
From: Andrea Cervesato @ 2026-08-10 11:13 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
The shell harness shields itself from the OOM killer and runs the
test in a child process, so it survives memory pressure and can
still report results (e.g. during memcg stress tests).
Suggested-by: Li Wang <liwang@redhat.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Under Li's idea, implement a OOM protection mechanism for the shell
tests so we can avoid OOM for memcg stress tests.
---
Changes in v4:
- fix with Petr suggestions
- fix with AI agent suggestions
- Link to v3: https://lore.kernel.org/20260804-shell_oom_protection-v3-1-fe42b15d034c@suse.com
Changes in v3:
- simplify oom code
- enable OOM protection by default
- Link to v2: https://lore.kernel.org/20260730-shell_oom_protection-v2-0-be1de2baa83d@suse.com
Changes in v2:
- update shell OOM protection functional test
- Link to v1: https://lore.kernel.org/20260713-shell_oom_protection-v1-0-b732e8647894@suse.com
To: Linux Test Project <ltp@lists.linux.it>
---
lib/newlib_tests/runtest.sh | 1 +
lib/newlib_tests/shell/tst_oom_protection.sh | 34 +++++++++++
testcases/lib/tst_test.sh | 84 ++++++++++++++++++++++++++--
3 files changed, 115 insertions(+), 4 deletions(-)
diff --git a/lib/newlib_tests/runtest.sh b/lib/newlib_tests/runtest.sh
index 71808ef8b..7e2d0a2ac 100755
--- a/lib/newlib_tests/runtest.sh
+++ b/lib/newlib_tests/runtest.sh
@@ -44,6 +44,7 @@ shell/tst_check_driver.sh
shell/tst_check_kconfig0[1-5].sh
shell/tst_mount_device.sh
shell/tst_mount_device_tmpfs.sh
+shell/tst_oom_protection.sh
shell/tst_skip_filesystems.sh
shell/net/*.sh}"
diff --git a/lib/newlib_tests/shell/tst_oom_protection.sh b/lib/newlib_tests/shell/tst_oom_protection.sh
new file mode 100755
index 000000000..564680700
--- /dev/null
+++ b/lib/newlib_tests/shell/tst_oom_protection.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2026 Linux Test Project
+
+TST_TESTFUNC=do_test
+
+read_oom_score_adj() {
+ cat "/proc/$1/oom_score_adj"
+}
+
+do_test() {
+ local harness_score body_score
+
+ # $$ points to the protected harness, while /proc/self is the
+ # unprotected child that actually runs the test body.
+ harness_score=$(read_oom_score_adj "$$")
+ body_score=$(read_oom_score_adj self)
+
+ if [ "$harness_score" != -1000 ]; then
+ tst_res TCONF "shell harness OOM protection unavailable"
+ return
+ fi
+
+ tst_res TPASS "shell harness is protected from OOM by default"
+
+ if [ "$body_score" = 0 ]; then
+ tst_res TPASS "test body runs in an unprotected child (oom_score_adj=0)"
+ else
+ tst_res TFAIL "test body oom_score_adj is $body_score, expected 0"
+ fi
+}
+
+. tst_test.sh
+tst_run
diff --git a/testcases/lib/tst_test.sh b/testcases/lib/tst_test.sh
index b3e7e29bb..e42e562f5 100644
--- a/testcases/lib/tst_test.sh
+++ b/testcases/lib/tst_test.sh
@@ -28,6 +28,48 @@ export TST_USR_GID="${LTP_USR_GID:-65534}"
trap "tst_brk TBROK 'test interrupted'" INT
trap "unset _tst_setup_timer_pid; tst_brk TBROK 'test terminated'" TERM
+_tst_set_oom_score_adj()
+{
+ local value="$1"
+ local path="/proc/self/oom_score_adj"
+
+ if [ ! -e "$path" ]; then
+ tst_res TINFO "oom_score_adj does not exist, skipping the adjustment"
+ return
+ fi
+
+ if ! echo "$value" > "$path"; then
+ tst_res TWARN "Can't adjust score"
+ fi
+}
+
+_tst_enable_oom_protection()
+{
+ _tst_set_oom_score_adj -1000
+}
+
+_tst_disable_oom_protection()
+{
+ _tst_set_oom_score_adj 0
+}
+
+_tst_write_results()
+{
+ [ "$TST_CHILD" = 1 ] || return 0
+ [ -n "$TST_RESULTS_FILE" ] || return 0
+
+ echo "$TST_PASS $TST_FAIL $TST_BROK $TST_WARN $TST_CONF $TST_COUNT" \
+ > "$TST_RESULTS_FILE"
+}
+
+_tst_read_results()
+{
+ [ -s "$TST_RESULTS_FILE" ] || return 0
+
+ read TST_PASS TST_FAIL TST_BROK TST_WARN TST_CONF TST_COUNT \
+ < "$TST_RESULTS_FILE"
+}
+
_tst_do_cleanup()
{
if [ -n "$TST_DO_CLEANUP" -a -n "$TST_CLEANUP" -a -z "$LTP_NO_CLEANUP" ]; then
@@ -48,6 +90,15 @@ _tst_do_exit()
_tst_do_cleanup
+ # When running as the unprotected test child, only propagate the
+ # results back to the protected harness which does the teardown and
+ # prints the summary.
+ if [ "$TST_CHILD" = 1 ]; then
+ _tst_cleanup_timer
+ _tst_write_results
+ exit 0
+ fi
+
cd "$LTPROOT"
[ "$TST_MOUNT_FLAG" = 1 ] && tst_umount
@@ -788,10 +839,34 @@ tst_run()
TST_MNTPOINT="${TST_MNTPOINT:-$PWD/mntpoint}"
- if [ "$TST_ALL_FILESYSTEMS" = 1 ]; then
- _tst_run_tcases_per_fs
- else
- _tst_run_iterations
+ # Protect the harness so it survives memory pressure and can
+ # still report results, then run the test body in a child that
+ # resets OOM protection. This way workloads forked by the test
+ # remain killable, mirroring the C test harness.
+ _tst_enable_oom_protection
+
+ TST_RESULTS_FILE=$(mktemp "${TMPDIR:-/tmp}/ltp_${TST_ID}_res.XXXXXX")
+
+ (
+ TST_CHILD=1
+ _tst_disable_oom_protection
+ trap '_tst_cleanup_timer; _tst_write_results' EXIT
+
+ if [ "$TST_ALL_FILESYSTEMS" = 1 ]; then
+ _tst_run_tcases_per_fs
+ else
+ _tst_run_iterations
+ fi
+ ) &
+
+ wait $!
+ ret=$?
+
+ _tst_read_results
+ rm -f "$TST_RESULTS_FILE"
+
+ if [ $ret -gt 128 ]; then
+ tst_res TBROK "Test killed by signal $((ret - 128))!"
fi
_tst_do_exit
@@ -865,6 +940,7 @@ _tst_run_test()
$_tst_fnc "$@"
_tst_rescmp "$_tst_res"
TST_COUNT=$((TST_COUNT+1))
+ _tst_write_results
}
export LC_ALL=C
---
base-commit: ee945bb71ba7015dace7d983cf98a530b3eb53a4
change-id: 20260713-shell_oom_protection-6221ab825220
Best regards,
--
Andrea Cervesato <andrea.cervesato@suse.com>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [LTP] shell: enable OOM protection by default
2026-08-10 11:13 [LTP] [PATCH v4] " Andrea Cervesato
@ 2026-08-10 13:10 ` linuxtestproject.agent
2026-08-10 17:14 ` Petr Vorel
0 siblings, 1 reply; 7+ messages in thread
From: linuxtestproject.agent @ 2026-08-10 13:10 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi Andrea,
On Aug 10, 2026, Andrea Cervesato wrote:
> shell: enable OOM protection by default
> + if ! echo "$value" > "$path"; then
> + tst_res TWARN "Can't adjust score"
> + fi
Could this avoid reporting TWARN when CAP_SYS_RESOURCE is absent, as
tst_memutils.c does? Lowering oom_score_adj requires that capability, so
every unprivileged shell test now gets a warning result. The new self-test
itself reports TCONF but exits 36 because this TWARN remains counted.
> + (
> + TST_CHILD=1
> + _tst_disable_oom_protection
> + trap '_tst_cleanup_timer; _tst_write_results' EXIT
> +
> + if [ "$TST_ALL_FILESYSTEMS" = 1 ]; then
> + _tst_run_tcases_per_fs
> + else
> + _tst_run_iterations
> + fi
> + ) &
> +
> + wait $!
> + ret=$?
How can the protected parent perform cleanup if this child is OOM-killed
or times out? TST_DO_CLEANUP and TST_MOUNT_FLAG are set only in the
subshell. On an abnormal child exit, the parent therefore reports TBROK
without calling TST_CLEANUP or unmounting a device mounted by
_prepare_device(), leaving external test state behind.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [LTP] shell: enable OOM protection by default
2026-08-10 13:10 ` [LTP] " linuxtestproject.agent
@ 2026-08-10 17:14 ` Petr Vorel
0 siblings, 0 replies; 7+ messages in thread
From: Petr Vorel @ 2026-08-10 17:14 UTC (permalink / raw)
To: linuxtestproject.agent; +Cc: ltp
Hi Andrea,
> Hi Andrea,
> On Aug 10, 2026, Andrea Cervesato wrote:
> > shell: enable OOM protection by default
> > + if ! echo "$value" > "$path"; then
> > + tst_res TWARN "Can't adjust score"
> > + fi
> Could this avoid reporting TWARN when CAP_SYS_RESOURCE is absent, as
> tst_memutils.c does? Lowering oom_score_adj requires that capability, so
> every unprivileged shell test now gets a warning result. The new self-test
> itself reports TCONF but exits 36 because this TWARN remains counted.
Ah, this really needs to be guarded behind if [ "$(id -ru)" != 0 ]; then
If you're in a mood for it, you could factor out [ "$(id -ru)" != 0 ] check into
it's own function tst_check_root or tst_is_root which would be then used in
tst_require_root and in this function.
I repeat my suggestion from last revision: add a helper into testcases/lib which
will just call C function. That way the behavior will be the same (use
capabilities). That would be more clearer solution.
Kind regards,
Petr
> > + (
> > + TST_CHILD=1
> > + _tst_disable_oom_protection
> > + trap '_tst_cleanup_timer; _tst_write_results' EXIT
> > +
> > + if [ "$TST_ALL_FILESYSTEMS" = 1 ]; then
> > + _tst_run_tcases_per_fs
> > + else
> > + _tst_run_iterations
> > + fi
> > + ) &
> > +
> > + wait $!
> > + ret=$?
> How can the protected parent perform cleanup if this child is OOM-killed
> or times out? TST_DO_CLEANUP and TST_MOUNT_FLAG are set only in the
> subshell. On an abnormal child exit, the parent therefore reports TBROK
> without calling TST_CLEANUP or unmounting a device mounted by
> _prepare_device(), leaving external test state behind.
Sounds serious :). I'll comment on the patch itself.
Kind regards,
Petr
> Verdict - Needs revision
> ---
> Note:
> The agent can sometimes produce false positives although often its
> findings are genuine. If you find issues with the review, please
> comment this email or ignore the suggestions.
> Regards,
> LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-10 17:15 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-04 9:22 [LTP] [PATCH v3] shell: enable OOM protection by default Andrea Cervesato
2026-08-04 9:25 ` Andrea Cervesato via ltp
2026-08-04 10:40 ` [LTP] " linuxtestproject.agent
2026-08-04 11:30 ` Andrea Cervesato via ltp
2026-08-04 13:17 ` [LTP] [PATCH v3] " Petr Vorel
-- strict thread matches above, loose matches on Subject: below --
2026-08-10 11:13 [LTP] [PATCH v4] " Andrea Cervesato
2026-08-10 13:10 ` [LTP] " linuxtestproject.agent
2026-08-10 17:14 ` Petr Vorel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.