On Wed, May 8, 2019 at 4:19 PM Kairui Song <kasong(a)redhat.com> wrote:
Previous we rebuild the initramfs when kenrel load module list changed,
but this is not very stable as some async services may load/unload
kernel modules, and cause unnecessary initramfs rebuild.
Instead, it's better to just check if the module required to dump to
the dump target is loaded or not, and rebuild if not loaded. This
avoids most false-positives, and ensure local target change is always
covered.
Currently only local fs dump target is covered, because this check
requires the dump target to be mounted when building the initramfs,
this guarantee that the module is in the loaded kernel module list,
else we may still get some false positive.
dracut-install could be leveraged to combine the modalias list with
kernel loaded module list as a more stable module list in the initramfs,
but upstream dracut change need to be done first.
Passed test on a KVM VM, changing the storage between SATA/USB/VirtIO
will trigger initramfs rebuild and didn't notice any false-positive.
Also passed tests on my laptop and an AWS instance.
Signed-off-by: Kairui Song <kasong(a)redhat.com>
---
Update from V1:
- Make it work well for most modules with older version of kmod
- Improve some output message
kdumpctl | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/kdumpctl b/kdumpctl
index 3f80ba4..e78ac46 100755
--- a/kdumpctl
+++ b/kdumpctl
@@ -357,6 +357,9 @@ check_dump_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
+
+ local _old_drivers="$(lsinitrd $TARGET_INITRD -f
/usr/lib/dracut/loaded-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
@@ -385,6 +388,44 @@ check_dump_fs_modified()
fi
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
+ # Target is mounted already, if module is not included by current
kernel,
+ # could be a deprecated/invalid driver name or a built-in module
+ _module_name=$(modinfo --set-version "$kdump_kver" -F name
$_driver 2>/dev/null)
+ if [ $? -ne 0 ]; then
+ continue
+ fi
+ # Older version of kmod util doesn't give module name, so follow
Kbuild's
+ # name-fix rule and guess the name
+ if [ -z "$_module_name" ]; then
+ _module_name=$(echo "$_driver" | sed
"s/\(,\|-\)/_/g")
+ if ! (grep "\b$_driver\b" /proc/modules -q); then
+ continue
+ fi
+ 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
--
2.20.1
After some offline discus with Dave, the old version kmod workaround
is not needed on Fedora with the latest package, so instead V1 will be
merged with minor update of out put message.
--
Best Regards,
Kairui Song