diff --git a/README.md b/README.md index 4ebb3bf..4928c99 100644 --- a/README.md +++ b/README.md @@ -90,11 +90,16 @@ details. Use the following environment variables: - * WM2_VERBOSE: value from 0 (default, no logging) - 3 (tracing). + * `WM2_VERBOSE:` value from 0 (default, no logging) - 3 (tracing). the -v/--verbose option increases log level by one. - * WM2_DEBUG: 0 (default) or 1. Enables verbose output of certain + * `WM2_DEBUG`: 0 (default) or 1. Enables verbose output of certain commands called by weak-modules2. Equivalent to --debug. - * WM2_LOGFILE: redirect the output to the given file. + * `WM2_LOGFILE`: redirect the output to the given file. + +### Other environment variables + + * `WM2_DEPMOD_INC`: set this to a non-empty string to enable the experimental + "incremental depmod" feature. This will speed up KMP installations. ## Kernel scriptlet files diff --git a/kernel-scriptlets/rpm-script b/kernel-scriptlets/rpm-script index 002fc48..e2687da 100644 --- a/kernel-scriptlets/rpm-script +++ b/kernel-scriptlets/rpm-script @@ -281,6 +281,9 @@ EOF [ -z "$certs" ] || /usr/lib/module-init-tools/kernel-scriptlets/cert-$op --ca-check 1 --certs "$certs" "$@" ;; posttrans) + if test -x /usr/lib/module-init-tools/regenerate-initrd-posttrans; then + /bin/bash -c 'set +e; /usr/lib/module-init-tools/regenerate-initrd-posttrans' || script_rc=$? + fi ;; *) echo Unknown scriptlet "$op" >&2 diff --git a/weak-modules2 b/weak-modules2 index 94df90b..e1206f6 100644 --- a/weak-modules2 +++ b/weak-modules2 @@ -113,10 +113,11 @@ doit() { else : fi + log "Done $1" } strip_mod_extensions() { - sed -rn '/^_kernel_$/p;s/\.ko(\.[gx]z|\.zst)?$//p' + sed -rn 's/\.ko(\.[gx]z|\.zst)?$//p' } # Name of the symlink that makes a module available to a given kernel @@ -158,9 +159,9 @@ add_kmp_modules() { local module symlink while read module; do symlink=$(symlink_to_module $module $krel) - doit mkdir -p ${opt_debug:+-v} $basedir${symlink%/*} || exit 1 - doit ln -sf ${opt_debug:+-v} $module $basedir$symlink || exit 1 - dlog "add_kmp_modules: added $module to $krel" + mkdir -p $basedir${symlink%/*} || exit 1 + ln -sf $module $basedir$symlink || exit 1 + dlog "add_kmp_modules: added $module to $krel in $basedir" done < $tmpdir/modules-$kmp } @@ -173,7 +174,7 @@ remove_kmp_modules() { local module symlink while read module; do symlink=$(symlink_to_module $module $krel) - doit rm -f ${opt_debug:+-v} $basedir$symlink + rm -f $basedir$symlink dlog "remove_kmp_modules: removed $module from $krel" done < $tmpdir/modules-$kmp } @@ -195,7 +196,8 @@ create_temporary_modules_dir() { # Check for unresolved symbols has_unresolved_symbols() { - local krel=$1 basedir=$2 output status args sym_errors _f + local krel=$1 basedir=$2 kmp=$3 kmp_mods=() inc= + local output status args sym_errors _f if [ ! -e $tmpdir/symvers-$krel ]; then for _f in /boot/symvers-$krel.gz /usr/lib/modules/$krel/symvers.gz; do @@ -212,8 +214,23 @@ has_unresolved_symbols() { echo "warning: $tmpdir/symvers-$krel not available" >&2 args=(-F /boot/System.map-$krel) fi - output="$("$DEPMOD" -b "$basedir" -ae "${args[@]}" $krel 2>&1)" + if [[ $WM2_DEPMOD_INC && $kmp ]]; then + inc=-I + kmp_mods=($(cat $tmpdir/modules-$kmp)) + # prepend $basedir + kmp_mods=("${kmp_mods[@]/#/$basedir}") + fi + log "$DEPMOD -b $basedir -ae ${args[@]} $inc $krel ${kmp_mods[@]}" + output="$("$DEPMOD" -b "$basedir" -ae "${args[@]}" $inc $krel ${kmp_mods[@]} 2>&1)" status=$? + log "$DEPMOD finished" + if [[ $status -ne 0 && $WM2_DEPMOD_INC && $kmp ]]; then + # Fallback to full depmod + log "$DEPMOD -b $basedir -ae ${args[@]} $krel" + output="$("$DEPMOD" -b "$basedir" -ae "${args[@]}" $krel 2>&1)" + status=$? + log "$DEPMOD finished" + fi if [ $status -ne 0 ]; then echo "$output" >&2 echo "depmod exited with error $status" >&2 @@ -266,7 +283,7 @@ __can_replace_kmp() { return 1 fi doit=1 add_kmp_modules "$new_kmp" "$krel" "$basedir" - if has_unresolved_symbols "$krel" "$basedir"; then + if has_unresolved_symbols "$krel" "$basedir" "$new_kmp"; then doit=1 remove_kmp_modules "$new_kmp" "$krel" "$basedir" doit=1 add_kmp_modules "$old_kmp" "$krel" "$basedir" return 1 @@ -372,7 +389,7 @@ previous_version_of_kmp() { } get_initrd_basenames() { - $LSINITRD /boot/initrd-$1 | \ + doit $LSINITRD /boot/initrd-$1 | \ sed -rn 's:.*\ must rebuild initrd)? +# 3rd arg: can the initrd build be delayed to %posttrans? +# other args - modules to add, enables depmod incremental +# stdin: list of module basenames to feed into build_initrd / needs_initrd kernel_changed() { - local krel=$1 flavor=${1##*-} + local krel=$1 is_basepkg=$2 may_delay=$3 flavor=${1##*-} + shift + shift + shift if [ ! -f /boot/System.map-$krel ]; then # this kernel does not exist anymore @@ -514,13 +566,14 @@ kernel_changed() { walk_kmps "$krel" fi - echo "_kernel_" | run_depmod_build_initrd "$krel" + run_depmod "$krel" "$@" + build_initrd "$krel" "$is_basepkg" "$may_delay" } add_kernel() { local krel=$1 - kernel_changed $krel + kernel_changed "$krel" initrd_needed "$INITRD_IN_POSTTRANS" } remove_kernel() { @@ -536,17 +589,58 @@ remove_kernel() { add_kernel_modules() { local krel=$1 - cat >/dev/null + local initrd_needed=yes + + sed -rn '/\.ko(|\.xz|\.gz|\.zst)/p' >$tmpdir/kernel-modules + sed 's:.*/::' <$tmpdir/kernel-modules >$tmpdir/kernel-basenames + + # If INITRD_IN_POSTTRANS isn't set, and a kernel base package + # is installed / updated together with subpackages, the base package + # is processed first. If a module from a subpackage is necessary + # in the initrd, it will be missing at that stage, and the initrd + # will be built without it. Therefore we need to force initrd rebuild + # in that case. If INITRD_IN_POSTTRANS is set, this won't happen, and + # we only need to force initrd creation if one of the modules of + # our subpkg are present in the initrd. + if [[ $INITRD_IN_POSTTRANS ]]; then + initrd_needed= + fi + kernel_changed "$krel" "$initrd_needed" "$INITRD_IN_POSTTRANS" \ + $(cat $tmpdir/kernel-modules) \ + <$tmpdir/kernel-basenames +} + +# for package deletion, there's no %posttrans, therefore delaying the +# initrd rebuild is not generally possible. But if some other package +# has scheduled a rebuild for the given kernel already, we can. +# (this would happen on a KMP update, for example). +may_delay_on_removal() { + local krel=$1 res= + + if [[ $INITRD_IN_POSTTRANS ]]; then + if [[ -e /run/regenerate-initrd/all ]]; then + res="1" + else + local image=$(get_image_name "$krel") - kernel_changed $krel + if [[ -e /run/regenerate-initrd/$image-$krel ]]; then + res="1" + fi + fi + fi + dlog "may_delay_on_removal => \"$res\"" + echo "$res" } remove_kernel_modules() { local krel=$1 - cat >/dev/null + + sed -rn '/\.ko(|\.xz|\.gz|\.zst)/p' >$tmpdir/kernel-modules + sed 's:.*/::' <$tmpdir/kernel-modules >$tmpdir/kernel-basenames # FIXME: remove KMP symlinks that no longer work - kernel_changed $krel + kernel_changed "$krel" "" "$(may_delay_on_removal "$krel")" \ + <$tmpdir/kernel-basenames } add_kmp() { @@ -567,15 +661,13 @@ add_kmp() { esac dlog "add_kmp: processing $kmp for $krel" [ -d $dir -a -f /boot/System.map-$krel ] || continue - if opt_debug=1 has_unresolved_symbols "$krel" "/"; then - echo "Warning: /lib/modules/$krel is inconsistent" >&2 - echo "Warning: weak-updates symlinks might not be created" >&2 - fi if kmp_is_present $kmp $krel; then log "Package $kmp does not need to be added to kernel $krel" - run_depmod_build_initrd "$krel" <$tmpdir/basenames-$kmp || \ - status=1 + run_depmod "$krel" && \ + build_initrd "$krel" "" "$INITRD_IN_POSTTRANS" \ + <$tmpdir/basenames-$kmp || \ + status=1 continue fi local old_kmp=$(previous_version_of_kmp $kmp $krel) @@ -584,15 +676,25 @@ add_kmp() { add_kmp_modules "$kmp" "$krel" if [ -z "$old_kmp" ]; then log "Package $kmp added to kernel $krel" - run_depmod_build_initrd "$krel" <$tmpdir/basenames-$kmp || \ - status=1 + run_depmod "$krel" $(cat $tmpdir/modules-$kmp) && \ + build_initrd "$krel" "" "$INITRD_IN_POSTTRANS" \ + <$tmpdir/basenames-$kmp || \ + status=1 else log "Package $old_kmp replaced by package $kmp in kernel $krel" - cat $tmpdir/basenames-{$old_kmp,$kmp} \ - | run_depmod_build_initrd "$krel" || status=1 + run_depmod "$krel" $(cat $tmpdir/modules-$kmp) && \ + cat $tmpdir/basenames-{$old_kmp,$kmp} \ + | build_initrd "$krel" "" "$INITRD_IN_POSTTRANS" || \ + status=1 fi + elif [[ $old_kmp ]]; then + log "Package $old_kmp kept in kernel $krel (not replaced by $kmp)" else - dlog "add_kmp: skipped $kmp" + echo "FAILED to add $kmp in kernel $krel" >&2 + if [[ $opt_debug -gt 0 ]] && \ + has_unresolved_symbols "$krel" "/"; then + echo "Warning: /lib/modules/$krel is inconsistent" >&2 + fi fi done dlog "add_kmp: status=$status" @@ -623,12 +725,7 @@ remove_kmp() { [ -d $dir -a -f /boot/System.map-$krel ] || continue dlog "remove_kmp: processing $kmp for $krel" if kmp_is_present $kmp $krel; then - local other_found=0 inconsistent=0 - - if opt_debug=1 has_unresolved_symbols "$krel" "/" \ - >$tmpdir/unresolved-"$krel" 2>&1; then - inconsistent=1 - fi + local other_found=0 if [ $krel != "$(cat $tmpdir/krel-$kmp)" ]; then remove_kmp_modules "$kmp" "$krel" @@ -647,22 +744,20 @@ remove_kmp() { done < $tmpdir/kmps if [ -n "$other_kmp" ]; then log "Package $kmp replaced by package $other_kmp in kernel $krel" - cat $tmpdir/basenames-{$kmp,$other_kmp} \ - | run_depmod_build_initrd "$krel" || status=1 + run_depmod "$krel" && \ + cat $tmpdir/basenames-{$kmp,$other_kmp} \ + | build_initrd "$krel" "" "$(may_delay_on_removal "$krel")" || \ + status=1 else log "Package $kmp removed from kernel $krel" if [ $other_found -eq 1 ]; then log "Weak-updates symlinks to no other $kmpshort package could be created" - if [ $inconsistent -eq 1 ]; then - echo "Warning: /lib/modules/$krel was inconsistent before removal of $kmp" >&2 - [ -s $tmpdir/unresolved-"$krel" ] && \ - cat $tmpdir/unresolved-"$krel" - fi fi - run_depmod_build_initrd "$krel" <$tmpdir/basenames-$kmp || \ - status=1 + run_depmod "$krel" && \ + build_initrd "$krel" "" "$(may_delay_on_removal "$krel")" \ + <$tmpdir/basenames-$kmp || \ + status=1 fi - rm -f $tmpdir/unresolved-"$krel" fi done dlog "remove_kmp: status=$status" @@ -717,6 +812,7 @@ usage() { ############################################################################## +echo "weak-modules2 startup" >&2 save_argv=("$@") options=`getopt -o vh --long add-kernel,remove-kernel,add-kmp,remove-kmp \ --long add-kernel-modules,remove-kernel-modules \ @@ -842,4 +938,5 @@ case $mode in remove_kmp "$1" esac +echo "weak-modules2 finished" >&2 # vim:shiftwidth=4 softtabstop=4