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