Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netconsole: selftest: test for sysdata CPU

Add a new selftest to verify that the netconsole module correctly
handles CPU runtime data in sysdata. The test validates three scenarios:

1. Basic CPU sysdata functionality - verifies that cpu=X is appended to
messages
2. CPU sysdata with userdata - ensures CPU data works alongside userdata
3. Disabled CPU sysdata - confirms no CPU data is included when disabled

The test uses taskset to control which CPU sends messages and verifies
the reported CPU matches the one used. This helps ensure that netconsole
accurately tracks and reports the originating CPU of messages.

Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Breno Leitao and committed by
David S. Miller
12fd83ca ec15bc46

+185
+1
tools/testing/selftests/drivers/net/Makefile
··· 9 9 netcons_basic.sh \ 10 10 netcons_fragmented_msg.sh \ 11 11 netcons_overflow.sh \ 12 + netcons_sysdata.sh \ 12 13 ping.py \ 13 14 queues.py \ 14 15 stats.py \
+17
tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh
··· 230 230 exit "${ksft_skip}" 231 231 fi 232 232 } 233 + 234 + function check_for_taskset() { 235 + if ! which taskset > /dev/null ; then 236 + echo "SKIP: taskset(1) is not available" >&2 237 + exit "${ksft_skip}" 238 + fi 239 + } 240 + 241 + # This is necessary if running multiple tests in a row 242 + function pkill_socat() { 243 + PROCESS_NAME="socat UDP-LISTEN:6666,fork ${OUTPUT_FILE}" 244 + # socat runs under timeout(1), kill it if it is still alive 245 + # do not fail if socat doesn't exist anymore 246 + set +e 247 + pkill -f "${PROCESS_NAME}" 248 + set -e 249 + }
+167
tools/testing/selftests/drivers/net/netcons_sysdata.sh
··· 1 + #!/usr/bin/env bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # A test that makes sure that sysdata runtime CPU data is properly set 5 + # when a message is sent. 6 + # 7 + # There are 3 different tests, every time sent using a random CPU. 8 + # - Test #1 9 + # * Only enable cpu_nr sysdata feature. 10 + # - Test #2 11 + # * Keep cpu_nr sysdata feature enable and enable userdata. 12 + # - Test #3 13 + # * keep userdata enabled, and disable sysdata cpu_nr feature. 14 + # 15 + # Author: Breno Leitao <leitao@debian.org> 16 + 17 + set -euo pipefail 18 + 19 + SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") 20 + 21 + source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh 22 + 23 + # Enable the sysdata cpu_nr feature 24 + function set_cpu_nr() { 25 + if [[ ! -f "${NETCONS_PATH}/userdata/cpu_nr_enabled" ]] 26 + then 27 + echo "Populate CPU configfs path not available in ${NETCONS_PATH}/userdata/cpu_nr_enabled" >&2 28 + exit "${ksft_skip}" 29 + fi 30 + 31 + echo 1 > "${NETCONS_PATH}/userdata/cpu_nr_enabled" 32 + } 33 + 34 + # Disable the sysdata cpu_nr feature 35 + function unset_cpu_nr() { 36 + echo 0 > "${NETCONS_PATH}/userdata/cpu_nr_enabled" 37 + } 38 + 39 + # Test if MSG content and `cpu=${CPU}` exists in OUTPUT_FILE 40 + function validate_sysdata_cpu_exists() { 41 + # OUTPUT_FILE will contain something like: 42 + # 6.11.1-0_fbk0_rc13_509_g30d75cea12f7,13,1822,115075213798,-;netconsole selftest: netcons_gtJHM 43 + # userdatakey=userdatavalue 44 + # cpu=X 45 + 46 + if [ ! -f "$OUTPUT_FILE" ]; then 47 + echo "FAIL: File was not generated." >&2 48 + exit "${ksft_fail}" 49 + fi 50 + 51 + if ! grep -q "${MSG}" "${OUTPUT_FILE}"; then 52 + echo "FAIL: ${MSG} not found in ${OUTPUT_FILE}" >&2 53 + cat "${OUTPUT_FILE}" >&2 54 + exit "${ksft_fail}" 55 + fi 56 + 57 + # Check if cpu=XX exists in the file and matches the one used 58 + # in taskset(1) 59 + if ! grep -q "cpu=${CPU}\+" "${OUTPUT_FILE}"; then 60 + echo "FAIL: 'cpu=${CPU}' not found in ${OUTPUT_FILE}" >&2 61 + cat "${OUTPUT_FILE}" >&2 62 + exit "${ksft_fail}" 63 + fi 64 + 65 + rm "${OUTPUT_FILE}" 66 + pkill_socat 67 + } 68 + 69 + # Test if MSG content exists in OUTPUT_FILE but no `cpu=` string 70 + function validate_sysdata_no_cpu() { 71 + if [ ! -f "$OUTPUT_FILE" ]; then 72 + echo "FAIL: File was not generated." >&2 73 + exit "${ksft_fail}" 74 + fi 75 + 76 + if ! grep -q "${MSG}" "${OUTPUT_FILE}"; then 77 + echo "FAIL: ${MSG} not found in ${OUTPUT_FILE}" >&2 78 + cat "${OUTPUT_FILE}" >&2 79 + exit "${ksft_fail}" 80 + fi 81 + 82 + if grep -q "cpu=" "${OUTPUT_FILE}"; then 83 + echo "FAIL: 'cpu= found in ${OUTPUT_FILE}" >&2 84 + cat "${OUTPUT_FILE}" >&2 85 + exit "${ksft_fail}" 86 + fi 87 + 88 + rm "${OUTPUT_FILE}" 89 + } 90 + 91 + # Start socat, send the message and wait for the file to show up in the file 92 + # system 93 + function runtest { 94 + # Listen for netconsole port inside the namespace and destination 95 + # interface 96 + listen_port_and_save_to "${OUTPUT_FILE}" & 97 + # Wait for socat to start and listen to the port. 98 + wait_local_port_listen "${NAMESPACE}" "${PORT}" udp 99 + # Send the message 100 + taskset -c "${CPU}" echo "${MSG}: ${TARGET}" > /dev/kmsg 101 + # Wait until socat saves the file to disk 102 + busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}" 103 + } 104 + 105 + # ========== # 106 + # Start here # 107 + # ========== # 108 + 109 + modprobe netdevsim 2> /dev/null || true 110 + modprobe netconsole 2> /dev/null || true 111 + 112 + # Check for basic system dependency and exit if not found 113 + check_for_dependencies 114 + # This test also depends on taskset(1). Check for it before starting the test 115 + check_for_taskset 116 + 117 + # Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5) 118 + echo "6 5" > /proc/sys/kernel/printk 119 + # Remove the namespace, interfaces and netconsole target on exit 120 + trap cleanup EXIT 121 + # Create one namespace and two interfaces 122 + set_network 123 + # Create a dynamic target for netconsole 124 + create_dynamic_target 125 + 126 + #==================================================== 127 + # TEST #1 128 + # Send message from a random CPU 129 + #==================================================== 130 + # Random CPU in the system 131 + CPU=$((RANDOM % $(nproc))) 132 + OUTPUT_FILE="/tmp/${TARGET}_1" 133 + MSG="Test #1 from CPU${CPU}" 134 + # Enable the auto population of cpu_nr 135 + set_cpu_nr 136 + runtest 137 + # Make sure the message was received in the dst part 138 + # and exit 139 + validate_sysdata_cpu_exists 140 + 141 + #==================================================== 142 + # TEST #2 143 + # This test now adds userdata together with sysdata 144 + # =================================================== 145 + # Get a new random CPU 146 + CPU=$((RANDOM % $(nproc))) 147 + OUTPUT_FILE="/tmp/${TARGET}_2" 148 + MSG="Test #2 from CPU${CPU}" 149 + set_user_data 150 + runtest 151 + validate_sysdata_cpu_exists 152 + 153 + # =================================================== 154 + # TEST #3 155 + # Unset cpu_nr, so, no CPU should be appended. 156 + # userdata is still set 157 + # =================================================== 158 + CPU=$((RANDOM % $(nproc))) 159 + OUTPUT_FILE="/tmp/${TARGET}_3" 160 + MSG="Test #3 from CPU${CPU}" 161 + # Enable the auto population of cpu_nr 162 + unset_cpu_nr 163 + runtest 164 + # At this time, cpu= shouldn't be present in the msg 165 + validate_sysdata_no_cpu 166 + 167 + exit "${ksft_pass}"