Date: Sunday, May 27, 2018 @ 18:57:50
  Author: seblu
Revision: 325046

upgpkg: dkms 2.5-2

- implement FS#52901 (module dep ordering)
- support BUILD_EXCLUSIVE_KERNEL

Modified:
  dkms/trunk/PKGBUILD
  dkms/trunk/hook.sh

----------+
 PKGBUILD |    6 +-
 hook.sh  |  133 +++++++++++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 102 insertions(+), 37 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD    2018-05-26 23:25:31 UTC (rev 325045)
+++ PKGBUILD    2018-05-27 18:57:50 UTC (rev 325046)
@@ -3,8 +3,8 @@
 # Contributor: Balwinder S "bsd" Dheeman (bdheeman AT gmail.com)
 
 pkgname=dkms
-pkgver=2.6.1
-pkgrel=1
+pkgver=2.5
+pkgrel=2
 pkgdesc='Dynamic Kernel Modules System'
 arch=('any')
 url='https://github.com/dell/dkms'
@@ -25,7 +25,7 @@
 md5sums=('SKIP'
          '90f1486e0af9aab85e8c60d456802c63'
          '2e8ffd0c2ddec02872d0234befd129fd'
-         'f1ea074ef22d1afe855a1eb63233566b'
+         'acdc173fed3cfe3b109d1e08f24a0d81'
          'd3b91ef709f567a375f4bbdbd3291d2b')
 
 prepare() {

Modified: hook.sh
===================================================================
--- hook.sh     2018-05-26 23:25:31 UTC (rev 325045)
+++ hook.sh     2018-05-27 18:57:50 UTC (rev 325046)
@@ -23,31 +23,40 @@
        "$@" > /dev/null
 }
 
