1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
|
#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0
# A test that makes sure that sysdata runtime CPU data is properly set
# when a message is sent.
#
# There are 3 different tests, every time sent using a random CPU.
# - Test #1
# * Only enable cpu_nr sysdata feature.
# - Test #2
# * Keep cpu_nr sysdata feature enable and enable userdata.
# - Test #3
# * keep userdata enabled, and disable sysdata cpu_nr feature.
#
# Author: Breno Leitao <leitao@debian.org>
set -euo pipefail
SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")
source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh
# Enable the sysdata cpu_nr feature
function set_cpu_nr() {
if [[ ! -f "${NETCONS_PATH}/userdata/cpu_nr_enabled" ]]
then
echo "Populate CPU configfs path not available in ${NETCONS_PATH}/userdata/cpu_nr_enabled" >&2
exit "${ksft_skip}"
fi
echo 1 > "${NETCONS_PATH}/userdata/cpu_nr_enabled"
}
# Enable the taskname to be appended to sysdata
function set_taskname() {
if [[ ! -f "${NETCONS_PATH}/userdata/taskname_enabled" ]]
then
echo "Not able to enable taskname sysdata append. Configfs not available in ${NETCONS_PATH}/userdata/taskname_enabled" >&2
exit "${ksft_skip}"
fi
echo 1 > "${NETCONS_PATH}/userdata/taskname_enabled"
}
# Enable the release to be appended to sysdata
function set_release() {
if [[ ! -f "${NETCONS_PATH}/userdata/release_enabled" ]]
then
echo "Not able to enable release sysdata append. Configfs not available in ${NETCONS_PATH}/userdata/release_enabled" >&2
exit "${ksft_skip}"
fi
echo 1 > "${NETCONS_PATH}/userdata/release_enabled"
}
# Enable the msgid to be appended to sysdata
function set_msgid() {
if [[ ! -f "${NETCONS_PATH}/userdata/msgid_enabled" ]]
then
echo "Not able to enable msgid sysdata append. Configfs not available in ${NETCONS_PATH}/userdata/msgid_enabled" >&2
exit "${ksft_skip}"
fi
echo 1 > "${NETCONS_PATH}/userdata/msgid_enabled"
}
# Disable the sysdata cpu_nr feature
function unset_cpu_nr() {
echo 0 > "${NETCONS_PATH}/userdata/cpu_nr_enabled"
}
# Once called, taskname=<..> will not be appended anymore
function unset_taskname() {
echo 0 > "${NETCONS_PATH}/userdata/taskname_enabled"
}
function unset_release() {
echo 0 > "${NETCONS_PATH}/userdata/release_enabled"
}
function unset_msgid() {
echo 0 > "${NETCONS_PATH}/userdata/msgid_enabled"
}
# Test if MSG contains sysdata
function validate_sysdata() {
# OUTPUT_FILE will contain something like:
# 6.11.1-0_fbk0_rc13_509_g30d75cea12f7,13,1822,115075213798,-;netconsole selftest: netcons_gtJHM
# userdatakey=userdatavalue
# cpu=X
# taskname=<taskname>
# msgid=<id>
# Echo is what this test uses to create the message. See runtest()
# function
SENDER="echo"
if [ ! -f "$OUTPUT_FILE" ]; then
echo "FAIL: File was not generated." >&2
exit "${ksft_fail}"
fi
if ! grep -q "${MSG}" "${OUTPUT_FILE}"; then
echo "FAIL: ${MSG} not found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
# Check if cpu=XX exists in the file and matches the one used
# in taskset(1)
if ! grep -q "cpu=${CPU}\+" "${OUTPUT_FILE}"; then
echo "FAIL: 'cpu=${CPU}' not found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
if ! grep -q "taskname=${SENDER}" "${OUTPUT_FILE}"; then
echo "FAIL: 'taskname=echo' not found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
if ! grep -q "msgid=[0-9]\+$" "${OUTPUT_FILE}"; then
echo "FAIL: 'msgid=<id>' not found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
rm "${OUTPUT_FILE}"
pkill_socat
}
function validate_release() {
RELEASE=$(uname -r)
if [ ! -f "$OUTPUT_FILE" ]; then
echo "FAIL: File was not generated." >&2
exit "${ksft_fail}"
fi
if ! grep -q "release=${RELEASE}" "${OUTPUT_FILE}"; then
echo "FAIL: 'release=${RELEASE}' not found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
}
# Test if MSG content exists in OUTPUT_FILE but no `cpu=` and `taskname=`
# strings
function validate_no_sysdata() {
if [ ! -f "$OUTPUT_FILE" ]; then
echo "FAIL: File was not generated." >&2
exit "${ksft_fail}"
fi
if ! grep -q "${MSG}" "${OUTPUT_FILE}"; then
echo "FAIL: ${MSG} not found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
if grep -q "cpu=" "${OUTPUT_FILE}"; then
echo "FAIL: 'cpu= found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
if grep -q "taskname=" "${OUTPUT_FILE}"; then
echo "FAIL: 'taskname= found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
if grep -q "release=" "${OUTPUT_FILE}"; then
echo "FAIL: 'release= found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
if grep -q "msgid=" "${OUTPUT_FILE}"; then
echo "FAIL: 'msgid= found in ${OUTPUT_FILE}" >&2
cat "${OUTPUT_FILE}" >&2
exit "${ksft_fail}"
fi
rm "${OUTPUT_FILE}"
}
# Start socat, send the message and wait for the file to show up in the file
# system
function runtest {
# Listen for netconsole port inside the namespace and destination
# interface
listen_port_and_save_to "${OUTPUT_FILE}" &
# Wait for socat to start and listen to the port.
wait_local_port_listen "${NAMESPACE}" "${PORT}" udp
# Send the message
taskset -c "${CPU}" echo "${MSG}: ${TARGET}" > /dev/kmsg
# Wait until socat saves the file to disk
busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}"
}
# ========== #
# Start here #
# ========== #
modprobe netdevsim 2> /dev/null || true
modprobe netconsole 2> /dev/null || true
# Check for basic system dependency and exit if not found
check_for_dependencies
# This test also depends on taskset(1). Check for it before starting the test
check_for_taskset
# Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5)
echo "6 5" > /proc/sys/kernel/printk
# Remove the namespace, interfaces and netconsole target on exit
trap cleanup EXIT
# Create one namespace and two interfaces
set_network
# Create a dynamic target for netconsole
create_dynamic_target
#====================================================
# TEST #1
# Send message from a random CPU
#====================================================
# Random CPU in the system
CPU=$((RANDOM % $(nproc)))
OUTPUT_FILE="/tmp/${TARGET}_1"
MSG="Test #1 from CPU${CPU}"
# Enable the auto population of cpu_nr
set_cpu_nr
# Enable taskname to be appended to sysdata
set_taskname
set_release
set_msgid
runtest
# Make sure the message was received in the dst part
# and exit
validate_release
validate_sysdata
#====================================================
# TEST #2
# This test now adds userdata together with sysdata
# ===================================================
# Get a new random CPU
CPU=$((RANDOM % $(nproc)))
OUTPUT_FILE="/tmp/${TARGET}_2"
MSG="Test #2 from CPU${CPU}"
set_user_data
runtest
validate_release
validate_sysdata
# ===================================================
# TEST #3
# Unset all sysdata, fail if any userdata is set
# ===================================================
CPU=$((RANDOM % $(nproc)))
OUTPUT_FILE="/tmp/${TARGET}_3"
MSG="Test #3 from CPU${CPU}"
unset_cpu_nr
unset_taskname
unset_release
unset_msgid
runtest
# At this time, cpu= shouldn't be present in the msg
validate_no_sysdata
exit "${ksft_pass}"
|