Commit f1fea725 authored by Joe Lawrence's avatar Joe Lawrence Committed by Shuah Khan

selftests/livepatch: fix and refactor new dmesg message code

The livepatching kselftests rely on comparing expected vs. observed
dmesg output.  After each test, new dmesg entries are determined by the
'comm' utility comparing a saved, pre-test copy of dmesg to post-test
dmesg output.

Alexander reports that the 'comm --nocheck-order -13' invocation used by
the tests can be confused when dmesg entry timestamps vary in magnitude
(ie, "[   98.820331]" vs. "[  100.031067]"), in which case, additional
messages are reported as new.  The unexpected entries then spoil the
test results.

Instead of relying on 'comm' or 'diff' to determine new testing dmesg
entries, refactor the code:

  - pre-test  : log a unique canary dmesg entry
  - test      : run tests, log messages
  - post-test : filter dmesg starting from pre-test message
Reported-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Closes: https://lore.kernel.org/live-patching/ZYAimyPYhxVA9wKg@li-008a6a4c-3549-11b2-a85c-c5cc2836eea2.ibm.com/Signed-off-by: default avatarJoe Lawrence <joe.lawrence@redhat.com>
Acked-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Tested-by: default avatarMarcos Paulo de Souza <mpdesouza@suse.com>
Reviewed-by: default avatarMarcos Paulo de Souza <mpdesouza@suse.com>
Acked-by: default avatarMiroslav Benes <mbenes@suse.cz>
Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
parent d53271c0
...@@ -42,17 +42,6 @@ function die() { ...@@ -42,17 +42,6 @@ function die() {
exit 1 exit 1
} }
# save existing dmesg so we can detect new content
function save_dmesg() {
SAVED_DMESG=$(mktemp --tmpdir -t klp-dmesg-XXXXXX)
dmesg > "$SAVED_DMESG"
}
# cleanup temporary dmesg file from save_dmesg()
function cleanup_dmesg_file() {
rm -f "$SAVED_DMESG"
}
function push_config() { function push_config() {
DYNAMIC_DEBUG=$(grep '^kernel/livepatch' /sys/kernel/debug/dynamic_debug/control | \ DYNAMIC_DEBUG=$(grep '^kernel/livepatch' /sys/kernel/debug/dynamic_debug/control | \
awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}') awk -F'[: ]' '{print "file " $1 " line " $2 " " $4}')
...@@ -99,7 +88,6 @@ function set_ftrace_enabled() { ...@@ -99,7 +88,6 @@ function set_ftrace_enabled() {
function cleanup() { function cleanup() {
pop_config pop_config
cleanup_dmesg_file
} }
# setup_config - save the current config and set a script exit trap that # setup_config - save the current config and set a script exit trap that
...@@ -280,7 +268,15 @@ function set_pre_patch_ret { ...@@ -280,7 +268,15 @@ function set_pre_patch_ret {
function start_test { function start_test {
local test="$1" local test="$1"
save_dmesg # Dump something unique into the dmesg log, then stash the entry
# in LAST_DMESG. The check_result() function will use it to
# find new kernel messages since the test started.
local last_dmesg_msg="livepatch kselftest timestamp: $(date --rfc-3339=ns)"
log "$last_dmesg_msg"
loop_until 'dmesg | grep -q "$last_dmesg_msg"' ||
die "buffer busy? can't find canary dmesg message: $last_dmesg_msg"
LAST_DMESG=$(dmesg | grep "$last_dmesg_msg")
echo -n "TEST: $test ... " echo -n "TEST: $test ... "
log "===== TEST: $test =====" log "===== TEST: $test ====="
} }
...@@ -291,23 +287,24 @@ function check_result { ...@@ -291,23 +287,24 @@ function check_result {
local expect="$*" local expect="$*"
local result local result
# Note: when comparing dmesg output, the kernel log timestamps # Test results include any new dmesg entry since LAST_DMESG, then:
# help differentiate repeated testing runs. Remove them with a # - include lines matching keywords
# post-comparison sed filter. # - exclude lines matching keywords
# - filter out dmesg timestamp prefixes
result=$(dmesg | comm --nocheck-order -13 "$SAVED_DMESG" - | \ result=$(dmesg | awk -v last_dmesg="$LAST_DMESG" 'p; $0 == last_dmesg { p=1 }' | \
grep -e 'livepatch:' -e 'test_klp' | \ grep -e 'livepatch:' -e 'test_klp' | \
grep -v '\(tainting\|taints\) kernel' | \ grep -v '\(tainting\|taints\) kernel' | \
sed 's/^\[[ 0-9.]*\] //') sed 's/^\[[ 0-9.]*\] //')
if [[ "$expect" == "$result" ]] ; then if [[ "$expect" == "$result" ]] ; then
echo "ok" echo "ok"
elif [[ "$result" == "" ]] ; then
echo -e "not ok\n\nbuffer overrun? can't find canary dmesg entry: $LAST_DMESG\n"
die "livepatch kselftest(s) failed"
else else
echo -e "not ok\n\n$(diff -upr --label expected --label result <(echo "$expect") <(echo "$result"))\n" echo -e "not ok\n\n$(diff -upr --label expected --label result <(echo "$expect") <(echo "$result"))\n"
die "livepatch kselftest(s) failed" die "livepatch kselftest(s) failed"
fi fi
cleanup_dmesg_file
} }
# check_sysfs_rights(modname, rel_path, expected_rights) - check sysfs # check_sysfs_rights(modname, rel_path, expected_rights) - check sysfs
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment