Currently we have to read multiple files from initramfs image in
kdumpctl, and we are calling lsinitrd for each file individually, and
the initramfs image will get decompressed for each lsinitrd call which
is a waste of time.
This patch will let kdumpctl extract all required files with a single
lsinitrd call, so the image will only get decompressed for once.
This commit relies on following dracut commits:
commit 986b12d391b8de6c820da1af9bfdb4153c340370
Author: Kairui Song <kasong(a)redhat.com>
lsinitrd: optimize performance when handling multiple files
commit f81c864eede2a11bfeb849cb2a2634be034ed7fb
Author: Kairui Song <kasong(a)redhat.com>
lsinitrd: allow to only unpack certain files
Performance compare:
Before:
real 0m1.657s
user 0m1.401s
sys 0m0.223s
After:
real 0m1.440s
user 0m1.087s
sys 0m0.330s
---
kdumpctl | 38 ++++++++++++++++++++++++++++++++++----
1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/kdumpctl b/kdumpctl
index 6a01c13..c6b52fb 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -17,6 +17,13 @@ TARGET_INITRD=""
FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered"
#kdump shall be the default dump mode
DEFAULT_DUMP_MODE="kdump"
+INITRD_PREFETCH_FILES="\
+etc/cmdline.d/00-watchdog.conf \
+usr/lib/dracut/build-parameter.txt \
+usr/lib/dracut/loaded-kernel-modules.txt \
+$DRACUT_MODULES_FILE \
+"
+INITRD_TMP_PATH=""
image_time=0
[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
@@ -32,6 +39,22 @@ if [ -f /etc/sysconfig/kdump ]; then
. /etc/sysconfig/kdump
fi
+# Wrapper for lsinitrd
+# possible required files in initramfs will be extarcted to a temp directory all at once
+# when this script just started, because batch extract is faster
+# Will try to read from the temp dir first, fall back to read the image if not found
+_lsinitrd()
+{
+ local file=${1##\/}
+ if [[ -e $INITRD_TMP_PATH/$file ]]; then
+ cat $INITRD_TMP_PATH/$file
+ return 0
+ else
+ lsinitrd $TARGET_INITRD -f $file
+ return 1
+ fi
+}
+
single_instance_lock()
{
local rc timeout=5
@@ -287,6 +310,13 @@ setup_initrd()
else
TARGET_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
fi
+
+ INITRD_TMP_PATH="$(mktemp -t -d --suffix=.d kdumpctl.XXXXXX)"
+ [[ $? -ne 0 ]] && echo "Error: Failed to create temp dir to extract
initramfs!" >&2 && exit 1
+ [[ -n "$INITRD_TMP_PATH" ]] && trap "rm -rf
'$INITRD_TMP_PATH'" EXIT
+ pushd $INITRD_TMP_PATH &> /dev/null
+ lsinitrd --unpack $TARGET_INITRD $INITRD_PREFETCH_FILES &> /dev/null
+ popd &> /dev/null
}
check_files_modified()
@@ -378,7 +408,7 @@ check_dump_fs_modified()
_new_mntpoint="/kdumproot/$(get_mntpoint_from_target $_target)"
fi
- _dracut_args=$(lsinitrd $TARGET_INITRD -f usr/lib/dracut/build-parameter.txt)
+ _dracut_args=$(_lsinitrd usr/lib/dracut/build-parameter.txt)
if [[ -z "$_dracut_args" ]];then
echo "Warning: No dracut arguments found in initrd"
return 0
@@ -451,7 +481,7 @@ check_wdt_modified()
# ensure that watchdog module is loaded as early as possible
_alldrivers="${!_drivers[*]}"
[[ $_alldrivers ]] && wd_new="rd.driver.pre=${_alldrivers// /,}"
- wd_old=$(lsinitrd $TARGET_INITRD -f etc/cmdline.d/00-watchdog.conf)
+ wd_old=$(_lsinitrd etc/cmdline.d/00-watchdog.conf)
[[ "$wd_old" = "$wd_new" ]] && return 0
@@ -461,7 +491,7 @@ check_wdt_modified()
check_kmodules_modified()
{
# always sort again to avoid LANG/LC inconsistent problem
- local _old_modules="$(lsinitrd $TARGET_INITRD -f
/usr/lib/dracut/loaded-kernel-modules.txt | sort)"
+ local _old_modules="$(_lsinitrd /usr/lib/dracut/loaded-kernel-modules.txt |
sort)"
local _new_modules="$(get_loaded_kernel_modules | sort)"
[[ -z $_old_modules ]] && echo "Warning: Previous loaded kernel module list
is absent or empty"
@@ -580,7 +610,7 @@ check_rebuild()
#in case of fadump mode, check whether the default/target
#initrd is already built with dump capture capability
if [ "$DEFAULT_DUMP_MODE" == "fadump" ]; then
- capture_capable_initrd=$(lsinitrd -f $DRACUT_MODULES_FILE $TARGET_INITRD | grep
^kdumpbase$ | wc -l)
+ capture_capable_initrd=$(_lsinitrd $DRACUT_MODULES_FILE | grep ^kdumpbase$ | wc -l)
fi
fi
--
2.17.1
Show replies by date