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