#!/usr/bin/env bash # SPDX-License-Identifier: GPL-2.0 # Repeatedly send kernel messages, toggles netconsole targets on and off, # creates and deletes targets in parallel, and toggles the source interface to # simulate stress conditions. # # This test aims to verify the robustness of netconsole under dynamic # configurations and concurrent operations. # # The major goal is to run this test with LOCKDEP, Kmemleak and KASAN to make # sure no issues is reported. # # Author: Breno Leitao set -euo pipefail SCRIPTDIR=$(dirname "$(readlink -e "${BASH_SOURCE[0]}")") source "${SCRIPTDIR}"/lib/sh/lib_netcons.sh # Number of times the main loop run ITERATIONS=${1:-150} # Only test extended format FORMAT="extended" # And ipv6 only IP_VERSION="ipv6" # Create, enable and delete some targets. create_and_delete_random_target() { COUNT=2 RND_PREFIX=$(mktemp -u netcons_rnd_XXXX_) if [ -d "${NETCONS_CONFIGFS}/${RND_PREFIX}${COUNT}" ] || \ [ -d "${NETCONS_CONFIGFS}/${RND_PREFIX}0" ]; then echo "Function didn't finish yet, skipping it." >&2 return fi # enable COUNT targets for i in $(seq ${COUNT}) do RND_TARGET="${RND_PREFIX}"${i} RND_TARGET_PATH="${NETCONS_CONFIGFS}"/"${RND_TARGET}" # Basic population so the target can come up _create_dynamic_target "${FORMAT}" "${RND_TARGET_PATH}" done echo "netconsole selftest: ${COUNT} additional targets were created" > /dev/kmsg # disable them all for i in $(seq ${COUNT}) do RND_TARGET="${RND_PREFIX}"${i} RND_TARGET_PATH="${NETCONS_CONFIGFS}"/"${RND_TARGET}" if [[ $(cat "${RND_TARGET_PATH}/enabled") -eq 1 ]] then echo 0 > "${RND_TARGET_PATH}"/enabled fi rmdir "${RND_TARGET_PATH}" done } # Disable and enable the target mid-air, while messages # are being transmitted. toggle_netcons_target() { for i in $(seq 2) do if [ ! -d "${NETCONS_PATH}" ] then break fi echo 0 > "${NETCONS_PATH}"/enabled 2> /dev/null || true # Try to enable a bit harder, given it might fail to enable # Write to `enabled` might fail depending on the lock, which is # highly contentious here for _ in $(seq 5) do echo 1 > "${NETCONS_PATH}"/enabled 2> /dev/null || true done done } toggle_iface(){ ip link set "${SRCIF}" down ip link set "${SRCIF}" up } # 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 # 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 "${IP_VERSION}" # Create a dynamic target for netconsole create_dynamic_target "${FORMAT}" for i in $(seq "$ITERATIONS") do for _ in $(seq 10) do echo "${MSG}: ${TARGET} ${i}" > /dev/kmsg done wait if (( i % 30 == 0 )); then toggle_netcons_target & fi if (( i % 50 == 0 )); then # create some targets, enable them, send msg and disable # all in a parallel thread create_and_delete_random_target & fi if (( i % 70 == 0 )); then toggle_iface & fi done wait exit "${EXIT_STATUS}"