-# check kernel is valid for action
-# it means kernel and its headers are installed
-# $1: kernel version
-check_kernel() {
-       local kver="$1"; shift
-       if [[ ! -d "$install_tree/$kver/kernel" ]]; then
-               echo "==> No kernel $kver modules. You must install them to use 
DKMS!"
-               return 1
-       elif [[ ! -d "$install_tree/$kver/build/include" ]]; then
-               echo "==> No kernel $kver headers. You must install them to use 
DKMS!"
-               return 1
-       fi
+# check whether the dependencies of a module are installed
+# $1: module name/module version
+# $2: kernel version
+check_dependency() {
+       local -a BUILD_DEPENDS
+       readarray -t BUILD_DEPENDS <<<$(source 
"$source_tree/${1/\//-}/dkms.conf"; printf '%s\n' "${BUILD_DEPENDS[@]}")
+       [[ -z ${BUILD_DEPENDS[@]} ]] && unset BUILD_DEPENDS
+       local mod
+       for mod in "${BUILD_DEPENDS[@]}"; do
+               if ! [[ "$(dkms status -m "$mod" -k "$2")" =~ 
:[[:space:]]installed$ ]]; then
+                       return 1
+               fi
+       done
        return 0
 }
 
+# check whether the modules should be built with this kernel version
+# $1: module name/module version
+# $2: kernel version
+check_buildexclusive() {
+       local BUILD_EXCLUSIVE_KERNEL
+       readarray -t BUILD_EXCLUSIVE_KERNEL <<<$(source 
"$source_tree/${1/\//-}/dkms.conf"; printf '%s\n' "$BUILD_EXCLUSIVE_KERNEL")
+       [[ "$2" =~ $BUILD_EXCLUSIVE_KERNEL ]]
+}
+
 # handle actions on module addition/upgrade/removal
 # $1: module name
 # $2: module version
-# $3: dkms action
 parse_module() {
        pushd "$install_tree" >/dev/null
        local path
        for path in */build/; do
                local kver="${path%%/*}"
-               dkms_register "$1" "$2" "$kver" "$3"
+               dkms_register "$1" "$2" "$kver"
        done
        popd >/dev/null
 }
@@ -54,34 +63,82 @@
 
 # handle actions on kernel addition/upgrade/removal
 # $1: kernel version
-# $2: dkms action
 parse_kernel() {
        local path
        for path in "$source_tree"/*-*/dkms.conf; do
                if [[ -f "$path" && "$path" =~ 
^$source_tree/([^/]+)-([^/]+)/dkms\.conf$ ]]; then
-                       dkms_register "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" 
"$1" "$2"
+                       dkms_register "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" 
"$1"
                fi
        done
 }
 
-# register a dkms call
+# register a dkms module to install/remove
 # this function suppress echo call for a module
-# $1: module name, $2: module version, $3: kernel version, $4: action
+# $1: module name, $2: module version, $3: kernel version
 dkms_register() {
-       DKMS_ACTION["$1/$2/$3"]="$4"
+       DKMS_MODULES["$1/$2/$3"]=''
 }
 
-# run registered dkms commands
-dkms_run() {
+# install registered modules
+dkms_install() {
        local nvk mod kver
-       for nvk in "${!DKMS_ACTION[@]}"; do
+       local -i retry=1
+
+       while (( $retry > 0 )); do
+               retry=0
+               for nvk in "${!DKMS_MODULES[@]}"; do
+                       mod=${nvk%/*}
+                       kver=${nvk##*/}
+                       # do not build excluded modules
+                       if ! check_buildexclusive "$mod" "$kver"; then
+                               unset DKMS_MODULES[$nvk]
+                               continue
+                       # skip modules with missing kernel headers
+                       elif [[ ! -d "$install_tree/$kver/build/include" ]]; 
then
+                               DKMS_MODULES[$nvk]="Missing kernel headers"
+                               continue
+                       # skip modules with missing kernel package
+                       elif [[ ! -d "$install_tree/$kver/kernel" ]]; then
+                               DKMS_MODULES[$nvk]="Missing kernel modules tree"
+                               continue
+                       # postone modules with missing dependencies
+                       elif ! check_dependency "$mod" "$kver"; then
+                               DKMS_MODULES[$nvk]="Missing dependency"
+                               continue
+                       fi
+                       # give it a try dkms
+                       run dkms install "$mod" -k "$kver"
+                       unset DKMS_MODULES[$nvk]
+                       # maybe this module was a dep of another, so we retry
+                       retry=1
+               done
+       done
+}
+
+# remove registered modules when built/installed
+dkms_remove() {
+       local nvk mod kver
+       for nvk in "${!DKMS_MODULES[@]}"; do
                mod=${nvk%/*}
                kver=${nvk##*/}
-               check_kernel "$kver" || continue
-               run dkms "${DKMS_ACTION[$nvk]}" "$mod" -k "$kver"
+               state=$(dkms status -m "$mod" -k "$kver")
+               if [[ "$state" =~ :[[:space:]](built|installed)$ ]]; then
+                       run dkms remove "$mod" -k "$kver"
+               fi
+               unset DKMS_MODULES[$nvk]
        done
 }
 
+# show information about failed modules
+show_errors() {
+       local nvk mod kver
+       for nvk in "${!DKMS_MODULES[@]}"; do
+               mod=${nvk%/*}
+               kver=${nvk##*/}
+               echo "==> Unable to $DKMS_ACTION module $mod for kernel $kver: 
${DKMS_MODULES[$nvk]}."
+       done
+}
+
 # emulated program entry point
 main() {
        [[ -n "$DKMS_ALPM_HOOK_DEBUG" ]] && set -x
@@ -92,11 +149,16 @@
                exit 1
        fi
 
-       # check args count
-       if (( $# < 1 )); then
-               echo "usage: ${0##*/} dkms-arguments" >&2
-               exit 1
-       fi
+       # register DKMS action
+       case "$1" in
+               install|remove)
+                       local -r DKMS_ACTION="$1"
+                       ;;
+               *)
+                       echo "usage: ${0##*/} install|remove" >&2
+                       exit 1
+                       ;;
+       esac
 
        # dkms path from framework config
        # note: the alpm hooks which trigger this script use static path
@@ -113,20 +175,23 @@
                fi
        done
 
-       # Storage for DKMS action to run
-       declare -A DKMS_ACTION
+       # storage for DKMS modules to install/remove
+       # we use associate arrays to prevent duplicate
+       declare -A DKMS_MODULES
 
        # parse stdin paths to guess what do do
        while read -r path; do
                if [[ "/$path" =~ ^$source_tree/([^/]+)-([^/]+)/dkms\.conf$ ]]; 
then
-                       parse_module "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" 
"$@"
+                       parse_module "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}"
                elif [[ "/$path" =~ ^$install_tree/([^/]+)/ ]]; then
-                       parse_kernel "${BASH_REMATCH[1]}" "$@"
+                       parse_kernel "${BASH_REMATCH[1]}"
                fi
        done
 
-       dkms_run
+       dkms_$DKMS_ACTION
 
+       show_errors
+
        return 0
 }
 

Reply via email to