1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0-or-later 3# Copyright (C) 2017 Red Hat, Inc. 4# 5# Test functionality of dynamic debug feature by enabling 6# and disabling traces with available flags. Check that these 7# settings don't cause issues by searching dmesg. 8# 9# This test handles changes of dynamic debug interface from 10# commits 5ca7d2a6 (dynamic_debug: describe_flags with 11# '=[pmflt_]*') and 8ba6ebf5 (Dynamic debug: Add more flags) 12 13TST_TESTFUNC=ddebug_test 14TST_NEEDS_CMDS="awk /bin/echo" 15TST_NEEDS_TMPDIR=1 16TST_NEEDS_ROOT=1 17TST_SETUP=setup 18TST_CLEANUP=cleanup 19 20. tst_test.sh 21 22 23DEBUGFS_WAS_MOUNTED=0 24DEBUGFS_PATH="" 25DEBUGFS_CONTROL="" 26DYNDEBUG_STATEMENTS="./debug_statements" 27EMPTY_FLAG="-" 28NEW_INTERFACE=0 29 30 31mount_debugfs() 32{ 33 if grep -q debugfs /proc/mounts ; then 34 DEBUGFS_WAS_MOUNTED=1 35 DEBUGFS_PATH=$(awk '/debugfs/{print $2}' /proc/mounts) 36 tst_res TINFO "debugfs already mounted at $DEBUGFS_PATH" 37 else 38 if ! grep -q debugfs /proc/filesystems ; then 39 tst_res TCONF "debugfs not supported" 40 fi 41 DEBUGFS_PATH="$PWD/tst_debug" 42 mkdir "$DEBUGFS_PATH" 43 if mount -t debugfs xxx "$DEBUGFS_PATH" ; then 44 tst_res TINFO "debugfs mounted at $DEBUGFS_PATH" 45 else 46 tst_res TFAIL "Unable to mount debugfs" 47 fi 48 fi 49} 50 51setup() 52{ 53 if tst_kvcmp -lt 2.6.30 ; then 54 tst_brk TCONF "Dynamic debug is available since version 2.6.30" 55 fi 56 57 mount_debugfs 58 if [ ! -d "$DEBUGFS_PATH/dynamic_debug" ] ; then 59 tst_brk TBROK "Unable to find $DEBUGFS_PATH/dynamic_debug" 60 fi 61 DEBUGFS_CONTROL="$DEBUGFS_PATH/dynamic_debug/control" 62 if [ ! -e "$DEBUGFS_CONTROL" ] ; then 63 tst_brk TBROK "Unable to find $DEBUGFS_CONTROL" 64 fi 65 66 # Both patches with changes were backported to RHEL6 kernel 2.6.32-547 67 if tst_kvcmp -ge '3.4 RHEL6:2.6.32-547' ; then 68 NEW_INTERFACE=1 69 EMPTY_FLAG="=_" 70 fi 71 72 grep -v "^#" "$DEBUGFS_CONTROL" > "$DYNDEBUG_STATEMENTS" 73} 74 75do_flag() 76{ 77 local FLAG="$1" 78 local OPTION_TO_SET="$2" 79 local OPTION_VALUE="$3" 80 81 if ! echo "$OPTION_TO_SET $OPTION_VALUE $FLAG" > \ 82 "$DEBUGFS_CONTROL" ; then 83 tst_res TFAIL "Setting '$OPTION_TO_SET $OPTION_VALUE " \ 84 "$FLAG' failed with $?!" 85 fi 86} 87 88do_all_flags() 89{ 90 OPTION="$1" 91 ALL_INPUTS="$2" 92 93 for INPUT_LINE in $ALL_INPUTS; do 94 do_flag "+p" "$OPTION" "$INPUT_LINE" 95 if tst_kvcmp -ge 3.2 || [ $NEW_INTERFACE -eq 1 ] ; then 96 do_flag "+flmt" "$OPTION" "$INPUT_LINE" 97 do_flag "-flmt" "$OPTION" "$INPUT_LINE" 98 fi 99 do_flag "-p" "$OPTION" "$INPUT_LINE" 100 done 101 102 if awk -v emp="$EMPTY_FLAG" '$3 != emp' "$DEBUGFS_CONTROL" \ 103 | grep -v -q "^#" ; then 104 tst_res TFAIL "Failed to remove all set flags" 105 fi 106} 107 108ddebug_test() 109{ 110 dmesg > ./dmesg.old 111 112 DD_FUNCS=$(awk -F " |]" '{print $3}' "$DYNDEBUG_STATEMENTS" \ 113 | sort | uniq) 114 DD_FILES=$(awk -F " |:" '{print $1}' "$DYNDEBUG_STATEMENTS" \ 115 | sort | uniq) 116 DD_LINES=$(awk -F " |:" '{print $2}' "$DYNDEBUG_STATEMENTS" \ 117 | sort | uniq) 118 DD_MODULES=$(awk -F [][] '{print $2}' "$DYNDEBUG_STATEMENTS" \ 119 | sort | uniq) 120 121 do_all_flags "func" "$DD_FUNCS" 122 do_all_flags "file" "$DD_FILES" 123 do_all_flags "line" "$DD_LINES" 124 do_all_flags "module" "$DD_MODULES" 125 126 dmesg > ./dmesg.new 127 sed -i -e 1,`wc -l < ./dmesg.old`d ./dmesg.new 128 if grep -q -e "Kernel panic" -e "Oops" -e "general protection fault" \ 129 -e "general protection handler: wrong gs" -e "\(XEN\) Panic" \ 130 -e "fault" -e "warn" -e "\<BUG\>" ./dmesg.new ; then 131 tst_res TFAIL "Issues found in dmesg!" 132 else 133 tst_res TPASS "Dynamic debug OK" 134 fi 135} 136 137cleanup() 138{ 139 if [ -e "$DYNDEBUG_STATEMENTS" ]; then 140 FLAGS_SET=$(awk -v emp="$EMPTY_FLAG" '$3 != emp' $DYNDEBUG_STATEMENTS) 141 fi 142 if [ "$FLAGS_SET" ] ; then 143 FLAG_PREFIX=$([ $NEW_INTERFACE -eq 1 ] && echo "" || echo "+") 144 /bin/echo "$FLAGS_SET" | while read -r FLAG_LINE ; do 145 /bin/echo -n "$FLAG_LINE" \ 146 | awk -v prf="$FLAG_PREFIX" -F " |:" \ 147 '{print "file "$1" line "$2" "prf $4}' \ 148 > "$DEBUGFS_CONTROL" 149 done 150 fi 151 if [ $DEBUGFS_WAS_MOUNTED -eq 0 -a -n "$DEBUGFS_PATH" ] ; then 152 tst_umount "$DEBUGFS_PATH" 153 fi 154} 155 156tst_run 157