If lvm2 thinp is enabled in kdump, a lvm2 thin pool monitor service
is needed for monitoring and autoextend the size of thin pool when
it reached the threshold.
Usually the monitor service is achieved by enabling lvm2-monitor.service
for systemd, which will start the monitoring with dmeventd. When threshold
reaches, dmeventd will perform the autoextension for thin pool.
However dmeventd is not designed for running in ramdisk environment as
kdump does, for it will mlockall() the whole executable with all libraries
and the memory allocations pinned in RAM, which will consume lot of
memory and unsuitable for kdump use. For example we can notice OOM kill
of dmeventd on rhel8 with crashkernel value 1G-4G:160M when autoextension
starts.
In this patch, we will use a shell script to achieve the same. It
runs in parallel background with vmcore collector and sync, and it calls
lvextend looply. If threshold reaches, autoextend it, if not, just exit.
After kdump finishes, the script will be terminated by TERM signal.
Comparing to lvm2-monitor.service/dmeventd version, this version will
extend thin pool at a fixed time interval(5s for now), it may take a
longer kdump time but without the memory shortage risk of mlockall().
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
dracut-kdump.sh | 9 ++++++++
dracut-module-setup.sh | 5 +++++
dracut-monitor_lvm2_thinp_autoextend | 33 ++++++++++++++++++++++++++++
kexec-tools.spec | 2 ++
4 files changed, 49 insertions(+)
create mode 100644 dracut-monitor_lvm2_thinp_autoextend
diff --git a/dracut-kdump.sh b/dracut-kdump.sh
index 4852c01..7ec7ebd 100755
--- a/dracut-kdump.sh
+++ b/dracut-kdump.sh
@@ -164,6 +164,12 @@ dump_fs()
mkdir -p "$_dump_fs_path" || return 1
+ _target=$(get_target_from_path "$_dump_fs_path")
+ if is_lvm2_thinp_device "$_target"; then
+ /kdumpscripts/monitor_lvm2_thinp_autoextend "$_target"
"$CORE_COLLECTOR" "${DMESG_COLLECTOR}" "cp" &
+ _mon_pid=$!
+ fi
+
save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_dump_fs_path"
save_opalcore_fs "$_dump_fs_path"
@@ -178,12 +184,15 @@ dump_fs()
_sync_exitcode=$?
if [ $_sync_exitcode -eq 0 ]; then
mv "$_dump_fs_path/vmcore-incomplete" "$_dump_fs_path/vmcore"
+ [ -n "$_mon_pid" ] && kill $_mon_pid
dinfo "saving vmcore complete"
else
+ [ -n "$_mon_pid" ] && kill $_mon_pid
derror "sync vmcore failed, exitcode:$_sync_exitcode"
return 1
fi
else
+ [ -n "$_mon_pid" ] && kill $_mon_pid
derror "saving vmcore failed, exitcode:$_dump_exitcode"
return 1
fi
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index c319fc2..db3d91b 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -1038,7 +1038,9 @@ install() {
fi
dracut_install -o /etc/adjtime /etc/localtime
inst "$moddir/monitor_dd_progress"
"/kdumpscripts/monitor_dd_progress"
+ inst "$moddir/monitor_lvm2_thinp_autoextend"
"/kdumpscripts/monitor_lvm2_thinp_autoextend"
chmod +x "${initdir}/kdumpscripts/monitor_dd_progress"
+ chmod +x "${initdir}/kdumpscripts/monitor_lvm2_thinp_autoextend"
inst "/bin/dd" "/bin/dd"
inst "/bin/tail" "/bin/tail"
inst "/bin/date" "/bin/date"
@@ -1053,6 +1055,9 @@ install() {
inst "/usr/bin/printf" "/sbin/printf"
inst "/usr/bin/logger" "/sbin/logger"
inst "/usr/bin/chmod" "/sbin/chmod"
+ inst "/usr/bin/pidof" "/sbin/pidof"
+ inst "/usr/bin/df" "/sbin/df"
+ inst "/usr/bin/kill" "/sbin/kill"
inst "/lib/kdump/kdump-lib-initramfs.sh"
"/lib/kdump-lib-initramfs.sh"
inst "/lib/kdump/kdump-logger.sh" "/lib/kdump-logger.sh"
inst "$moddir/kdump.sh" "/usr/bin/kdump.sh"
diff --git a/dracut-monitor_lvm2_thinp_autoextend b/dracut-monitor_lvm2_thinp_autoextend
new file mode 100644
index 0000000..5d5c44f
--- /dev/null
+++ b/dracut-monitor_lvm2_thinp_autoextend
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+THIN_LV=$1
+THIN_POOL=$(lvm lvs -S 'lv_layout=sparse && lv_layout=thin' \
+ --nosuffix --noheadings -o vg_name,pool_lv "$THIN_LV" | \
+ awk '{printf("%s/%s",$1,$2);}')
+shift
+COLLECTORS=()
+for collector in "$@"; do
+ COLLECTORS+=($(echo "$collector" | awk '{print $1}'))
+done
+
+while true
+do
+ # Wait when vmcore dumping or syncfs starts.
+ if [ -n "$(pidof sync ${COLLECTORS[@]})" ]; then
+ break
+ fi
+ sleep 0.5
+done
+
+while true
+do
+ # Quit when vmcore dumping and syncfs finishes.
+ if ! [ -n "$(pidof sync ${COLLECTORS[@]})" ]; then
+ break
+ fi
+
+ # Use 'monitoring=0' to override the value in lvm.conf, in case
+ # dmeventd monitoring been started after the calling.
+ lvm lvextend --use-policies --config "activation {monitoring=0}"
"$THIN_POOL"
+ sleep 5
+done
diff --git a/kexec-tools.spec b/kexec-tools.spec
index 6673000..c12f6f6 100644
--- a/kexec-tools.spec
+++ b/kexec-tools.spec
@@ -60,6 +60,7 @@ Source109: dracut-early-kdump-module-setup.sh
Source200: dracut-fadump-init-fadump.sh
Source201: dracut-fadump-module-setup.sh
+Source202: dracut-monitor_lvm2_thinp_autoextend
%ifarch ppc64 ppc64le
Requires(post): servicelog
@@ -240,6 +241,7 @@ cp %{SOURCE102}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpb
cp %{SOURCE104}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE104}}
cp %{SOURCE106}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE106}}
cp %{SOURCE107}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE107}}
+cp %{SOURCE202}
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE202}}
chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE100}}
chmod 755
$RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix
%{SOURCE101}}
mkdir -p -m755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump
--
2.33.1