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.
Reviewed-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Andre Carvalho <asantostc@gmail.com>
---
tools/testing/selftests/drivers/net/Makefile | 1 +
.../selftests/drivers/net/lib/sh/lib_netcons.sh | 35 +++++-
.../selftests/drivers/net/netcons_resume.sh | 124 +++++++++++++++++++++
3 files changed, 155 insertions(+), 5 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/Makefile b/tools/testing/selftests/drivers/net/Makefile
index f5c71d993750..3eba569b3366 100644
--- a/tools/testing/selftests/drivers/net/Makefile
+++ b/tools/testing/selftests/drivers/net/Makefile
@@ -19,6 +19,7 @@ TEST_PROGS := \
netcons_cmdline.sh \
netcons_fragmented_msg.sh \
netcons_overflow.sh \
+ netcons_resume.sh \
netcons_sysdata.sh \
netcons_torture.sh \
netpoll_basic.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 ae8abff4be40..b6093bcf2b06 100644
--- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
+++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
@@ -203,19 +203,21 @@ function do_cleanup() {
function cleanup_netcons() {
# delete netconsole dynamic reconfiguration
# do not fail if the target is already disabled
- if [[ ! -d "${NETCONS_PATH}" ]]
+ local TARGET_PATH=${1:-${NETCONS_PATH}}
+
+ if [[ ! -d "${TARGET_PATH}" ]]
then
# in some cases this is called before netcons path is created
return
fi
- if [[ $(cat "${NETCONS_PATH}"/enabled) != 0 ]]
+ if [[ $(cat "${TARGET_PATH}"/enabled) != 0 ]]
then
- echo 0 > "${NETCONS_PATH}"/enabled || true
+ echo 0 > "${TARGET_PATH}"/enabled || true
fi
# Remove all the keys that got created during the selftest
- find "${NETCONS_PATH}/userdata/" -mindepth 1 -type d -delete
+ find "${TARGET_PATH}/userdata/" -mindepth 1 -type d -delete
# Remove the configfs entry
- rmdir "${NETCONS_PATH}"
+ rmdir "${TARGET_PATH}"
}
function cleanup() {
@@ -377,6 +379,29 @@ function check_netconsole_module() {
fi
}
+function wait_target_state() {
+ local TARGET=${1}
+ local STATE=${2}
+ local TARGET_PATH="${NETCONS_CONFIGFS}"/"${TARGET}"
+ local ENABLED=0
+
+ if [ "${STATE}" == "enabled" ]
+ then
+ ENABLED=1
+ fi
+
+ if [ ! -d "$TARGET_PATH" ]; then
+ echo "FAIL: Target does not exist." >&2
+ exit "${ksft_fail}"
+ fi
+
+ local CHECK_CMD="grep \"$ENABLED\" \"$TARGET_PATH/enabled\""
+ slowwait 2 sh -c "test -n \"\$($CHECK_CMD)\"" || {
+ echo "FAIL: ${TARGET} is not ${STATE}." >&2
+ exit "${ksft_fail}"
+ }
+}
+
# 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..fc5e5e3ad3d4
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/netcons_resume.sh
@@ -0,0 +1,124 @@
+#!/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.
+#
+# 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 <asantostc@gmail.com>
+
+set -euo pipefail
+
+SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
+
+source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh
+
+SAVED_SRCMAC="" # to be populated later
+SAVED_DSTMAC="" # to be populated later
+
+modprobe netdevsim 2> /dev/null || true
+rmmod netconsole 2> /dev/null || true
+
+check_netconsole_module
+
+function cleanup() {
+ cleanup_netcons "${NETCONS_CONFIGFS}/cmdline0"
+ do_cleanup
+ rmmod netconsole
+}
+
+function trigger_reactivation() {
+ # Add back low level module
+ modprobe netdevsim
+ # Recreate namespace and two interfaces
+ set_network
+ # Restore MACs
+ ip netns exec "${NAMESPACE}" ip link set "${DSTIF}" \
+ address "${SAVED_DSTMAC}"
+ if [ "${BINDMODE}" == "mac" ]; then
+ ip link set dev "${SRCIF}" down
+ ip link set dev "${SRCIF}" address "${SAVED_SRCMAC}"
+ # Rename device in order to trigger target resume, as initial
+ # when device was recreated it didn't have correct mac address.
+ ip link set dev "${SRCIF}" name "${TARGET}"
+ fi
+}
+
+function trigger_deactivation() {
+ # Start by storing mac addresses so we can be restored in reactivate
+ SAVED_DSTMAC=$(ip netns exec "${NAMESPACE}" \
+ cat /sys/class/net/"$DSTIF"/address)
+ SAVED_SRCMAC=$(mac_get "${SRCIF}")
+ # Remove low level module
+ rmmod netdevsim
+}
+
+trap cleanup EXIT
+
+# 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
+
+ # 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"
+
+ # Target should be enabled
+ wait_target_state "cmdline0" "enabled"
+
+ # Trigger deactivation by unloading netdevsim module. Target should be
+ # disabled.
+ trigger_deactivation
+ wait_target_state "cmdline0" "disabled"
+
+ # Trigger reactivation by loading netdevsim, recreating the network and
+ # restoring mac addresses. Target should be re-enabled.
+ trigger_reactivation
+ 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
+
+ echo "${BINDMODE} : Test passed" >&2
+done
+
+trap - EXIT
+exit "${EXIT_STATUS}"
--
2.52.0
On Sun, 18 Jan 2026 11:00:27 +0000 Andre Carvalho wrote: > +++ b/tools/testing/selftests/drivers/net/netcons_resume.sh We'll keep this series in the queue but I think it's time to move the netcons tests out to their own target or move them to netdevsim. There's too many of them now and they keep failing on real HW. With absolutely no error message getting printed :| TAP version 13 1..1 # overriding timeout to 360 # selftests: drivers/net: netcons_resume.sh # Running with bind mode: ifname # ifname : Test passed # Running with bind mode: mac not ok 1 selftests: drivers/net: netcons_resume.sh # exit=1 https://netdev-3.bots.linux.dev/vmksft-drv-hw-dbg/results/482560/4-netcons-resume-sh/stdout
Hi Jakub,
On Tue, Jan 20, 2026 at 05:20:57PM -0800, Jakub Kicinski wrote:
> On Sun, 18 Jan 2026 11:00:27 +0000 Andre Carvalho wrote:
> > +++ b/tools/testing/selftests/drivers/net/netcons_resume.sh
>
> There's too many of them now and they keep failing on real HW.
Since these tests are only using netdevsim I was a bit surprised about the failures
on real HW runs.
I'm suspecting a race on my workaround to trigger reactivation and these runs
potentially running on a host with systemd with MACAddressPolicy=persistent as
I'm able to produce a similar error on this conditions. Any chance these are
running with different configuration then SW runs?
When the device is recreated with the same MAC address as before, there is a race
between my workaround and the resume. netconsole will immediately resume and UP
the device, then my workaround goes and:
ip link set dev "${SRCIF}" down
ip link set dev "${SRCIF}" address "${SAVED_SRCMAC}"
# Rename device in order to trigger target resume, as initial
# when device was recreated it didn't have correct mac address.
ip link set dev "${SRCIF}" name "${TARGET}"
The problem is that the rename won't resume, as the target has already not deactivated
and nothing will UP the device.
Doing "ip link set dev "${TARGET}" up" at this point should address this gap. Alternative,
we can skip restoring the mac addresses if they are the same.
Does this make sense? Perhaps there are other conditions that can trigger this, but
running it with MACAddressPolicy=persistent is a reliable way for me to reproduce it.
> We'll keep this series in the queue but I think it's time to move
> the netcons tests out to their own target or move them to netdevsim.
Given the above, let me know if you prefer I send v12 with the proposed fixes or
a separated follow up patch to fix the test on HW runs. Since you mentioned keeping
on the queue I want to make sure a new version of this series won't mess up your process.
> With absolutely no error message getting printed :|
Yes, debugging these has been quite challenging. I'd like to improve all netconsole
selftests debuggability in a future series, looking to work on this as soon as I wrap
this one up.
>
> TAP version 13
> 1..1
> # overriding timeout to 360
> # selftests: drivers/net: netcons_resume.sh
> # Running with bind mode: ifname
> # ifname : Test passed
> # Running with bind mode: mac
> not ok 1 selftests: drivers/net: netcons_resume.sh # exit=1
>
> https://netdev-3.bots.linux.dev/vmksft-drv-hw-dbg/results/482560/4-netcons-resume-sh/stdout
--
Andre Carvalho
On Wed, 21 Jan 2026 22:04:23 +0000 Andre Carvalho wrote: > On Tue, Jan 20, 2026 at 05:20:57PM -0800, Jakub Kicinski wrote: > > On Sun, 18 Jan 2026 11:00:27 +0000 Andre Carvalho wrote: > > > +++ b/tools/testing/selftests/drivers/net/netcons_resume.sh > > > > There's too many of them now and they keep failing on real HW. > > Since these tests are only using netdevsim I was a bit surprised about the failures > on real HW runs. My main point is that even if we fix the HW setups to do the right thing in systemd policies - the tests are running against netdevsim, not the precious HW present on those setups. The HW setups have actual physical NICs, driver tests are expected to use netdevsim if $NETIF is not set, and if set whatever existing netdev $NETIF is pointing to. I don't remember the history, it's quite possible that Breno wanted to have a separate target for netcons from the start and I pushed back. I think we reached the point where we want to create a target.
On Wed, Jan 21, 2026 at 05:45:05PM -0800, Jakub Kicinski wrote: > My main point is that even if we fix the HW setups to do the right thing > in systemd policies - the tests are running against netdevsim, not the > precious HW present on those setups. This makes total sense. I got too carried away trying to make sense of why this was failing (I might still submit a follow up to make the test more resilient). > I don't remember the history, it's quite possible that Breno wanted to > have a separate target for netcons from the start and I pushed back. > I think we reached the point where we want to create a target. Sounds good. I had a chat with Breno and I'll look into moving netconsole tests to a standalone target. Thanks for the patience and reviewing this series! -- Andre Carvalho
© 2016 - 2026 Red Hat, Inc.