diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2018-01-24 15:53:23 -0800 |
---|---|---|
committer | Eryu Guan <eguan@redhat.com> | 2018-01-25 15:51:58 +0800 |
commit | 074740a32c6a36c5ba7d4be66dd4ee63e9f744f3 (patch) | |
tree | 123adb648745d02514d202300d52bfbd29991984 | |
parent | f2afd6331d2f0c3014072390d1a440abdd0a7103 (diff) | |
download | xfstests-074740a32c6a36c5ba7d4be66dd4ee63e9f744f3.tar.gz |
common/rc: report kmemleak errors
If kmemleak is enabled, scan and report memory leaks after every
test.
Note that the kmemleak check support is EXPERIMENTAL! Due to the way
kmemleak works, the leak might be from an earlier test, or something
totally unrelated.
[eguan: add EXPERIMENTAL disclaimer in commit log too]
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eryu Guan <eguan@redhat.com>
Signed-off-by: Eryu Guan <eguan@redhat.com>
-rwxr-xr-x | check | 2 | ||||
-rw-r--r-- | common/rc | 60 |
2 files changed, 62 insertions, 0 deletions
@@ -499,6 +499,7 @@ _expunge_test() return 0 } +_init_kmemleak _prepare_test_list if $OPTIONS_HAVE_SECTIONS; then @@ -791,6 +792,7 @@ for section in $HOST_OPTIONS_SECTIONS; do n_try=`expr $n_try + 1` _check_filesystems _check_dmesg || err=true + _check_kmemleak || err=true fi fi @@ -3438,6 +3438,66 @@ _check_dmesg() fi } +# capture the kmemleak report +_capture_kmemleak() +{ + local _kern_knob="${DEBUGFS_MNT}/kmemleak" + local _leak_file="$1" + + # Tell the kernel to scan for memory leaks. Apparently the write + # returns before the scan is complete, so do it twice in the hopes + # that twice is enough to capture all the leaks. + echo "scan" > "${_kern_knob}" + cat "${_kern_knob}" > /dev/null + echo "scan" > "${_kern_knob}" + cat "${_kern_knob}" > "${_leak_file}.tmp" + if [ -s "${_leak_file}.tmp" ]; then + cat > "${_leak_file}" << ENDL +EXPERIMENTAL kmemleak reported some memory leaks! Due to the way kmemleak +works, the leak might be from an earlier test, or something totally unrelated. +ENDL + cat "${_leak_file}.tmp" >> "${_leak_file}" + rm -rf "${_leak_file}.tmp" + fi + echo "clear" > "${_kern_knob}" +} + +# set up kmemleak +_init_kmemleak() +{ + local _kern_knob="${DEBUGFS_MNT}/kmemleak" + + if [ ! -w "${_kern_knob}" ]; then + return 0 + fi + + # Disable the automatic scan so that we can control it completely, + # then dump all the leaks recorded so far. + echo "scan=off" > "${_kern_knob}" + _capture_kmemleak /dev/null +} + +# check kmemleak log +_check_kmemleak() +{ + local _kern_knob="${DEBUGFS_MNT}/kmemleak" + local _leak_file="${seqres}.kmemleak" + + if [ ! -w "${_kern_knob}" ]; then + return 0 + fi + + # Capture and report any leaks + _capture_kmemleak "${_leak_file}" + if [ -s "${_leak_file}" ]; then + _dump_err "_check_kmemleak: something found in kmemleak (see ${_leak_file})" + return 1 + else + rm -f "${_leak_file}" + return 0 + fi +} + # don't check dmesg log after test _disable_dmesg_check() { |