Skip to content

Commit 12fd83c

Browse files
leitaodavem330
authored andcommitted
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>
1 parent ec15bc4 commit 12fd83c

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

tools/testing/selftests/drivers/net/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ TEST_PROGS := \
99
netcons_basic.sh \
1010
netcons_fragmented_msg.sh \
1111
netcons_overflow.sh \
12+
netcons_sysdata.sh \
1213
ping.py \
1314
queues.py \
1415
stats.py \

tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,20 @@ function check_for_dependencies() {
230230
exit "${ksft_skip}"
231231
fi
232232
}
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+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
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}"

0 commit comments

Comments
 (0)