1a2818ee4SJoe Lawrence#!/bin/bash 2a2818ee4SJoe Lawrence# SPDX-License-Identifier: GPL-2.0 3a2818ee4SJoe Lawrence# Copyright (C) 2018 Joe Lawrence <[email protected]> 4a2818ee4SJoe Lawrence 5a2818ee4SJoe Lawrence# Shell functions for the rest of the scripts. 6a2818ee4SJoe Lawrence 7a2818ee4SJoe LawrenceMAX_RETRIES=600 8a2818ee4SJoe LawrenceRETRY_INTERVAL=".1" # seconds 959766286SMichael VetterSYSFS_KERNEL_DIR="/sys/kernel" 1059766286SMichael VetterSYSFS_KLP_DIR="$SYSFS_KERNEL_DIR/livepatch" 1159766286SMichael VetterSYSFS_DEBUG_DIR="$SYSFS_KERNEL_DIR/debug" 1259766286SMichael VetterSYSFS_KPROBES_DIR="$SYSFS_DEBUG_DIR/kprobes" 13*2ca7cd80SFilipe XavierSYSFS_TRACING_DIR="$SYSFS_DEBUG_DIR/tracing" 14a2818ee4SJoe Lawrence 1505564c29SShuah Khan# Kselftest framework requirement - SKIP code is 4 1605564c29SShuah Khanksft_skip=4 1705564c29SShuah Khan 18a2818ee4SJoe Lawrence# log(msg) - write message to kernel log 19a2818ee4SJoe Lawrence# msg - insightful words 20a2818ee4SJoe Lawrencefunction log() { 21a2818ee4SJoe Lawrence echo "$1" > /dev/kmsg 22a2818ee4SJoe Lawrence} 23a2818ee4SJoe Lawrence 24527d37e9SJoe Lawrence# skip(msg) - testing can't proceed 25527d37e9SJoe Lawrence# msg - explanation 26527d37e9SJoe Lawrencefunction skip() { 27527d37e9SJoe Lawrence log "SKIP: $1" 28527d37e9SJoe Lawrence echo "SKIP: $1" >&2 2905564c29SShuah Khan exit $ksft_skip 3005564c29SShuah Khan} 3105564c29SShuah Khan 3205564c29SShuah Khan# root test 3305564c29SShuah Khanfunction is_root() { 3405564c29SShuah Khan uid=$(id -u) 3505564c29SShuah Khan if [ $uid -ne 0 ]; then 3605564c29SShuah Khan echo "skip all tests: must be run as root" >&2 3705564c29SShuah Khan exit $ksft_skip 3805564c29SShuah Khan fi 39527d37e9SJoe Lawrence} 40527d37e9SJoe Lawrence 4154ee3526SMarcos Paulo de Souza# Check if we can compile the modules before loading them 4254ee3526SMarcos Paulo de Souzafunction has_kdir() { 4354ee3526SMarcos Paulo de Souza if [ -z "$KDIR" ]; then 4454ee3526SMarcos Paulo de Souza KDIR="/lib/modules/$(uname -r)/build" 4554ee3526SMarcos Paulo de Souza fi 4654ee3526SMarcos Paulo de Souza 4754ee3526SMarcos Paulo de Souza if [ ! -d "$KDIR" ]; then 4854ee3526SMarcos Paulo de Souza echo "skip all tests: KDIR ($KDIR) not available to compile modules." 4954ee3526SMarcos Paulo de Souza exit $ksft_skip 5054ee3526SMarcos Paulo de Souza fi 5154ee3526SMarcos Paulo de Souza} 5254ee3526SMarcos Paulo de Souza 53a2818ee4SJoe Lawrence# die(msg) - game over, man 54a2818ee4SJoe Lawrence# msg - dying words 55a2818ee4SJoe Lawrencefunction die() { 56a2818ee4SJoe Lawrence log "ERROR: $1" 57a2818ee4SJoe Lawrence echo "ERROR: $1" >&2 58a2818ee4SJoe Lawrence exit 1 59a2818ee4SJoe Lawrence} 60a2818ee4SJoe Lawrence 6135c9e74cSJoe Lawrencefunction push_config() { 6259766286SMichael Vetter DYNAMIC_DEBUG=$(grep '^kernel/livepatch' "$SYSFS_DEBUG_DIR/dynamic_debug/control" | \ 63fbb01c52SJoe Lawrence awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}') 648c666d2aSJoe Lawrence FTRACE_ENABLED=$(sysctl --values kernel.ftrace_enabled) 6559766286SMichael Vetter KPROBE_ENABLED=$(cat "$SYSFS_KPROBES_DIR/enabled") 66*2ca7cd80SFilipe Xavier TRACING_ON=$(cat "$SYSFS_TRACING_DIR/tracing_on") 67*2ca7cd80SFilipe Xavier CURRENT_TRACER=$(cat "$SYSFS_TRACING_DIR/current_tracer") 68*2ca7cd80SFilipe Xavier FTRACE_FILTER=$(cat "$SYSFS_TRACING_DIR/set_ftrace_filter") 69fbb01c52SJoe Lawrence} 70fbb01c52SJoe Lawrence 7135c9e74cSJoe Lawrencefunction pop_config() { 72fbb01c52SJoe Lawrence if [[ -n "$DYNAMIC_DEBUG" ]]; then 7359766286SMichael Vetter echo -n "$DYNAMIC_DEBUG" > "$SYSFS_DEBUG_DIR/dynamic_debug/control" 74fbb01c52SJoe Lawrence fi 758c666d2aSJoe Lawrence if [[ -n "$FTRACE_ENABLED" ]]; then 768c666d2aSJoe Lawrence sysctl kernel.ftrace_enabled="$FTRACE_ENABLED" &> /dev/null 778c666d2aSJoe Lawrence fi 7859766286SMichael Vetter if [[ -n "$KPROBE_ENABLED" ]]; then 7959766286SMichael Vetter echo "$KPROBE_ENABLED" > "$SYSFS_KPROBES_DIR/enabled" 8059766286SMichael Vetter fi 81*2ca7cd80SFilipe Xavier if [[ -n "$TRACING_ON" ]]; then 82*2ca7cd80SFilipe Xavier echo "$TRACING_ON" > "$SYSFS_TRACING_DIR/tracing_on" 83*2ca7cd80SFilipe Xavier fi 84*2ca7cd80SFilipe Xavier if [[ -n "$CURRENT_TRACER" ]]; then 85*2ca7cd80SFilipe Xavier echo "$CURRENT_TRACER" > "$SYSFS_TRACING_DIR/current_tracer" 86*2ca7cd80SFilipe Xavier fi 87*2ca7cd80SFilipe Xavier if [[ -n "$FTRACE_FILTER" ]]; then 88*2ca7cd80SFilipe Xavier echo "$FTRACE_FILTER" \ 89*2ca7cd80SFilipe Xavier | sed -e "/#### all functions enabled ####/d" \ 90*2ca7cd80SFilipe Xavier > "$SYSFS_TRACING_DIR/set_ftrace_filter" 91*2ca7cd80SFilipe Xavier fi 92fbb01c52SJoe Lawrence} 93fbb01c52SJoe Lawrence 94a2818ee4SJoe Lawrencefunction set_dynamic_debug() { 9559766286SMichael Vetter cat <<-EOF > "$SYSFS_DEBUG_DIR/dynamic_debug/control" 96a2818ee4SJoe Lawrence file kernel/livepatch/* +p 97a2818ee4SJoe Lawrence func klp_try_switch_task -p 98a2818ee4SJoe Lawrence EOF 99a2818ee4SJoe Lawrence} 100a2818ee4SJoe Lawrence 1018c666d2aSJoe Lawrencefunction set_ftrace_enabled() { 1024327b9eaSDavid Vernet local can_fail=0 1034327b9eaSDavid Vernet if [[ "$1" == "--fail" ]] ; then 1044327b9eaSDavid Vernet can_fail=1 1054327b9eaSDavid Vernet shift 1064327b9eaSDavid Vernet fi 1074327b9eaSDavid Vernet 1084327b9eaSDavid Vernet local err=$(sysctl -q kernel.ftrace_enabled="$1" 2>&1) 1094327b9eaSDavid Vernet local result=$(sysctl --values kernel.ftrace_enabled) 1104327b9eaSDavid Vernet 1114327b9eaSDavid Vernet if [[ "$result" != "$1" ]] ; then 1124327b9eaSDavid Vernet if [[ $can_fail -eq 1 ]] ; then 113857300b7SJoe Lawrence echo "livepatch: $err" | sed 's#/proc/sys/kernel/#kernel.#' > /dev/kmsg 1144327b9eaSDavid Vernet return 1154327b9eaSDavid Vernet fi 1164327b9eaSDavid Vernet 1174327b9eaSDavid Vernet skip "failed to set kernel.ftrace_enabled = $1" 1184327b9eaSDavid Vernet fi 1194327b9eaSDavid Vernet 1204327b9eaSDavid Vernet echo "livepatch: kernel.ftrace_enabled = $result" > /dev/kmsg 1218c666d2aSJoe Lawrence} 1228c666d2aSJoe Lawrence 1232eeb0d45SJoe Lawrencefunction cleanup() { 1242eeb0d45SJoe Lawrence pop_config 1252eeb0d45SJoe Lawrence} 1262eeb0d45SJoe Lawrence 12735c9e74cSJoe Lawrence# setup_config - save the current config and set a script exit trap that 12835c9e74cSJoe Lawrence# restores the original config. Setup the dynamic debug 1298c666d2aSJoe Lawrence# for verbose livepatching output and turn on 1308c666d2aSJoe Lawrence# the ftrace_enabled sysctl. 13135c9e74cSJoe Lawrencefunction setup_config() { 13205564c29SShuah Khan is_root 13354ee3526SMarcos Paulo de Souza has_kdir 13435c9e74cSJoe Lawrence push_config 13535c9e74cSJoe Lawrence set_dynamic_debug 1368c666d2aSJoe Lawrence set_ftrace_enabled 1 1372eeb0d45SJoe Lawrence trap cleanup EXIT INT TERM HUP 13835c9e74cSJoe Lawrence} 13935c9e74cSJoe Lawrence 140a2818ee4SJoe Lawrence# loop_until(cmd) - loop a command until it is successful or $MAX_RETRIES, 141a2818ee4SJoe Lawrence# sleep $RETRY_INTERVAL between attempts 142a2818ee4SJoe Lawrence# cmd - command and its arguments to run 143a2818ee4SJoe Lawrencefunction loop_until() { 144a2818ee4SJoe Lawrence local cmd="$*" 145a2818ee4SJoe Lawrence local i=0 146a2818ee4SJoe Lawrence while true; do 147a2818ee4SJoe Lawrence eval "$cmd" && return 0 148a2818ee4SJoe Lawrence [[ $((i++)) -eq $MAX_RETRIES ]] && return 1 149a2818ee4SJoe Lawrence sleep $RETRY_INTERVAL 150a2818ee4SJoe Lawrence done 151a2818ee4SJoe Lawrence} 152a2818ee4SJoe Lawrence 153a2818ee4SJoe Lawrencefunction is_livepatch_mod() { 154a2818ee4SJoe Lawrence local mod="$1" 155a2818ee4SJoe Lawrence 156c4bbe83dSMarcos Paulo de Souza if [[ ! -f "test_modules/$mod.ko" ]]; then 157c4bbe83dSMarcos Paulo de Souza die "Can't find \"test_modules/$mod.ko\", try \"make\"" 158c4bbe83dSMarcos Paulo de Souza fi 159c4bbe83dSMarcos Paulo de Souza 160c4bbe83dSMarcos Paulo de Souza if [[ $(modinfo "test_modules/$mod.ko" | awk '/^livepatch:/{print $NF}') == "Y" ]]; then 161a2818ee4SJoe Lawrence return 0 162a2818ee4SJoe Lawrence fi 163a2818ee4SJoe Lawrence 164a2818ee4SJoe Lawrence return 1 165a2818ee4SJoe Lawrence} 166a2818ee4SJoe Lawrence 167a2818ee4SJoe Lawrencefunction __load_mod() { 168a2818ee4SJoe Lawrence local mod="$1"; shift 169a2818ee4SJoe Lawrence 170c4bbe83dSMarcos Paulo de Souza local msg="% insmod test_modules/$mod.ko $*" 171a2818ee4SJoe Lawrence log "${msg%% }" 172c4bbe83dSMarcos Paulo de Souza ret=$(insmod "test_modules/$mod.ko" "$@" 2>&1) 173a2818ee4SJoe Lawrence if [[ "$ret" != "" ]]; then 174a2818ee4SJoe Lawrence die "$ret" 175a2818ee4SJoe Lawrence fi 176a2818ee4SJoe Lawrence 177a2818ee4SJoe Lawrence # Wait for module in sysfs ... 178a2818ee4SJoe Lawrence loop_until '[[ -e "/sys/module/$mod" ]]' || 179a2818ee4SJoe Lawrence die "failed to load module $mod" 180a2818ee4SJoe Lawrence} 181a2818ee4SJoe Lawrence 182a2818ee4SJoe Lawrence 183a2818ee4SJoe Lawrence# load_mod(modname, params) - load a kernel module 184a2818ee4SJoe Lawrence# modname - module name to load 185c4bbe83dSMarcos Paulo de Souza# params - module parameters to pass to insmod 186a2818ee4SJoe Lawrencefunction load_mod() { 187a2818ee4SJoe Lawrence local mod="$1"; shift 188a2818ee4SJoe Lawrence 189a2818ee4SJoe Lawrence is_livepatch_mod "$mod" && 190a2818ee4SJoe Lawrence die "use load_lp() to load the livepatch module $mod" 191a2818ee4SJoe Lawrence 192fbb76d57SJoe Lawrence __load_mod "$mod" "$@" 193a2818ee4SJoe Lawrence} 194a2818ee4SJoe Lawrence 195a2818ee4SJoe Lawrence# load_lp_nowait(modname, params) - load a kernel module with a livepatch 196a2818ee4SJoe Lawrence# but do not wait on until the transition finishes 197a2818ee4SJoe Lawrence# modname - module name to load 198c4bbe83dSMarcos Paulo de Souza# params - module parameters to pass to insmod 199a2818ee4SJoe Lawrencefunction load_lp_nowait() { 200a2818ee4SJoe Lawrence local mod="$1"; shift 201a2818ee4SJoe Lawrence 202a2818ee4SJoe Lawrence is_livepatch_mod "$mod" || 203a2818ee4SJoe Lawrence die "module $mod is not a livepatch" 204a2818ee4SJoe Lawrence 205fbb76d57SJoe Lawrence __load_mod "$mod" "$@" 206a2818ee4SJoe Lawrence 207a2818ee4SJoe Lawrence # Wait for livepatch in sysfs ... 208637c7309SMichael Vetter loop_until '[[ -e "$SYSFS_KLP_DIR/$mod" ]]' || 209a2818ee4SJoe Lawrence die "failed to load module $mod (sysfs)" 210a2818ee4SJoe Lawrence} 211a2818ee4SJoe Lawrence 212a2818ee4SJoe Lawrence# load_lp(modname, params) - load a kernel module with a livepatch 213a2818ee4SJoe Lawrence# modname - module name to load 214c4bbe83dSMarcos Paulo de Souza# params - module parameters to pass to insmod 215a2818ee4SJoe Lawrencefunction load_lp() { 216a2818ee4SJoe Lawrence local mod="$1"; shift 217a2818ee4SJoe Lawrence 218fbb76d57SJoe Lawrence load_lp_nowait "$mod" "$@" 219a2818ee4SJoe Lawrence 220a2818ee4SJoe Lawrence # Wait until the transition finishes ... 221637c7309SMichael Vetter loop_until 'grep -q '^0$' $SYSFS_KLP_DIR/$mod/transition' || 222a2818ee4SJoe Lawrence die "failed to complete transition" 223a2818ee4SJoe Lawrence} 224a2818ee4SJoe Lawrence 225a2818ee4SJoe Lawrence# load_failing_mod(modname, params) - load a kernel module, expect to fail 226a2818ee4SJoe Lawrence# modname - module name to load 227c4bbe83dSMarcos Paulo de Souza# params - module parameters to pass to insmod 228a2818ee4SJoe Lawrencefunction load_failing_mod() { 229a2818ee4SJoe Lawrence local mod="$1"; shift 230a2818ee4SJoe Lawrence 231c4bbe83dSMarcos Paulo de Souza local msg="% insmod test_modules/$mod.ko $*" 232a2818ee4SJoe Lawrence log "${msg%% }" 233c4bbe83dSMarcos Paulo de Souza ret=$(insmod "test_modules/$mod.ko" "$@" 2>&1) 234a2818ee4SJoe Lawrence if [[ "$ret" == "" ]]; then 235a2818ee4SJoe Lawrence die "$mod unexpectedly loaded" 236a2818ee4SJoe Lawrence fi 237a2818ee4SJoe Lawrence log "$ret" 238a2818ee4SJoe Lawrence} 239a2818ee4SJoe Lawrence 240a2818ee4SJoe Lawrence# unload_mod(modname) - unload a kernel module 241a2818ee4SJoe Lawrence# modname - module name to unload 242a2818ee4SJoe Lawrencefunction unload_mod() { 243a2818ee4SJoe Lawrence local mod="$1" 244a2818ee4SJoe Lawrence 245a2818ee4SJoe Lawrence # Wait for module reference count to clear ... 246a2818ee4SJoe Lawrence loop_until '[[ $(cat "/sys/module/$mod/refcnt") == "0" ]]' || 247a2818ee4SJoe Lawrence die "failed to unload module $mod (refcnt)" 248a2818ee4SJoe Lawrence 249a2818ee4SJoe Lawrence log "% rmmod $mod" 250a2818ee4SJoe Lawrence ret=$(rmmod "$mod" 2>&1) 251a2818ee4SJoe Lawrence if [[ "$ret" != "" ]]; then 252a2818ee4SJoe Lawrence die "$ret" 253a2818ee4SJoe Lawrence fi 254a2818ee4SJoe Lawrence 255a2818ee4SJoe Lawrence # Wait for module in sysfs ... 256a2818ee4SJoe Lawrence loop_until '[[ ! -e "/sys/module/$mod" ]]' || 257a2818ee4SJoe Lawrence die "failed to unload module $mod (/sys/module)" 258a2818ee4SJoe Lawrence} 259a2818ee4SJoe Lawrence 260a2818ee4SJoe Lawrence# unload_lp(modname) - unload a kernel module with a livepatch 261a2818ee4SJoe Lawrence# modname - module name to unload 262a2818ee4SJoe Lawrencefunction unload_lp() { 263a2818ee4SJoe Lawrence unload_mod "$1" 264a2818ee4SJoe Lawrence} 265a2818ee4SJoe Lawrence 266a2818ee4SJoe Lawrence# disable_lp(modname) - disable a livepatch 267a2818ee4SJoe Lawrence# modname - module name to unload 268a2818ee4SJoe Lawrencefunction disable_lp() { 269a2818ee4SJoe Lawrence local mod="$1" 270a2818ee4SJoe Lawrence 271637c7309SMichael Vetter log "% echo 0 > $SYSFS_KLP_DIR/$mod/enabled" 272637c7309SMichael Vetter echo 0 > "$SYSFS_KLP_DIR/$mod/enabled" 273a2818ee4SJoe Lawrence 274a2818ee4SJoe Lawrence # Wait until the transition finishes and the livepatch gets 275a2818ee4SJoe Lawrence # removed from sysfs... 276637c7309SMichael Vetter loop_until '[[ ! -e "$SYSFS_KLP_DIR/$mod" ]]' || 277a2818ee4SJoe Lawrence die "failed to disable livepatch $mod" 278a2818ee4SJoe Lawrence} 279a2818ee4SJoe Lawrence 280a2818ee4SJoe Lawrence# set_pre_patch_ret(modname, pre_patch_ret) 281a2818ee4SJoe Lawrence# modname - module name to set 282a2818ee4SJoe Lawrence# pre_patch_ret - new pre_patch_ret value 283a2818ee4SJoe Lawrencefunction set_pre_patch_ret { 284a2818ee4SJoe Lawrence local mod="$1"; shift 285a2818ee4SJoe Lawrence local ret="$1" 286a2818ee4SJoe Lawrence 287a2818ee4SJoe Lawrence log "% echo $ret > /sys/module/$mod/parameters/pre_patch_ret" 288a2818ee4SJoe Lawrence echo "$ret" > /sys/module/"$mod"/parameters/pre_patch_ret 289a2818ee4SJoe Lawrence 290a2818ee4SJoe Lawrence # Wait for sysfs value to hold ... 291a2818ee4SJoe Lawrence loop_until '[[ $(cat "/sys/module/$mod/parameters/pre_patch_ret") == "$ret" ]]' || 292a2818ee4SJoe Lawrence die "failed to set pre_patch_ret parameter for $mod module" 293a2818ee4SJoe Lawrence} 294a2818ee4SJoe Lawrence 2952eeb0d45SJoe Lawrencefunction start_test { 2962eeb0d45SJoe Lawrence local test="$1" 2972eeb0d45SJoe Lawrence 298f1fea725SJoe Lawrence # Dump something unique into the dmesg log, then stash the entry 299f1fea725SJoe Lawrence # in LAST_DMESG. The check_result() function will use it to 300f1fea725SJoe Lawrence # find new kernel messages since the test started. 301f1fea725SJoe Lawrence local last_dmesg_msg="livepatch kselftest timestamp: $(date --rfc-3339=ns)" 302f1fea725SJoe Lawrence log "$last_dmesg_msg" 303f1fea725SJoe Lawrence loop_until 'dmesg | grep -q "$last_dmesg_msg"' || 304f1fea725SJoe Lawrence die "buffer busy? can't find canary dmesg message: $last_dmesg_msg" 305f1fea725SJoe Lawrence LAST_DMESG=$(dmesg | grep "$last_dmesg_msg") 306f1fea725SJoe Lawrence 3072eeb0d45SJoe Lawrence echo -n "TEST: $test ... " 3083fd9bd8bSJoe Lawrence log "===== TEST: $test =====" 3092eeb0d45SJoe Lawrence} 3102eeb0d45SJoe Lawrence 311a2818ee4SJoe Lawrence# check_result() - verify dmesg output 312a2818ee4SJoe Lawrence# TODO - better filter, out of order msgs, etc? 313a2818ee4SJoe Lawrencefunction check_result { 314a2818ee4SJoe Lawrence local expect="$*" 315a2818ee4SJoe Lawrence local result 316a2818ee4SJoe Lawrence 317f1fea725SJoe Lawrence # Test results include any new dmesg entry since LAST_DMESG, then: 318f1fea725SJoe Lawrence # - include lines matching keywords 319f1fea725SJoe Lawrence # - exclude lines matching keywords 320f1fea725SJoe Lawrence # - filter out dmesg timestamp prefixes 321f1fea725SJoe Lawrence result=$(dmesg | awk -v last_dmesg="$LAST_DMESG" 'p; $0 == last_dmesg { p=1 }' | \ 322c401088fSJoe Lawrence grep -e 'livepatch:' -e 'test_klp' | \ 323c401088fSJoe Lawrence grep -v '\(tainting\|taints\) kernel' | \ 3242eeb0d45SJoe Lawrence sed 's/^\[[ 0-9.]*\] //' | \ 325a2818ee4SJoe Lawrence sed 's/^\[[ ]*[CT][0-9]*\] //') 326a2818ee4SJoe Lawrence 327a2818ee4SJoe Lawrence if [[ "$expect" == "$result" ]] ; then 328f1fea725SJoe Lawrence echo "ok" 329f1fea725SJoe Lawrence elif [[ "$result" == "" ]] ; then 330f1fea725SJoe Lawrence echo -e "not ok\n\nbuffer overrun? can't find canary dmesg entry: $LAST_DMESG\n" 331a2818ee4SJoe Lawrence die "livepatch kselftest(s) failed" 332a2818ee4SJoe Lawrence else 333a2818ee4SJoe Lawrence echo -e "not ok\n\n$(diff -upr --label expected --label result <(echo "$expect") <(echo "$result"))\n" 334a2818ee4SJoe Lawrence die "livepatch kselftest(s) failed" 335a2818ee4SJoe Lawrence fi 336ff1b80ecSSong Liu} 337ff1b80ecSSong Liu 338ff1b80ecSSong Liu# check_sysfs_rights(modname, rel_path, expected_rights) - check sysfs 339ff1b80ecSSong Liu# path permissions 340ff1b80ecSSong Liu# modname - livepatch module creating the sysfs interface 341ff1b80ecSSong Liu# rel_path - relative path of the sysfs interface 342ff1b80ecSSong Liu# expected_rights - expected access rights 343ff1b80ecSSong Liufunction check_sysfs_rights() { 344ff1b80ecSSong Liu local mod="$1"; shift 345ff1b80ecSSong Liu local rel_path="$1"; shift 346ff1b80ecSSong Liu local expected_rights="$1"; shift 347637c7309SMichael Vetter 348ff1b80ecSSong Liu local path="$SYSFS_KLP_DIR/$mod/$rel_path" 349ff1b80ecSSong Liu local rights=$(/bin/stat --format '%A' "$path") 350ff1b80ecSSong Liu if test "$rights" != "$expected_rights" ; then 351ff1b80ecSSong Liu die "Unexpected access rights of $path: $expected_rights vs. $rights" 352ff1b80ecSSong Liu fi 353ff1b80ecSSong Liu} 354ff1b80ecSSong Liu 355ff1b80ecSSong Liu# check_sysfs_value(modname, rel_path, expected_value) - check sysfs value 356ff1b80ecSSong Liu# modname - livepatch module creating the sysfs interface 357ff1b80ecSSong Liu# rel_path - relative path of the sysfs interface 358ff1b80ecSSong Liu# expected_value - expected value read from the file 359ff1b80ecSSong Liufunction check_sysfs_value() { 360ff1b80ecSSong Liu local mod="$1"; shift 361ff1b80ecSSong Liu local rel_path="$1"; shift 362ff1b80ecSSong Liu local expected_value="$1"; shift 363637c7309SMichael Vetter 364ff1b80ecSSong Liu local path="$SYSFS_KLP_DIR/$mod/$rel_path" 365ff1b80ecSSong Liu local value=`cat $path` 366ff1b80ecSSong Liu if test "$value" != "$expected_value" ; then 367ff1b80ecSSong Liu die "Unexpected value in $path: $expected_value vs. $value" 368ff1b80ecSSong Liu fi 369*2ca7cd80SFilipe Xavier} 370*2ca7cd80SFilipe Xavier 371*2ca7cd80SFilipe Xavier# cleanup_tracing() - stop and clean up function tracing 372*2ca7cd80SFilipe Xavierfunction cleanup_tracing() { 373*2ca7cd80SFilipe Xavier echo 0 > "$SYSFS_TRACING_DIR/tracing_on" 374*2ca7cd80SFilipe Xavier echo "" > "$SYSFS_TRACING_DIR/set_ftrace_filter" 375*2ca7cd80SFilipe Xavier echo "nop" > "$SYSFS_TRACING_DIR/current_tracer" 376*2ca7cd80SFilipe Xavier echo "" > "$SYSFS_TRACING_DIR/trace" 377*2ca7cd80SFilipe Xavier} 378*2ca7cd80SFilipe Xavier 379*2ca7cd80SFilipe Xavier# trace_function(function) - start tracing of a function 380*2ca7cd80SFilipe Xavier# function - to be traced function 381*2ca7cd80SFilipe Xavierfunction trace_function() { 382*2ca7cd80SFilipe Xavier local function="$1"; shift 383*2ca7cd80SFilipe Xavier 384*2ca7cd80SFilipe Xavier cleanup_tracing 385*2ca7cd80SFilipe Xavier 386*2ca7cd80SFilipe Xavier echo "function" > "$SYSFS_TRACING_DIR/current_tracer" 387*2ca7cd80SFilipe Xavier echo "$function" > "$SYSFS_TRACING_DIR/set_ftrace_filter" 388*2ca7cd80SFilipe Xavier echo 1 > "$SYSFS_TRACING_DIR/tracing_on" 389*2ca7cd80SFilipe Xavier} 390*2ca7cd80SFilipe Xavier 391*2ca7cd80SFilipe Xavier# check_traced_functions(functions...) - check whether each function appeared in the trace log 392*2ca7cd80SFilipe Xavier# functions - list of functions to be checked 393*2ca7cd80SFilipe Xavierfunction check_traced_functions() { 394*2ca7cd80SFilipe Xavier local function 395*2ca7cd80SFilipe Xavier 396*2ca7cd80SFilipe Xavier for function in "$@"; do 397*2ca7cd80SFilipe Xavier if ! grep -Fwq "$function" "$SYSFS_TRACING_DIR/trace" ; then 398*2ca7cd80SFilipe Xavier die "Function ($function) did not appear in the trace" 399*2ca7cd80SFilipe Xavier fi 400*2ca7cd80SFilipe Xavier done 401*2ca7cd80SFilipe Xavier 402*2ca7cd80SFilipe Xavier cleanup_tracing 403} 404