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 kdump lsinitrd tmp file exists)
kexec: loaded kdump kernel
Starting kdump: [OK]
real 0m0.854s
user 0m0.389s
sys 0m0.582s
$ time kdumpctl start (when kdump 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>
---
v1->v2:
-Merged Patch3 into this one.
-No functional change.
dracut-module-setup.sh | 5 +++++
kdump-lib.sh | 26 ++++++++++++++++++++++++++
kdumpctl | 10 +++++++---
mkdumprd | 7 +++++++
4 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index 9f88b4e..ef4ec06 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -740,6 +740,11 @@ install() {
# Also redirect dracut-emergency to kdump error handler
ln_r "$systemdsystemunitdir/emergency.service"
"$systemdsystemunitdir/dracut-emergency.service"
+ # 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
+
# Check for all the devices and if any device is iscsi, bring up iscsi
# target. Ideally all this should be pushed into dracut iscsi module
# at some point of time.
diff --git a/kdump-lib.sh b/kdump-lib.sh
index 8ebad70..c4d31a9 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 2>
/dev/null
+ fi
+
+ grep "^$1=.*" $KDUMP_LSINITRD_FILE | awk -F "$1=" '{print
$2}'
+}
diff --git a/kdumpctl b/kdumpctl
index b064c52..11d7f1f 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 | grep "^Arguments:" | head -1)
+ _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
@@ -578,7 +582,7 @@ check_wdt_modified()
[[ -f "$dir/state" ]] || continue
if [ -z "$lsinitrd_done" ]; then
- old_mods=$(lsinitrd $TARGET_INITRD -f etc/cmdline.d/00-watchdog.conf)
+ old_mods=$(kdump_lsinitrd_get watchdog)
lsinitrd_done=1
fi
diff --git a/mkdumprd b/mkdumprd
index 5a25853..ab3b6e4 100644
--- a/mkdumprd
+++ b/mkdumprd
@@ -503,6 +503,13 @@ then
add_dracut_arg "--add-drivers" "$extra_modules"
fi
+# lsinitrd takes seconds to finish, in order to speed up kdump
+# start process, we generate kdump's own lsinitrd information
+# and store it into initramfs to be used by future starts.
+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