xref: /linux/tools/testing/selftests/drivers/net/netcons_sysdata.sh (revision 1cc3462159babb69c84c39cb1b4e262aef3ea325)
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
17set -euo pipefail
18
19SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
20
21source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh
22
23# Enable the sysdata cpu_nr feature
24function 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# Enable the taskname to be appended to sysdata
35function set_taskname() {
36	if [[ ! -f "${NETCONS_PATH}/userdata/taskname_enabled" ]]
37	then
38		echo "Not able to enable taskname sysdata append. Configfs not available in ${NETCONS_PATH}/userdata/taskname_enabled" >&2
39		exit "${ksft_skip}"
40	fi
41
42	echo 1 > "${NETCONS_PATH}/userdata/taskname_enabled"
43}
44
45# Disable the sysdata cpu_nr feature
46function unset_cpu_nr() {
47	echo 0 > "${NETCONS_PATH}/userdata/cpu_nr_enabled"
48}
49
50# Once called, taskname=<..> will not be appended anymore
51function unset_taskname() {
52	echo 0 > "${NETCONS_PATH}/userdata/taskname_enabled"
53}
54
55# Test if MSG contains sysdata
56function validate_sysdata() {
57	# OUTPUT_FILE will contain something like:
58	# 6.11.1-0_fbk0_rc13_509_g30d75cea12f7,13,1822,115075213798,-;netconsole selftest: netcons_gtJHM
59	#  userdatakey=userdatavalue
60	#  cpu=X
61	#  taskname=<taskname>
62
63	# Echo is what this test uses to create the message. See runtest()
64	# function
65	SENDER="echo"
66
67	if [ ! -f "$OUTPUT_FILE" ]; then
68		echo "FAIL: File was not generated." >&2
69		exit "${ksft_fail}"
70	fi
71
72	if ! grep -q "${MSG}" "${OUTPUT_FILE}"; then
73		echo "FAIL: ${MSG} not found in ${OUTPUT_FILE}" >&2
74		cat "${OUTPUT_FILE}" >&2
75		exit "${ksft_fail}"
76	fi
77
78	# Check if cpu=XX exists in the file and matches the one used
79	# in taskset(1)
80	if ! grep -q "cpu=${CPU}\+" "${OUTPUT_FILE}"; then
81		echo "FAIL: 'cpu=${CPU}' not found in ${OUTPUT_FILE}" >&2
82		cat "${OUTPUT_FILE}" >&2
83		exit "${ksft_fail}"
84	fi
85
86	if ! grep -q "taskname=${SENDER}" "${OUTPUT_FILE}"; then
87		echo "FAIL: 'taskname=echo' not found in ${OUTPUT_FILE}" >&2
88		cat "${OUTPUT_FILE}" >&2
89		exit "${ksft_fail}"
90	fi
91
92	rm "${OUTPUT_FILE}"
93	pkill_socat
94}
95
96# Test if MSG content exists in OUTPUT_FILE but no `cpu=` and `taskname=`
97# strings
98function validate_no_sysdata() {
99	if [ ! -f "$OUTPUT_FILE" ]; then
100		echo "FAIL: File was not generated." >&2
101		exit "${ksft_fail}"
102	fi
103
104	if ! grep -q "${MSG}" "${OUTPUT_FILE}"; then
105		echo "FAIL: ${MSG} not found in ${OUTPUT_FILE}" >&2
106		cat "${OUTPUT_FILE}" >&2
107		exit "${ksft_fail}"
108	fi
109
110	if grep -q "cpu=" "${OUTPUT_FILE}"; then
111		echo "FAIL: 'cpu=  found in ${OUTPUT_FILE}" >&2
112		cat "${OUTPUT_FILE}" >&2
113		exit "${ksft_fail}"
114	fi
115
116	if grep -q "taskname=" "${OUTPUT_FILE}"; then
117		echo "FAIL: 'taskname=  found in ${OUTPUT_FILE}" >&2
118		cat "${OUTPUT_FILE}" >&2
119		exit "${ksft_fail}"
120	fi
121
122	rm "${OUTPUT_FILE}"
123}
124
125# Start socat, send the message and wait for the file to show up in the file
126# system
127function runtest {
128	# Listen for netconsole port inside the namespace and destination
129	# interface
130	listen_port_and_save_to "${OUTPUT_FILE}" &
131	# Wait for socat to start and listen to the port.
132	wait_local_port_listen "${NAMESPACE}" "${PORT}" udp
133	# Send the message
134	taskset -c "${CPU}" echo "${MSG}: ${TARGET}" > /dev/kmsg
135	# Wait until socat saves the file to disk
136	busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}"
137}
138
139# ========== #
140# Start here #
141# ========== #
142
143modprobe netdevsim 2> /dev/null || true
144modprobe netconsole 2> /dev/null || true
145
146# Check for basic system dependency and exit if not found
147check_for_dependencies
148# This test also depends on taskset(1). Check for it before starting the test
149check_for_taskset
150
151# Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5)
152echo "6 5" > /proc/sys/kernel/printk
153# Remove the namespace, interfaces and netconsole target on exit
154trap cleanup EXIT
155# Create one namespace and two interfaces
156set_network
157# Create a dynamic target for netconsole
158create_dynamic_target
159
160#====================================================
161# TEST #1
162# Send message from a random CPU
163#====================================================
164# Random CPU in the system
165CPU=$((RANDOM % $(nproc)))
166OUTPUT_FILE="/tmp/${TARGET}_1"
167MSG="Test #1 from CPU${CPU}"
168# Enable the auto population of cpu_nr
169set_cpu_nr
170# Enable taskname to be appended to sysdata
171set_taskname
172runtest
173# Make sure the message was received in the dst part
174# and exit
175validate_sysdata
176
177#====================================================
178# TEST #2
179# This test now adds userdata together with sysdata
180# ===================================================
181# Get a new random CPU
182CPU=$((RANDOM % $(nproc)))
183OUTPUT_FILE="/tmp/${TARGET}_2"
184MSG="Test #2 from CPU${CPU}"
185set_user_data
186runtest
187validate_sysdata
188
189# ===================================================
190# TEST #3
191# Unset cpu_nr, so, no CPU should be appended.
192# userdata is still set
193# ===================================================
194CPU=$((RANDOM % $(nproc)))
195OUTPUT_FILE="/tmp/${TARGET}_3"
196MSG="Test #3 from CPU${CPU}"
197# Enable the auto population of cpu_nr
198unset_cpu_nr
199unset_taskname
200runtest
201# At this time, cpu= shouldn't be present in the msg
202validate_no_sysdata
203
204exit "${ksft_pass}"
205