On Sun, Nov 09, 2025 at 11:05:56AM +0000, Andre Carvalho wrote:
> Introduce a new netconsole selftest to validate that netconsole is able
> to resume a deactivated target when the low level interface comes back.
> 
> The test setups the network using netdevsim, creates a netconsole target
> and then remove/add netdevsim in order to bring the same interfaces
> back. Afterwards, the test validates that the target works as expected.
> 
> Targets are created via cmdline parameters to the module to ensure that
> we are able to resume targets that were bound by mac and interface name.
> 
> Signed-off-by: Andre Carvalho <[email protected]>
> ---
>  tools/testing/selftests/drivers/net/Makefile       |  1 +
>  .../selftests/drivers/net/lib/sh/lib_netcons.sh    | 30 ++++++-
>  .../selftests/drivers/net/netcons_resume.sh        | 92 
> ++++++++++++++++++++++
>  3 files changed, 120 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/testing/selftests/drivers/net/Makefile 
> b/tools/testing/selftests/drivers/net/Makefile
> index 68e0bb603a9d..fbd81bec66cd 100644
> --- a/tools/testing/selftests/drivers/net/Makefile
> +++ b/tools/testing/selftests/drivers/net/Makefile
> @@ -17,6 +17,7 @@ TEST_PROGS := \
>       netcons_cmdline.sh \
>       netcons_fragmented_msg.sh \
>       netcons_overflow.sh \
> +     netcons_resume.sh \
>       netcons_sysdata.sh \
>       netpoll_basic.py \
>       ping.py \
> diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh 
> b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
> index 8e1085e89647..88b4bdfa84cf 100644
> --- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
> +++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
> @@ -186,12 +186,13 @@ function do_cleanup() {
>  }
>  
>  function cleanup() {
> +     local TARGETPATH=${1:-${NETCONS_PATH}}
>       # delete netconsole dynamic reconfiguration
> -     echo 0 > "${NETCONS_PATH}"/enabled
> +     echo 0 > "${TARGETPATH}"/enabled
>       # Remove all the keys that got created during the selftest
> -     find "${NETCONS_PATH}/userdata/" -mindepth 1 -type d -delete
> +     find "${TARGETPATH}/userdata/" -mindepth 1 -type d -delete
>       # Remove the configfs entry
> -     rmdir "${NETCONS_PATH}"
> +     rmdir "${TARGETPATH}"
>  
>       do_cleanup
>  }
> @@ -350,6 +351,29 @@ function check_netconsole_module() {
>       fi
>  }
>  
> +function wait_target_state() {
> +     local TARGET=${1}
> +     local STATE=${2}
> +     local FILE="${NETCONS_CONFIGFS}"/"${TARGET}"/"enabled"

local TARGET_PATH="${NETCONS_CONFIGFS}"/"${TARGET}"

> +
> +     if [ "${STATE}" == "enabled" ]
> +     then
> +             ENABLED=1

Shouldn't they be local variables in here ?

> +     else
> +             ENABLED=0
> +     fi
> +
> +     if [ ! -f "$FILE" ]; then

        if [ ! -f "${TARGET_PATH}" ]; then

> +             echo "FAIL: Target does not exist." >&2
> +             exit "${ksft_fail}"
> +     fi
> +
> +     slowwait 2 sh -c "test -n \"\$(grep \"${ENABLED}\" \"${FILE}\")\"" || {

        slowwait 2 sh -c "test -n \"\$(grep \"${ENABLED}\" 
\"${TARGET_PATH}/enabled\")\"" || {

> +             echo "FAIL: ${TARGET} is not ${STATE}." >&2
> +     }
> +}
> +
>  # A wrapper to translate protocol version to udp version
>  function wait_for_port() {
>       local NAMESPACE=${1}
> diff --git a/tools/testing/selftests/drivers/net/netcons_resume.sh 
> b/tools/testing/selftests/drivers/net/netcons_resume.sh
> new file mode 100755
> index 000000000000..404df7abef1b
> --- /dev/null
> +++ b/tools/testing/selftests/drivers/net/netcons_resume.sh
> @@ -0,0 +1,92 @@
> +#!/usr/bin/env bash
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# This test validates that netconsole is able to resume a target that was
> +# deactivated when its interface was removed when the interface is brought
> +# back up.

Comment above is a bit harder to understand.

> +#
> +# The test configures a netconsole target and then removes netdevsim module 
> to
> +# cause the interface to disappear. Targets are configured via cmdline to 
> ensure
> +# targets bound by interface name and mac address can be resumed.
> +# The test verifies that the target moved to disabled state before adding
> +# netdevsim and the interface back.
> +#
> +# Finally, the test verifies that the target is re-enabled automatically and
> +# the message is received on the destination interface.
> +#
> +# Author: Andre Carvalho <[email protected]>
> +
> +set -euo pipefail
> +
> +SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
> +
> +source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh
> +
> +modprobe netdevsim 2> /dev/null || true
> +rmmod netconsole 2> /dev/null || true
> +
> +check_netconsole_module
> +
> +# Run the test twice, with different cmdline parameters
> +for BINDMODE in "ifname" "mac"
> +do
> +     echo "Running with bind mode: ${BINDMODE}" >&2
> +     # Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5)
> +     echo "6 5" > /proc/sys/kernel/printk
> +
> +     # Create one namespace and two interfaces
> +     set_network
> +     trap do_cleanup EXIT

can we keep these trap lines outside of the loop?

> +
> +     # Create the command line for netconsole, with the configuration from
> +     # the function above
> +     CMDLINE=$(create_cmdline_str "${BINDMODE}")
> +
> +     # The content of kmsg will be save to the following file
> +     OUTPUT_FILE="/tmp/${TARGET}-${BINDMODE}"
> +
> +     # Load the module, with the cmdline set
> +     modprobe netconsole "${CMDLINE}"
> +     # Expose cmdline target in configfs
> +     mkdir ${NETCONS_CONFIGFS}"/cmdline0"
> +     trap 'cleanup "${NETCONS_CONFIGFS}"/cmdline0' EXIT
> +
> +     # Target should be enabled
> +     wait_target_state "cmdline0" "enabled"
> +
> +     # Remove low level module
> +     rmmod netdevsim
> +     # Target should be disabled
> +     wait_target_state "cmdline0" "disabled"
> +
> +     # Add back low level module
> +     modprobe netdevsim
> +     # Recreate namespace and two interfaces
> +     set_network
> +     # Target should be enabled again
> +     wait_target_state "cmdline0" "enabled"
> +
> +     # Listen for netconsole port inside the namespace and destination
> +     # interface
> +     listen_port_and_save_to "${OUTPUT_FILE}" &
> +     # Wait for socat to start and listen to the port.
> +     wait_local_port_listen "${NAMESPACE}" "${PORT}" udp
> +     # Send the message
> +     echo "${MSG}: ${TARGET}" > /dev/kmsg
> +     # Wait until socat saves the file to disk
> +     busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}"
> +     # Make sure the message was received in the dst part
> +     # and exit
> +     validate_msg "${OUTPUT_FILE}"
> +
> +     # kill socat in case it is still running
> +     pkill_socat
> +     # Cleanup & unload the module
> +     cleanup "${NETCONS_CONFIGFS}/cmdline0"
> +     rmmod netconsole

Why do we need to remove netconsole module in here?

Thanks for this patch. This is solving a real issue we have right now.
--breno

Reply via email to