Re: [PATCH 2/4] selftests: livepatch: Remove leftover modules when a testcase fails

From: Petr Mladek

Date: Fri Jun 05 2026 - 10:07:40 EST


On Sun 2026-05-24 20:50:31, Marcos Paulo de Souza wrote:
> The current livepatch selftest scripts load modules, run tests and
> unloads them. If the test fails, it can leave loaded modules behind, and
> in some cases making it impossible to run the next tests.
>
> This approach tracks down the loaded modules, and in case of a test
> failure, or premature exit of the script, the cleanup function will
> be called by the trap installed on setup_config function.
>
> The cleanup function iterates over the list of leftover loaded modules,
> unloading them. The function also checks if the given module is a
> livepatch, properly disabling it before unloading.
>
> Signed-off-by: Marcos Paulo de Souza <mpdesouza@xxxxxxxx>
> ---
> tools/testing/selftests/livepatch/functions.sh | 23 ++++++++++++++++++++++-
> 1 file changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/livepatch/functions.sh b/tools/testing/selftests/livepatch/functions.sh
> index 3ec0b7962fc5..25f137003865 100644
> --- a/tools/testing/selftests/livepatch/functions.sh
> +++ b/tools/testing/selftests/livepatch/functions.sh
> @@ -15,6 +15,8 @@ if [[ -e /sys/kernel/tracing/trace ]]; then
> else
> SYSFS_TRACING_DIR="$SYSFS_DEBUG_DIR/tracing"
> fi
> +# List of loaded modules used in tests
> +TEST_MODS=()
>
> # Kselftest framework requirement - SKIP code is 4
> ksft_skip=4
> @@ -125,6 +127,14 @@ function set_ftrace_enabled() {
> }
>
> function cleanup() {
> + # Remove leftover modules in reverse order to handle dependencies
> + for mod_item in "${TEST_MODS[@]}"; do

It would make sense to check here that the module is loaded.
I would add a helper function is_mod_loaded which
would check whether /sys/module/$mod exists.


> + if is_livepatch_mod "$mod_item"; then

It might make sense to 1st check here whether the livepatch is
enabled. Again, I would add a helper function for this.

> + disable_lp "$mod_item"
> + fi
> + _remove_mod "$mod_item"
> + done

I would put this into a helper function, for example,
called remove_test_mods().

> +
> pop_config
> }
>
> @@ -181,6 +191,9 @@ function __load_mod() {
> # Wait for module in sysfs ...
> loop_until '[[ -e "/sys/module/$mod" ]]' ||
> die "failed to load module $mod"
> +
> + # Store the module in the modules list
> + TEST_MODS+=("$mod")

I would put this into a helper function, for example,
called track_test_mod().

> }
>
>
> @@ -262,12 +275,20 @@ function _remove_mod() {
> die "failed to unload module $mod (/sys/module)"
> }
>
> -# unload_mod(modname) - unload a kernel module
> +# unload_mod(modname) - unload a kernel module and remove it from TEST_MODS
> # modname - module name to unload
> function unload_mod() {
> local mod="$1"
>
> _remove_mod "$mod"
> +
> + # Remove from TEST_MODS array
> + for i in "${!TEST_MODS[@]}"; do
> + if [[ "${TEST_MODS[$i]}" == "$mod" ]]; then
> + unset 'TEST_MODS[$i]'
> + break
> + fi
> + done

And this into a helper called, for example, untrack_test_mod().

> }
>
> # unload_lp(modname) - unload a kernel module with a livepatch

Best Regards,
Petr