Currently kdump service takes a few seconds to start even no need
to rebuild initramfs, the main reason is due to the slow lsinitrd.
This patch introduces kdump's own lsinitrd support, it generates a
tmp file that contains all the information needed by kdump into the
initramfs when rebuild, after that we use "lsinitrd -f" to retrieve
the file to a tmp file if it does not exist(e.g. the tmp file will
get lost every reboot if /tmp is mounted with tmpfs), and access it
instead for all the following lsinitrd operations.
We add two kdump_lsinitrd_add() and kdump_lsinitrd_get() functions,
kdump_lsinitrd_add() is called to generate lsinitrd information to
the tmp file, and then inserted to initramfs via dracut "--install".
kdump_lsinitrd_get() is called to retrieve the lsinitrd information
used by kdump, it will call "lsinitrd -f" to extract the tmp file
when necessary.
After this patch, the average time of kdump service start in case of
no initrd rebuild(tested on Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz):
$ time kdumpctl start (when the lsinitrd tmp file exists)
kexec: loaded kdump kernel
Starting kdump: [OK]
real 0m0.854s
user 0m0.389s
sys 0m0.582s
$ time kdumpctl start (when the lsinitrd tmp file got lost)
kexec: loaded kdump kernel
Starting kdump: [OK]
real 0m1.193s
user 0m0.757s
sys 0m0.620s
Signed-off-by: Xunlei Pang <xlpang(a)redhat.com>
---
dracut-module-setup.sh | 5 +++++
kdump-lib.sh | 26 ++++++++++++++++++++++++++
kdumpctl | 10 +++++++---
mkdumprd | 6 ++++++
4 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index 9f88b4e..9c5bf57 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -753,4 +753,9 @@ install() {
sed -i -e \
's/\(^[[:space:]]*reserved_memory[[:space:]]*=\)[[:space:]]*[[:digit:]]*/\1
1024/' \
${initdir}/etc/lvm/lvm.conf &>/dev/null
+
+ # Add the content of 04watchdog 00-watchdog.conf as kdump lsinird info
+ if [ -f "${initdir}/etc/cmdline.d/00-watchdog.conf" ]; then
+ kdump_lsinitrd_add watchdog "$(cat
${initdir}/etc/cmdline.d/00-watchdog.conf)"
+ fi
}
diff --git a/kdump-lib.sh b/kdump-lib.sh
index 8ebad70..7506c42 100755
--- a/kdump-lib.sh
+++ b/kdump-lib.sh
@@ -406,3 +406,29 @@ get_dracut_args_target()
{
echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut
-d' ' -f1
}
+
+kdump_lsinitrd_add()
+{
+ local str="$1="
+
+ if [ -z "$KDUMP_LSINITRD_FILE" ]; then
+ return
+ fi
+
+ shift
+ str=$str$@
+ echo "$str" >> $KDUMP_LSINITRD_FILE
+}
+
+kdump_lsinitrd_get()
+{
+ if [ -z "$KDUMP_LSINITRD_FILE" ]; then
+ return
+ fi
+
+ if ! [ -f "$KDUMP_LSINITRD_FILE" ]; then
+ lsinitrd $TARGET_INITRD -f $KDUMP_LSINITRD_FILE > $KDUMP_LSINITRD_FILE
+ fi
+
+ grep "^$1=.*" $KDUMP_LSINITRD_FILE | awk -F "$1=" '{print
$2}'
+}
diff --git a/kdumpctl b/kdumpctl
index b9d5fe6..4e86deb 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -450,6 +450,10 @@ setup_initrd()
else
TARGET_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img"
fi
+
+ # We need different KDUMP_LSINITRD_FILE names to distinguish between
+ # fadump and kdump, or different kernel versions.
+ export KDUMP_LSINITRD_FILE="/tmp/$(basename $TARGET_INITRD).lsinitrd"
}
check_files_modified()
@@ -539,7 +543,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=$(kdump_lsinitrd_get dracut_args)
if [[ -z "$_dracut_args" ]];then
echo "Warning: No dracut arguments found in initrd"
return 0
@@ -549,7 +553,7 @@ check_dump_fs_modified()
# point and file system. If any of them mismatches then rebuild
echo $_dracut_args | grep "\-\-mount" &> /dev/null
if [[ $? -eq 0 ]];then
- set -- $(echo $_dracut_args | awk -F "--mount '" '{print $2}' |
cut -d' ' -f1,2,3)
+ set -- $(echo $_dracut_args | awk -F "--mount " '{print $2}' | cut
-d' ' -f1,2,3)
_old_dev=$1
_old_mntpoint=$2
_old_fstype=$3
@@ -612,7 +616,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=$(kdump_lsinitrd_get watchdog)
[[ "$wd_old" = "$wd_new" ]] && return 0
diff --git a/mkdumprd b/mkdumprd
index 5a25853..5882d9d 100644
--- a/mkdumprd
+++ b/mkdumprd
@@ -503,6 +503,12 @@ then
add_dracut_arg "--add-drivers" "$extra_modules"
fi
+# lsinitrd takes seconds to finish, in order to speed up kdump
+# start time, we generate kdump's own lsinitrd information.
+rm $KDUMP_LSINITRD_FILE -f
+kdump_lsinitrd_add dracut_args "${dracut_args[@]}"
+add_dracut_arg "--install" "$KDUMP_LSINITRD_FILE"
+
dracut "${dracut_args[@]}" "$@"
_rc=$?
sync
--
1.8.3.1