We now have a module list in the initramfs, and combined with extra_modules we can detect any module update that may require a initramfs build. As a result we don't have to always rebuild, only rebuild whe needed. And also cover the case that kernel modules are updated but initramfs is not updated.
Even we drop the behavior or bebuild initramfs on kernel loaded module list changed, detecting module file change should always be a good idea to ensure initramfs is up to date.
Overhead is small, will consume about 0.1s to check for kernel module update for about 100 modules.
Signed-off-by: Kairui Song kasong@redhat.com --- kdumpctl | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-)
diff --git a/kdumpctl b/kdumpctl index 1cfbe31..25a5e3b 100755 --- a/kdumpctl +++ b/kdumpctl @@ -476,19 +476,46 @@ check_wdt_modified() return 1 }
+# Check if loaded kernel module list is changed, and check if any loaded module file is changed. check_kmodules_modified() { + local _module_file _time_stamp + local _modified_modules _added_modules _dropped_modules + # always sort again to avoid LANG/LC inconsistent problem local _old_modules="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/loaded-kernel-modules.txt | sort)" local _new_modules="$(get_loaded_kernel_modules | sort)" + local _extra_modules="$(grep ^extra_modules $KDUMP_CONFIG_FILE | sed 's/^extra_modules\s*//')"
- [[ -z $_old_modules ]] && echo "Warning: Previous loaded kernel module list is absent or empty" + if [[ -z "$_old_modules" ]] && [[ -n "$_extra_modules" ]]; then + echo "Warning: Previous loaded kernel module list is absent or " \ + "empty, and extra modules is set, forcing rebuild" + return 1 + fi
- local _added_modules=$(comm -13 <(echo "$_old_modules") <(echo "$_new_modules")) - local _dropped_modules=$(comm -23 <(echo "$_old_modules") <(echo "$_new_modules")) + _added_modules=$(comm -13 <(echo "$_old_modules") <(echo "$_new_modules")) + _dropped_modules=$(comm -23 <(echo "$_old_modules") <(echo "$_new_modules")) + + # Check for any updated module + for _module in $(echo "$_old_modules $_extra_modules" | sort | uniq); do + _module_file="$(modinfo -k "$kdump_kver" -n "$_module" 2>/dev/null)" + if [[ $? -ne 0 ]]; then + # Ignore for now, maybe the module is a builtin, + # else dracut will print an error to let the user know + : + else + _time_stamp="$(stat -c "%Y" "$_module_file")" + if [ "$_time_stamp" -gt "$image_time" ]; then + _modified_modules+="$_module " + fi + fi + done
- if [ "$_old_modules" != "$_new_modules" ]; then - echo "Detected change(s) of loaded kernel modules list:" + if [[ -n "$_modified_modules" ]] || [[ -n "$_added_modules" ]] || [[ -n "$_dropped_modules" ]]; then + echo "Detected change(s) of following kernel modules:" + [[ -n "$_modified_modules" ]] && for _module in $_modified_modules; do + echo " *$_module" + done [[ -n $_added_modules ]] && for _module in $_added_modules; do echo " +$_module" done @@ -538,7 +565,6 @@ check_system_modified()
check_rebuild() { - local extra_modules local capture_capable_initrd="1" local _force_rebuild force_rebuild="0" local _force_no_rebuild force_no_rebuild="0" @@ -578,10 +604,6 @@ check_rebuild() return 0 fi
- #will rebuild every time if extra_modules are specified - extra_modules=`grep ^extra_modules $KDUMP_CONFIG_FILE` - [ -n "$extra_modules" ] && force_rebuild="1" - #check to see if dependent files has been modified #since last build of the image file if [ -f $TARGET_INITRD ]; then
Hi Kairui, On 03/15/19 at 12:07pm, Kairui Song wrote:
We now have a module list in the initramfs, and combined with extra_modules we can detect any module update that may require a initramfs build. As a result we don't have to always rebuild, only rebuild whe needed. And also cover the case that kernel modules are updated but initramfs is not updated.
Even we drop the behavior or bebuild initramfs on kernel loaded module list changed, detecting module file change should always be a good idea to ensure initramfs is up to date.
Overhead is small, will consume about 0.1s to check for kernel module update for about 100 modules.
Signed-off-by: Kairui Song kasong@redhat.com
kdumpctl | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-)
diff --git a/kdumpctl b/kdumpctl index 1cfbe31..25a5e3b 100755 --- a/kdumpctl +++ b/kdumpctl @@ -476,19 +476,46 @@ check_wdt_modified() return 1 }
+# Check if loaded kernel module list is changed, and check if any loaded module file is changed. check_kmodules_modified() {
- local _module_file _time_stamp
- local _modified_modules _added_modules _dropped_modules
- # always sort again to avoid LANG/LC inconsistent problem local _old_modules="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/loaded-kernel-modules.txt | sort)" local _new_modules="$(get_loaded_kernel_modules | sort)"
- local _extra_modules="$(grep ^extra_modules $KDUMP_CONFIG_FILE | sed 's/^extra_modules\s*//')"
- [[ -z $_old_modules ]] && echo "Warning: Previous loaded kernel module list is absent or empty"
- if [[ -z "$_old_modules" ]] && [[ -n "$_extra_modules" ]]; then
echo "Warning: Previous loaded kernel module list is absent or " \
"empty, and extra modules is set, forcing rebuild"
return 1
- fi
- local _added_modules=$(comm -13 <(echo "$_old_modules") <(echo "$_new_modules"))
- local _dropped_modules=$(comm -23 <(echo "$_old_modules") <(echo "$_new_modules"))
- _added_modules=$(comm -13 <(echo "$_old_modules") <(echo "$_new_modules"))
I remember we have a report that kdump service runs earlier than some udev modprobe, so that this can cause rebuild initrd for each time in that case. And we talked about revert the module checking code.
But extra_modules is different with the check_kmodules case, am I missing something?
- _dropped_modules=$(comm -23 <(echo "$_old_modules") <(echo "$_new_modules"))
- # Check for any updated module
- for _module in $(echo "$_old_modules $_extra_modules" | sort | uniq); do
_module_file="$(modinfo -k "$kdump_kver" -n "$_module" 2>/dev/null)"
if [[ $? -ne 0 ]]; then
# Ignore for now, maybe the module is a builtin,
# else dracut will print an error to let the user know
:
else
_time_stamp="$(stat -c "%Y" "$_module_file")"
if [ "$_time_stamp" -gt "$image_time" ]; then
_modified_modules+="$_module "
fi
fi
- done
- if [ "$_old_modules" != "$_new_modules" ]; then
echo "Detected change(s) of loaded kernel modules list:"
- if [[ -n "$_modified_modules" ]] || [[ -n "$_added_modules" ]] || [[ -n "$_dropped_modules" ]]; then
echo "Detected change(s) of following kernel modules:"
[[ -n "$_modified_modules" ]] && for _module in $_modified_modules; do
echo " *$_module"
[[ -n $_added_modules ]] && for _module in $_added_modules; do echo " +$_module" donedone
@@ -538,7 +565,6 @@ check_system_modified()
check_rebuild() {
- local extra_modules local capture_capable_initrd="1" local _force_rebuild force_rebuild="0" local _force_no_rebuild force_no_rebuild="0"
@@ -578,10 +604,6 @@ check_rebuild() return 0 fi
- #will rebuild every time if extra_modules are specified
- extra_modules=`grep ^extra_modules $KDUMP_CONFIG_FILE`
- [ -n "$extra_modules" ] && force_rebuild="1"
- #check to see if dependent files has been modified #since last build of the image file if [ -f $TARGET_INITRD ]; then
-- 2.20.1
Thanks Dave
On Wed, Mar 20, 2019 at 6:09 PM Dave Young dyoung@redhat.com wrote:
I remember we have a report that kdump service runs earlier than some udev modprobe, so that this can cause rebuild initrd for each time in that case. And we talked about revert the module checking code.
But extra_modules is different with the check_kmodules case, am I missing something?
Yes, I put the extra_modules checking code in check_kmodules because it fits well with the function name. (check kernel modules) And we already have a old_modules list in initramfs now, so it should be good to check if there is any change of any module that got loaded by the previous kernel. This may cover some case user updated the modules but initramfs is not rebuilt. Just a bold suggestion, I can remove this part if there is any risk.
And as currently I still haven't reproduced the initramfs being rebuilt unexpectedly problem, I'm not sure if there is any better way to solve the problem, I think revert the commit is the button line only if there is no other way to fix it...