1#!/usr/bin/env bash 2# SPDX-License-Identifier: GPL-2.0 3 4# Repeatedly send kernel messages, toggles netconsole targets on and off, 5# creates and deletes targets in parallel, and toggles the source interface to 6# simulate stress conditions. 7# 8# This test aims to verify the robustness of netconsole under dynamic 9# configurations and concurrent operations. 10# 11# The major goal is to run this test with LOCKDEP, Kmemleak and KASAN to make 12# sure no issues is reported. 13# 14# Author: Breno Leitao <leitao@debian.org> 15 16set -euo pipefail 17 18SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") 19 20source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh 21 22# Number of times the main loop run 23ITERATIONS=${1:-150} 24 25# Only test extended format 26FORMAT="extended" 27# And ipv6 only 28IP_VERSION="ipv6" 29 30# Create, enable and delete some targets. 31create_and_delete_random_target() { 32 COUNT=2 33 RND_PREFIX=$(mktemp -u netcons_rnd_XXXX_) 34 35 if [ -d "${NETCONS_CONFIGFS}/${RND_PREFIX}${COUNT}" ] || \ 36 [ -d "${NETCONS_CONFIGFS}/${RND_PREFIX}0" ]; then 37 echo "Function didn't finish yet, skipping it." >&2 38 return 39 fi 40 41 # enable COUNT targets 42 for i in $(seq ${COUNT}) 43 do 44 RND_TARGET="${RND_PREFIX}"${i} 45 RND_TARGET_PATH="${NETCONS_CONFIGFS}"/"${RND_TARGET}" 46 47 # Basic population so the target can come up 48 _create_dynamic_target "${FORMAT}" "${RND_TARGET_PATH}" 49 done 50 51 echo "netconsole selftest: ${COUNT} additional targets were created" > /dev/kmsg 52 # disable them all 53 for i in $(seq ${COUNT}) 54 do 55 RND_TARGET="${RND_PREFIX}"${i} 56 RND_TARGET_PATH="${NETCONS_CONFIGFS}"/"${RND_TARGET}" 57 if [[ $(cat "${RND_TARGET_PATH}/enabled") -eq 1 ]] 58 then 59 echo 0 > "${RND_TARGET_PATH}"/enabled 60 fi 61 rmdir "${RND_TARGET_PATH}" 62 done 63} 64 65# Disable and enable the target mid-air, while messages 66# are being transmitted. 67toggle_netcons_target() { 68 for i in $(seq 2) 69 do 70 if [ ! -d "${NETCONS_PATH}" ] 71 then 72 break 73 fi 74 echo 0 > "${NETCONS_PATH}"/enabled 2> /dev/null || true 75 # Try to enable a bit harder, given it might fail to enable 76 # Write to `enabled` might fail depending on the lock, which is 77 # highly contentious here 78 for _ in $(seq 5) 79 do 80 echo 1 > "${NETCONS_PATH}"/enabled 2> /dev/null || true 81 done 82 done 83} 84 85toggle_iface(){ 86 ip link set "${SRCIF}" down 87 ip link set "${SRCIF}" up 88} 89 90# Start here 91 92modprobe netdevsim 2> /dev/null || true 93modprobe netconsole 2> /dev/null || true 94 95# Check for basic system dependency and exit if not found 96check_for_dependencies 97# Set current loglevel to KERN_INFO(6), and default to KERN_NOTICE(5) 98echo "6 5" > /proc/sys/kernel/printk 99# Remove the namespace, interfaces and netconsole target on exit 100trap cleanup EXIT 101# Create one namespace and two interfaces 102set_network "${IP_VERSION}" 103# Create a dynamic target for netconsole 104create_dynamic_target "${FORMAT}" 105 106for i in $(seq "$ITERATIONS") 107do 108 for _ in $(seq 10) 109 do 110 echo "${MSG}: ${TARGET} ${i}" > /dev/kmsg 111 done 112 wait 113 114 if (( i % 30 == 0 )); then 115 toggle_netcons_target & 116 fi 117 118 if (( i % 50 == 0 )); then 119 # create some targets, enable them, send msg and disable 120 # all in a parallel thread 121 create_and_delete_random_target & 122 fi 123 124 if (( i % 70 == 0 )); then 125 toggle_iface & 126 fi 127done 128wait 129 130exit "${EXIT_STATUS}" 131