diff --git a/SOURCES/weak-modules b/SOURCES/weak-modules index 2ca97b2..e5ef982 100644 --- a/SOURCES/weak-modules +++ b/SOURCES/weak-modules @@ -409,12 +409,17 @@ remove_weak_link_quiet() { update_modules_for_krel() { local krel="$1" local func="$2" + local do_fallback="$3" [[ -r "$BASEDIR/boot/symvers-$krel.gz" ]] || return global_link_state_save $krel $func $krel - validate_weak_links $krel + if ! validate_weak_links $krel && [[ -n "$do_fallback" ]]; then + global_link_state_restore $krel + return; + fi + global_link_state_announce_changes $krel } @@ -426,13 +431,14 @@ update_modules_for_krel() { # Triggers initrd rebuild for the kernels, which modules are installed. update_modules() { local func="$1" + local do_fallback="$2" local module_krel read_modules_list || exit 1 [[ ${#modules[@]} -gt 0 ]] || return for krel in $(find_installed_kernels); do - update_modules_for_krel $krel $func + update_modules_for_krel $krel $func $do_fallback done for module in "${modules[@]}"; do @@ -520,6 +526,9 @@ remove_weak_links() { # accroding to the priority list in its configuration, but without symbol # check and doesn't amend the list during the check, the function runs it # in a loop in which it removes discovered incompatible symlinks +# +# Returns 0 (success) if proposal is fine or +# 1 (false) if some incompatible symlinks were removed validate_weak_links() { local krel="$1" local basedir=${BASEDIR:+-b $BASEDIR} @@ -532,6 +541,9 @@ validate_weak_links() { local modpath local symbol local weak_link + # to return to caller that original proposal is not valid + # here 0 is true, 1 is false, since it will be the return code + local is_configuration_valid=0 tmp=$(mktemp -p $tmpdir) @@ -578,6 +590,7 @@ validate_weak_links() { pr_verbose "Module $(module_short_name $modpath) from kernel $module_krel is not compatible with kernel $krel in symbols: ${symbols[$modpath]}" is_updates_changed=1 + is_configuration_valid=1 # inversed value done done rm -f $tmp @@ -595,6 +608,7 @@ validate_weak_links() { pr_verbose "Module ${module##*/} from kernel $module_krel is compatible with kernel $krel" fi done + return $is_configuration_valid } # global_link_state_save: @@ -613,6 +627,28 @@ global_link_state_save() { done } +# global_link_state_restore: +# Takes kernel release +# Restores the previous weak links state +# (for example, if incompatible modules were installed) +global_link_state_restore() { + local krel="$1" + local link + local target + local weak_modules_dir="$BASEDIR/lib/modules/$krel/weak-updates" + + pr_verbose "Falling back weak-modules state for kernel $krel" + + ( cd "$weak_modules_dir" && doit rm -rf * ) + + for link in "${!weak_modules_before[@]}"; do + target=${weak_modules_before[$link]} + + doit mkdir -p "$(dirname $link)" + doit ln -sf $target $link + done +} + # global_link_state_announce_changes: # Takes kernel release # Reads the given kernel's weak symlinks state, compares to the saved, @@ -653,19 +689,22 @@ global_link_state_announce_changes() { # to the current requirements RPM will track existing of only one version # of extra/ module (no same extra/ modules for different kernels). remove_modules() { - update_modules remove_weak_links + local no_fallback="" + + update_modules remove_weak_links $no_fallback } # add_modules: # Read in a list of modules from stdinput and process them for compatibility # with installed kernels under /lib/modules. add_modules() { - update_modules add_weak_links + update_modules add_weak_links do_fallback } add_kernel() { local krel=${1:-$(uname -r)} local tmp + local no_fallback="" tmp=$(mktemp -p $tmpdir) @@ -675,7 +714,7 @@ add_kernel() { exit 1 fi - for k in $(find_kernels_with_extra | rpmsort -r); do + for k in $(find_kernels_with_extra | rpmsort); do [[ "$krel" == "$k" ]] && continue find_modules $k extra >> $tmp done @@ -684,7 +723,7 @@ add_kernel() { read_modules_list < $tmp rm -f $tmp - update_modules_for_krel $krel add_weak_links + update_modules_for_krel $krel add_weak_links $no_fallback } remove_kernel() { diff --git a/SPECS/kmod.spec b/SPECS/kmod.spec index 70fbf01..fa99462 100644 --- a/SPECS/kmod.spec +++ b/SPECS/kmod.spec @@ -1,6 +1,6 @@ Name: kmod Version: 20 -Release: 15%{?dist} +Release: 15%{?dist}.1 Summary: Linux kernel module management utilities Group: System Environment/Kernel @@ -128,6 +128,10 @@ install -m 0644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/depmod.d/dist.conf %{_libdir}/libkmod.so %changelog +* Wed Jul 12 2017 Yauheni Kaliuta - 20-15.el7_4.1 +- weak-modules: fallback weak-modules state if incompatible installed + Resolves: rhbz#1469990 + * Fri May 12 2017 Yauheni Kaliuta - 20-15 - weak-modules: install weak link even if there is same name in extra. Resolves: rhbz#1450003