xref: /linux/tools/testing/selftests/drivers/net/netcons_sysdata.sh (revision 2f435137a0484f11b47554281091ef4908f8cb31)
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# Disable the sysdata cpu_nr feature
35function 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
40function 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
70function 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
93function 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
109modprobe netdevsim 2> /dev/null || true
110modprobe netconsole 2> /dev/null || true
111
112# Check for basic system dependency and exit if not found
113check_for_dependencies
114# This test also depends on taskset(1). Check for it before starting the test
115check_for_taskset
116
117# Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5)
118echo "6 5" > /proc/sys/kernel/printk
119# Remove the namespace, interfaces and netconsole target on exit
120trap cleanup EXIT
121# Create one namespace and two interfaces
122set_network
123# Create a dynamic target for netconsole
124create_dynamic_target
125
126#====================================================
127# TEST #1
128# Send message from a random CPU
129#====================================================
130# Random CPU in the system
131CPU=$((RANDOM % $(nproc)))
132OUTPUT_FILE="/tmp/${TARGET}_1"
133MSG="Test #1 from CPU${CPU}"
134# Enable the auto population of cpu_nr
135set_cpu_nr
136runtest
137# Make sure the message was received in the dst part
138# and exit
139validate_sysdata_cpu_exists
140
141#====================================================
142# TEST #2
143# This test now adds userdata together with sysdata
144# ===================================================
145# Get a new random CPU
146CPU=$((RANDOM % $(nproc)))
147OUTPUT_FILE="/tmp/${TARGET}_2"
148MSG="Test #2 from CPU${CPU}"
149set_user_data
150runtest
151validate_sysdata_cpu_exists
152
153# ===================================================
154# TEST #3
155# Unset cpu_nr, so, no CPU should be appended.
156# userdata is still set
157# ===================================================
158CPU=$((RANDOM % $(nproc)))
159OUTPUT_FILE="/tmp/${TARGET}_3"
160MSG="Test #3 from CPU${CPU}"
161# Enable the auto population of cpu_nr
162unset_cpu_nr
163runtest
164# At this time, cpu= shouldn't be present in the msg
165validate_sysdata_no_cpu
166
167exit "${ksft_pass}"
168