From: Dave Young Date: Fri, 18 Jan 2013 01:59:52 +0000 (+0800) Subject: Add memory usage trace to diffrent hook points X-Git-Tag: 025~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7bd8f23303ab41b270af5142f4547f496a9f4f38;p=thirdparty%2Fdracut.git Add memory usage trace to diffrent hook points Hi, Here is an update of this patch, fixed the local variable issue. --- diff --git a/dracut.cmdline.7.asc b/dracut.cmdline.7.asc index ab0468a44..ea2d30bbc 100644 --- a/dracut.cmdline.7.asc +++ b/dracut.cmdline.7.asc @@ -143,6 +143,10 @@ It should be attached to any report about dracut problems. If systemd is not active, the logs are written to dmesg and _/run/initramfs/init.log_. If "quiet" is set, it also logs to the console. +**rd.memdebug=[0-3]**:: + print memory usage debug info, set the verbose level from 1 to 3 + print nothing when set rd.memdebug=0 + **rd.break**:: drop to a shell at the end diff --git a/modules.d/98systemd/dracut-cmdline.sh b/modules.d/98systemd/dracut-cmdline.sh index a366381a4..bfe2e433c 100755 --- a/modules.d/98systemd/dracut-cmdline.sh +++ b/modules.d/98systemd/dracut-cmdline.sh @@ -18,6 +18,7 @@ type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh source_conf /etc/conf.d +make_trace_mem "hook cmdline" '1+:mem' '1+:iomem' '3+:slab' # run scriptlets to parse the command line getarg 'rd.break=cmdline' -d 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline" source_hook cmdline diff --git a/modules.d/98systemd/dracut-initqueue.sh b/modules.d/98systemd/dracut-initqueue.sh index e9da432b0..c82b6eb24 100755 --- a/modules.d/98systemd/dracut-initqueue.sh +++ b/modules.d/98systemd/dracut-initqueue.sh @@ -10,6 +10,7 @@ type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh source_conf /etc/conf.d +make_trace_mem "hook initqueue" '1:shortmem' '2+:mem' '3+:slab' getarg 'rd.break=initqueue' -d 'rdbreak=initqueue' && emergency_shell -n initqueue "Break before initqueue" RDRETRY=$(getarg rd.retry -d 'rd_retry=') diff --git a/modules.d/98systemd/dracut-pre-pivot.sh b/modules.d/98systemd/dracut-pre-pivot.sh index 1ffa6aaab..2eed4bb8e 100755 --- a/modules.d/98systemd/dracut-pre-pivot.sh +++ b/modules.d/98systemd/dracut-pre-pivot.sh @@ -10,6 +10,7 @@ type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh source_conf /etc/conf.d +make_trace_mem "hook pre-pivot" '1:shortmem' '2+:mem' '3+:slab' # pre pivot scripts are sourced just before we doing cleanup and switch over # to the new root. getarg 'rd.break=pre-pivot' 'rdbreak=pre-pivot' && emergency_shell -n pre-pivot "Break pre-pivot" diff --git a/modules.d/98systemd/dracut-pre-trigger.sh b/modules.d/98systemd/dracut-pre-trigger.sh index 20a3f6470..deaf0f2ed 100755 --- a/modules.d/98systemd/dracut-pre-trigger.sh +++ b/modules.d/98systemd/dracut-pre-trigger.sh @@ -10,6 +10,7 @@ type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh source_conf /etc/conf.d +make_trace_mem "hook pre-trigger" "1:shortmem" "2+:mem" "3+:slab" getargbool 0 rd.udev.info -n -y rdudevinfo && udevadm control --log-priority=info getargbool 0 rd.udev.debug -n -y rdudevdebug && udevadm control --log-priority=debug udevproperty "hookdir=$hookdir" diff --git a/modules.d/98systemd/dracut-pre-udev.sh b/modules.d/98systemd/dracut-pre-udev.sh index 9a4dc61e9..d20e6137c 100755 --- a/modules.d/98systemd/dracut-pre-udev.sh +++ b/modules.d/98systemd/dracut-pre-udev.sh @@ -9,6 +9,7 @@ type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh source_conf /etc/conf.d +make_trace_mem "hook pre-udev" '1:shortmem' '2+:mem' '3+:slab' # pre pivot scripts are sourced just before we doing cleanup and switch over # to the new root. getarg 'rd.break=pre-udev' 'rdbreak=pre-udev' && emergency_shell -n pre-udev "Break pre-udev" diff --git a/modules.d/99base/dracut-lib.sh b/modules.d/99base/dracut-lib.sh index da37ac4ad..94ff33f85 100755 --- a/modules.d/99base/dracut-lib.sh +++ b/modules.d/99base/dracut-lib.sh @@ -1013,3 +1013,98 @@ listlist() { are_lists_eq() { listlist "$1" "$2" "$3" "$4" && listlist "$1" "$3" "$2" "$4" } + +setmemdebug() { + if [ -z "$DEBUG_MEM_LEVEL" ]; then + export DEBUG_MEM_LEVEL=$(getargnum 0 0 3 rd.memdebug) + fi +} + +setmemdebug + +# parameters: msg [trace_level:trace]... +make_trace_mem() +{ + local msg + msg="$1" + shift + if [ -n "$DEBUG_MEM_LEVEL" ] && [ "$DEBUG_MEM_LEVEL" -gt 0 ]; then + make_trace show_memstats $DEBUG_MEM_LEVEL "[debug_mem]" "$msg" "$@" + fi +} + +# parameters: func log_level prefix msg [trace_level:trace]... +make_trace() +{ + local func log_level prefix msg msg_printed + local trace trace_level trace_in_higher_levels insert_trace + + func=$1 + shift + + log_level=$1 + shift + + prefix=$1 + shift + + msg=$1 + shift + + if [ -z "$log_level" ]; then + return + fi + + msg=$(echo $msg) + + msg_printed=0 + while [ $# -gt 0 ]; do + trace=${1%%:*} + trace_level=${trace%%+} + [ "$trace" != "$trace_level" ] && trace_in_higher_levels="yes" + trace=${1##*:} + + if [ -z "$trace_level" ]; then + trace_level=0 + fi + + insert_trace=0 + if [ -n "$trace_in_higher_levels" ]; then + if [ "$log_level" -ge "$trace_level" ]; then + insert_trace=1 + fi + else + if [ "$log_level" -eq "$trace_level" ]; then + insert_trace=1 + fi + fi + + if [ $insert_trace -eq 1 ]; then + if [ $msg_printed -eq 0 ]; then + echo "$prefix $msg" + msg_printed=1 + fi + $func $trace + fi + shift + done +} + +# parameters: type +show_memstats() +{ + case $1 in + shortmem) + cat /proc/meminfo | grep -e "^MemFree" -e "^Cached" -e "^Slab" + ;; + mem) + cat /proc/meminfo + ;; + slab) + cat /proc/slabinfo + ;; + iomem) + cat /proc/iomem + ;; + esac +}