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