# Bug fixes and features # 1. Sort modules, randomly reversing for BUILD_DEPENDS # 2. Omit --no-depmod for a dependency of a to be installed module # 3. Omit --no-depmod when only one module is updated # 4. install ignores -D --- hook.sh 2020-05-27 21:22:22.015405834 -0400 +++ alpm-hook 2020-05-28 00:54:19.266318832 -0400 @@ -83,15 +83,70 @@ DKMS_MODULES["$1/$2/$3"]='' } +# Reverse sorting at random to ensure that +# bug reports are filed for modules with +# dependencies that lack BUILD_DEPENDS +init_sort_modules() { + if [ "$RANDOM" -lt 16384 ]; then + SORT_OPTION_R='-r' + else + SORT_OPTION_R='' + fi +} + +# module list from associative array in sorted order +# input: associative array keys DKMS_MODULES in random order +# output: array DKMS_MODULESA in order +sort_modules() { + DKMS_MODULESA=() + if [ "${#DKMS_MODULES[@]}" -gt 0 ]; then + readarray -t DKMS_MODULESA < <(printf '%s\n' "${!DKMS_MODULES[@]}" | sort -n $SORT_OPTION_R) + fi +} + +# $1: module name, $2: module version +# output: lines of dkms.conf BUILD_DEPENDS array +get_deps() { ( + source "$source_tree/$1-$2/dkms.conf" + printf '%s\n' "${BUILD_DEPENDS[@]}" +) } + # install registered modules dkms_install() { local nvk mod mver kver local -i retry=1 local -A dmods=() + # build dependency map + # Works with deps in any order + local -A DKMS_DEPMAP=() + local -A dmodsct=() + for nvk in "${!DKMS_MODULES[@]}"; do + [[ "$nvk" =~ ([^/]+)/([^/]+)/(.+) ]] + mod="${BASH_REMATCH[1]}" + #mver="${BASH_REMATCH[2]}" + #kver="${BASH_REMATCH[3]}" + DKMS_DEPMAP["$mod"]='--no-depmod' + dmodsct[$mod]='' + done + if [ "${#dmodsct[@]}" -le 1 ]; then + unset DKMS_DEPMAP + else + for nvk in "${!DKMS_MODULES[@]}"; do + [[ "$nvk" =~ ([^/]+)/([^/]+)/(.+) ]] + mod="${BASH_REMATCH[1]}" + mver="${BASH_REMATCH[2]}" + for kver in $(get_deps "$mod" "$mver"); do + DKMS_DEPMAP["$kver"]='' + done + done + fi + unset dmodsct + while (( $retry > 0 )); do retry=0 - for nvk in "${!DKMS_MODULES[@]}"; do + sort_modules + for nvk in "${DKMS_MODULESA[@]}"; do [[ "$nvk" =~ ([^/]+)/([^/]+)/(.+) ]] mod="${BASH_REMATCH[1]}" mver="${BASH_REMATCH[2]}" @@ -114,19 +169,21 @@ continue fi # give it a try dkms - run dkms install --no-depmod -m "$mod" -v "$mver" -k "$kver" - dmods[$kver]='' + run dkms install ${DKMS_DEPMAP[$mod]} -m "$mod" -v "$mver" -k "$kver" + if (( $? == 0 )) && [ -z "${DKMS_DEPMAP[$mod]}" ]; then + unset dmods[$kver] + else + dmods[$kver]='' + fi unset DKMS_MODULES[$nvk] # maybe this module was a dep of another, so we retry retry=1 done done # run depmod later for performance improvments - if (( $DKMS_DEPMOD )); then - for kver in "${!dmods[@]}"; do - run depmod "$kver" - done - fi + for kver in "${!dmods[@]}"; do + run depmod "$kver" + done } # remove registered modules when built/installed @@ -134,7 +191,8 @@ dkms_remove() { local nvk mod mver kver state local -A dmods=() - for nvk in "${!DKMS_MODULES[@]}"; do + sort_modules + for nvk in "${DKMS_MODULESA[@]}"; do [[ "$nvk" =~ ([^/]+)/([^/]+)/(.+) ]] mod="${BASH_REMATCH[1]}" mver="${BASH_REMATCH[2]}" @@ -168,7 +226,8 @@ # show information about failed modules show_errors() { local nvk mod kver - for nvk in "${!DKMS_MODULES[@]}"; do + sort_modules + for nvk in "${DKMS_MODULESA[@]}"; do mod=${nvk%/*} kver=${nvk##*/} echo "==> Unable to $DKMS_ACTION module $mod for kernel $kver: ${DKMS_MODULES[$nvk]}." @@ -248,4 +307,5 @@ return 0 } +init_sort_modules main "$@"