Block driver detection now doesn't work for raw targets, this will fix
it. And watchdog driver detection is broken after we enabled the squash
module, this also fixed that problem.
Last two patches will include watchdog-modules by default, but dracut
haven't make a release containing this module yet, so the last two
patches may be merged later.
Kairui Song (5):
kdumpctl: split the driver detection from fs dection function
Remove a redundant nfs check
Fix the watchdog drivers detection code
kdump-lib.sh: Use a more generic helper to detect omitted dracut
module
Always include watchdog-modules
dracut-module-setup.sh | 1 +
kdump-lib.sh | 35 +++-----
kdumpctl | 191 ++++++++++++++++-------------------------
3 files changed, 90 insertions(+), 137 deletions(-)
--
2.28.0
Show replies by date
The driver detection have nothing to do with fs detection, and currently
if the dump target is raw, the block driver detection is skipped which
is wrong. Just split it out and run the block driver detection when dump
target is fs or raw.
Also simplfied the code a bit.
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
kdumpctl | 98 ++++++++++++++++++++++++++++----------------------------
1 file changed, 49 insertions(+), 49 deletions(-)
diff --git a/kdumpctl b/kdumpctl
index 2248da4..5b8ded5 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -417,14 +417,47 @@ check_files_modified()
return 0
}
-check_dump_fs_modified()
+check_drivers_modified()
+{
+ local _target _new_drivers _old_drivers _module_name _module_filename
+
+ # If it's dump target is on block device, detect the block driver
+ if is_raw_dump_target || is_fs_dump_target; then
+ _record_block_drivers() {
+ local _drivers
+ _drivers=$(udevadm info -a "/dev/block/$1" | sed -n
's/\s*DRIVERS=="\(\S\+\)"/\1/p')
+ for _driver in $_drivers; do
+ if ! [[ " $_new_drivers " == *" $_driver "* ]]; then
+ _new_drivers="$_new_drivers $_driver"
+ fi
+ done
+ }
+ _target=$(get_block_dump_target)
+ check_block_and_slaves_all _record_block_drivers "$(get_maj_min
"$_target")"
+ fi
+
+ [ -z "$_new_drivers" ] && return 0
+
+ _old_drivers="$(lsinitrd $TARGET_INITRD -f
/usr/lib/dracut/hostonly-kernel-modules.txt | tr '\n' ' ')"
+ for _driver in $_new_drivers; do
+ # Skip deprecated/invalid driver name or built-in module
+ _module_name=$(modinfo --set-version "$KDUMP_KERNELVER" -F name $_driver
2>/dev/null)
+ _module_filename=$(modinfo --set-version "$KDUMP_KERNELVER" -n $_driver
2>/dev/null)
+ if [ $? -ne 0 ] || [ -z "$_module_name" ] || [[ "$_module_filename"
= *"(builtin)"* ]]; then
+ continue
+ fi
+ if ! [[ " $_old_drivers " == *" $_module_name "* ]]; then
+ echo "Detected change in block device driver, new loaded module:
$_module_name"
+ return 1
+ fi
+ done
+}
+
+check_fs_modified()
{
local _old_dev _old_mntpoint _old_fstype
local _new_dev _new_mntpoint _new_fstype
local _target _path _dracut_args
- local _target_drivers _module_name _module_filename
-
- local _old_drivers="$(lsinitrd $TARGET_INITRD -f
/usr/lib/dracut/hostonly-kernel-modules.txt | tr '\n' ' ')"
# No need to check in case of mount target specified via "dracut_args".
if is_mount_in_dracut_args; then
@@ -437,52 +470,13 @@ check_dump_fs_modified()
return 0
fi
- _target=$(get_user_configured_dump_disk)
-
- if [[ -n "$_target" ]]; then
- _target=$(to_dev_name $_target)
- _new_fstype=$(blkid $_target | awk -F"TYPE=" '{print $2}' | cut -d
'"' -f 2)
- else
- _path=$(get_save_path)
- _target=$(get_target_from_path $_path)
- _target=$(to_dev_name $_target)
- _new_fstype=$(get_fs_type_from_target $_target)
- if [[ -z "$_target" || -z "$_new_fstype" ]];then
- echo "Dump path $_path does not exist"
- return 2
- fi
+ _target=$(get_block_dump_target)
+ _new_fstype=$(get_fs_type_from_target $_target)
+ if [[ -z "$_target" ]] || [[ -z "$_new_fstype" ]];then
+ echo "Dump target is invalid"
+ return 2
fi
- _record_block_drivers() {
- local _drivers
- if [[ -b /dev/block/$1 ]]; then
- _drivers=$(udevadm info -a "/dev/block/$1" | sed -n
's/\s*DRIVERS=="\(\S\+\)"/\1/p')
- fi
- if [[ -b $1 ]]; then
- _drivers=$(udevadm info -a "$1" | sed -n
's/\s*DRIVERS=="\(\S\+\)"/\1/p')
- fi
- for _driver in $_drivers; do
- if ! [[ " $_target_drivers " == *" $_driver "* ]]; then
- _target_drivers="$_target_drivers $_driver"
- fi
- done
- return 1
- }
-
- check_block_and_slaves_all _record_block_drivers "$(get_maj_min
"$_target")"
- for _driver in $_target_drivers; do
- # Skip deprecated/invalid driver name or built-in module
- _module_name=$(modinfo --set-version "$KDUMP_KERNELVER" -F name $_driver
2>/dev/null)
- _module_filename=$(modinfo --set-version "$KDUMP_KERNELVER" -n $_driver
2>/dev/null)
- if [ $? -ne 0 ] || [ -z "$_module_name" ] || [[ "$_module_filename"
= *"(builtin)"* ]]; then
- continue
- fi
- if ! [[ " $_old_drivers " == *" $_module_name "* ]]; then
- echo "Detected change in block device driver, new loaded module:
$_module_name"
- return 1
- fi
- done
-
if [[ $(expr substr $_new_fstype 1 3) = "nfs" ]];then
_new_dev=$_target
else
@@ -589,7 +583,13 @@ check_system_modified()
return $ret
fi
- check_dump_fs_modified
+ check_fs_modified
+ ret=$?
+ if [ $ret -ne 0 ]; then
+ return $ret
+ fi
+
+ check_drivers_modified
ret=$?
if [ $ret -ne 0 ]; then
return $ret
--
2.28.0
In check_fs_modified, is_nfs_dump_target is already called, the dump
target can't be nfs. No need to check here.
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
kdumpctl | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/kdumpctl b/kdumpctl
index 5b8ded5..46a5006 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -477,14 +477,10 @@ check_fs_modified()
return 2
fi
- if [[ $(expr substr $_new_fstype 1 3) = "nfs" ]];then
- _new_dev=$_target
- else
- _new_dev=$(kdump_get_persistent_dev $_target)
- if [ -z "$_new_dev" ]; then
- echo "Get persistent device name failed"
- return 2
- fi
+ _new_dev=$(kdump_get_persistent_dev $_target)
+ if [ -z "$_new_dev" ]; then
+ echo "Get persistent device name failed"
+ return 2
fi
_new_mntpoint="$(get_kdump_mntpoint_from_target $_target)"
--
2.28.0
Currently the watchdog detection code is broken already, it
get the list of active watchdog drivers, then check if they are
set in the /etc/cmdline.d/* as preload module. But after we
switched to use squash module, /etc/cmdline.d/* is not directly visible.
So just detect whether current needed driver is installed.
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
kdumpctl | 90 ++++++++++++++++++--------------------------------------
1 file changed, 28 insertions(+), 62 deletions(-)
diff --git a/kdumpctl b/kdumpctl
index 46a5006..3d8f711 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -436,6 +436,34 @@ check_drivers_modified()
check_block_and_slaves_all _record_block_drivers "$(get_maj_min
"$_target")"
fi
+ # Detect watchdog drivers, if watchdog is available and not manually omitted
+ _record_wd_drivers() {
+ local _active _wdtdrv _wdtppath _dir
+
+ # Copied logic from dracut 04watchdog/module-setup.sh::installkernel()
+ for _dir in /sys/class/watchdog/*; do
+ [[ -f "$_dir/state" ]] || continue
+ _active=$(< "$_dir/state")
+ [[ "$_active" = "active" ]] || continue
+ # device/modalias will return driver of this device
+ [[ -f "$_dir/device/modalias" ]] || continue
+ _wdtdrv=$(< "$_dir/device/modalias")
+ # There can be more than one module represented by same
+ # modalias. Currently load all of them.
+ # TODO: Need to find a way to avoid any unwanted module
+ # represented by modalias
+ _wdtdrv=$(modprobe --set-version "$KDUMP_KERNELVER" -R $_wdtdrv
2>/dev/null)
+ if [[ $_wdtdrv ]]; then
+ for i in $_wdtdrv; do
+ if ! [[ " $_new_drivers " == *" $i "* ]]; then
+ _new_drivers="$_new_drivers $i"
+ fi
+ done
+ fi
+ done
+ }
+ is_wdt_mod_omitted || _record_wd_drivers
+
[ -z "$_new_drivers" ] && return 0
_old_drivers="$(lsinitrd $TARGET_INITRD -f
/usr/lib/dracut/hostonly-kernel-modules.txt | tr '\n' ' ')"
@@ -508,62 +536,6 @@ check_fs_modified()
return 1
}
-check_wdt_modified()
-{
- local -A _drivers
- local _alldrivers _active _wdtdrv _wdtppath _dir
- local wd_old wd_new
-
- is_wdt_mod_omitted
- [[ $? -eq 0 ]] && return 0
- [[ -d /sys/class/watchdog/ ]] || return 0
-
- # Copied logic from dracut 04watchdog/module-setup.sh::installkernel()
- for _dir in /sys/class/watchdog/*; do
- [[ -d "$_dir" ]] || continue
- [[ -f "$_dir/state" ]] || continue
- _active=$(< "$_dir/state")
- [[ "$_active" = "active" ]] || continue
- # device/modalias will return driver of this device
- _wdtdrv=$(< "$_dir/device/modalias")
- # There can be more than one module represented by same
- # modalias. Currently load all of them.
- # TODO: Need to find a way to avoid any unwanted module
- # represented by modalias
- _wdtdrv=$(modprobe --set-version "$KDUMP_KERNELVER" -R $_wdtdrv
2>/dev/null)
- if [[ $_wdtdrv ]]; then
- for i in $_wdtdrv; do
- _drivers[$i]=1
- done
- fi
- # however in some cases, we also need to check that if there is
- # a specific driver for the parent bus/device. In such cases
- # we also need to enable driver for parent bus/device.
- _wdtppath=$(readlink -f "$_dir/device")
- while [[ -d "$_wdtppath" ]] && [[ "$_wdtppath" !=
"/sys" ]]; do
- _wdtppath=$(readlink -f "$_wdtppath/..")
- [[ -f "$_wdtppath/modalias" ]] || continue
-
- _wdtdrv=$(< "$_wdtppath/modalias")
- _wdtdrv=$(modprobe --set-version "$KDUMP_KERNELVER" -R $_wdtdrv
2>/dev/null)
- if [[ $_wdtdrv ]]; then
- for i in $_wdtdrv; do
- _drivers[$i]=1
- done
- fi
- done
- done
-
- # 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" = "$wd_new" ]] && return 0
-
- return 1
-}
-
# returns 0 if system is not modified
# returns 1 if system is modified
# returns 2 if system modification is invalid
@@ -591,12 +563,6 @@ check_system_modified()
return $ret
fi
- check_wdt_modified
- if [ $? -ne 0 ]; then
- echo "Detected change in watchdog state"
- return 1
- fi
-
return 0
}
--
2.28.0
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
kdump-lib.sh | 35 ++++++++++++++---------------------
kdumpctl | 2 +-
2 files changed, 15 insertions(+), 22 deletions(-)
diff --git a/kdump-lib.sh b/kdump-lib.sh
index 119b7e2..ca69ce4 100755
--- a/kdump-lib.sh
+++ b/kdump-lib.sh
@@ -453,28 +453,21 @@ get_ifcfg_filename() {
echo -n "${ifcfg_file}"
}
-# returns 0 when omission of watchdog module is desired in dracut_args
+# returns 0 when omission of a module is desired in dracut_args
# returns 1 otherwise
-is_wdt_mod_omitted() {
- local dracut_args
- local ret=1
-
- dracut_args=$(grep "^dracut_args" /etc/kdump.conf)
- [[ -z $dracut_args ]] && return $ret
-
- eval set -- $dracut_args
- while :; do
- [[ -z $1 ]] && break
- case $1 in
- -o|--omit)
- echo $2 | grep -qw "watchdog"
- [[ $? == 0 ]] && ret=0
- break
- esac
- shift
- done
-
- return $ret
+is_dracut_mod_omitted() {
+ local dracut_args dracut_mod=$1
+
+ set -- $(grep "^dracut_args" /etc/kdump.conf)
+ while [ $# -gt 0 ]; do
+ case $1 in
+ -o|--omit)
+ [[ " ${2//[^[:alnum:]]/ } " == *" $dracut_mod "* ]]
&& return 0
+ esac
+ shift
+ done
+
+ return 1
}
is_wdt_active() {
diff --git a/kdumpctl b/kdumpctl
index 3d8f711..2f7e7e3 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -462,7 +462,7 @@ check_drivers_modified()
fi
done
}
- is_wdt_mod_omitted || _record_wd_drivers
+ is_dracut_mod_omitted watchdog || _record_wd_drivers
[ -z "$_new_drivers" ] && return 0
--
2.28.0
Systemd have a RebootWatchdogSec option that use watchdog to prevent
reboot hangs. And it can help prevent many kinds of hangs upon kdump
reboot, either it's systemd bug or kernel issue.
The overhead of watchdog drivers is trivial, and dracut have this new
watchdog-driver module that only load the kernel driver. So alway
install this module.
Also install all driver of watchdog instead of just active watchdog,
upstream dracut have changed the behaviour so follow up.
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
dracut-module-setup.sh | 1 +
kdumpctl | 7 ++-----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh
index db9250d..9f25172 100755
--- a/dracut-module-setup.sh
+++ b/dracut-module-setup.sh
@@ -40,6 +40,7 @@ depends() {
dwarning "Required modules to build a squashed kdump image is
missing!"
fi
+ add_opt_module watchdog-modules
if is_wdt_active; then
add_opt_module watchdog
fi
diff --git a/kdumpctl b/kdumpctl
index 2f7e7e3..f633ccb 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -438,13 +438,10 @@ check_drivers_modified()
# Detect watchdog drivers, if watchdog is available and not manually omitted
_record_wd_drivers() {
- local _active _wdtdrv _wdtppath _dir
+ local _wdtdrv _wdtppath _dir
# Copied logic from dracut 04watchdog/module-setup.sh::installkernel()
for _dir in /sys/class/watchdog/*; do
- [[ -f "$_dir/state" ]] || continue
- _active=$(< "$_dir/state")
- [[ "$_active" = "active" ]] || continue
# device/modalias will return driver of this device
[[ -f "$_dir/device/modalias" ]] || continue
_wdtdrv=$(< "$_dir/device/modalias")
@@ -462,7 +459,7 @@ check_drivers_modified()
fi
done
}
- is_dracut_mod_omitted watchdog || _record_wd_drivers
+ is_dracut_mod_omitted watchdog || is_dracut_mod_omitted watchdog-modules ||
_record_wd_drivers
[ -z "$_new_drivers" ] && return 0
--
2.28.0