common/rc: report kmemleak errors
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 24 Jan 2018 23:53:23 +0000 (15:53 -0800)
committerEryu Guan <eguan@redhat.com>
Thu, 25 Jan 2018 07:51:58 +0000 (15:51 +0800)
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>
check
common/rc

diff --git a/check b/check
index 2bdad3995b3d589c33d0e0a8a3af63fb6b61b8d6..58a2f5cca8b0b8dba1f0d51d993c024ca7850d97 100755 (executable)
--- a/check
+++ b/check
@@ -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
index 77a4eb4338fc263af8175cd0ae1bf522e205c069..2e3a83aefd6325658d629866bd624aad6a722648 100644 (file)
--- a/common/rc
+++ b/common/rc
@@ -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()
 {