diff -Naur dkms-3.0.10/.github/workflows/tests.yml dkms-3.0.11/.github/workflows/tests.yml
--- dkms-3.0.10/.github/workflows/tests.yml	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/.github/workflows/tests.yml	2023-04-27 17:06:25.000000000 +0200
@@ -1,6 +1,11 @@
 name: Run tests
 
-on: [push, pull_request]
+on:
+  # Build at 23:00 every Sunday
+  schedule:
+    - cron: "0 23 * * 1"
+  pull_request:
+  push:
 
 jobs:
   test-distributions:
@@ -8,26 +13,20 @@
     strategy:
       matrix:
         distro:
-          - {name: "alpine", tag: "3.14", variant: "-lts"}
-          - {name: "alpine", tag: "3.14", variant: "-virt"}
-          - {name: "alpine", tag: "3.13", variant: "-lts"}
-          - {name: "alpine", tag: "3.13", variant: "-virt"}
-          - {name: "alpine", tag: "3.12", variant: "-lts"}
-          - {name: "alpine", tag: "3.12", variant: "-virt"}
-          - {name: "alpine", tag: "3.11", variant: "-lts"}
-          - {name: "alpine", tag: "3.11", variant: "-virt"}
-          - {name: "alpine", tag: "3.10", variant: "-vanilla"}
-          - {name: "alpine", tag: "3.10", variant: "-virt"}
+          - {name: "alpine", tag: "3.17", variant: "-lts"}
+          - {name: "alpine", tag: "3.17", variant: "-virt"}
+          - {name: "alpine", tag: "3.16", variant: "-lts"}
+          - {name: "alpine", tag: "3.16", variant: "-virt"}
+          - {name: "alpine", tag: "3.15", variant: "-lts"}
+          - {name: "alpine", tag: "3.15", variant: "-virt"}
           - {name: "archlinux", tag: "latest"}
           - {name: "archlinux", tag: "latest", variant: "-lts"}
           - {name: "archlinux", tag: "latest", variant: "-zen"}
           - {name: "centos", tag: "7"}
-          - {name: "almalinux", tag: "8"}
           - {name: "almalinux", tag: "9"}
+          - {name: "almalinux", tag: "8"}
           - {name: "debian", tag: "11"}
           - {name: "debian", tag: "10"}
-          - {name: "debian", tag: "9"}
-          - {name: "debian", tag: "8"}
           - {name: "ubuntu", tag: "22.04"}
           - {name: "ubuntu", tag: "20.04"}
           - {name: "ubuntu", tag: "18.04"}
@@ -41,7 +40,7 @@
     - name: Install Alpine dependencies
       if: matrix.distro.name == 'alpine'
       run: |
-        apk --no-cache --update add bash gcc linux${{ matrix.distro.variant }} linux${{ matrix.distro.variant }}-dev make openssl
+        apk --no-cache --update add bash gcc linux${{ matrix.distro.variant }} linux${{ matrix.distro.variant }}-dev make openssl coreutils
 
     - name: Install Arch Linux dependencies
       if: matrix.distro.name == 'archlinux'
@@ -61,13 +60,8 @@
     - name: Install Debian dependencies
       if: matrix.distro.name == 'debian'
       run: |
-        EXTRA_ARGS=''
-        if [ "${{ matrix.distro.tag }}" = 8 ] ; then
-            # repo key is expired
-            EXTRA_ARGS="--allow-unauthenticated"
-        fi
         apt-get update -q
-        apt-get install -qy $EXTRA_ARGS gcc make linux-headers-amd64 linux-image-amd64 openssl
+        apt-get install -qy gcc make linux-headers-amd64 linux-image-amd64 openssl
 
     - name: Install Ubuntu dependencies
       if: matrix.distro.name == 'ubuntu'
@@ -102,9 +96,7 @@
 
     - name: Run tests
       run: |
-        if [ "${{ matrix.distro.name }}" = alpine ] && ([ "${{ matrix.distro.tag }}" = 3.10 ] || [ "${{ matrix.distro.variant }}" = "-lts" ]); then
-            ./run_test.sh --no-signing-tool
-        elif [ "${{ matrix.distro.name }}" = debian ] && [ "${{ matrix.distro.tag }}" = 8 ]; then
+        if [ "${{ matrix.distro.name }}" = alpine ] && [ "${{ matrix.distro.variant }}" = "-lts" ]; then
             ./run_test.sh --no-signing-tool
         else
             ./run_test.sh
diff -Naur dkms-3.0.10/Makefile dkms-3.0.11/Makefile
--- dkms-3.0.10/Makefile	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/Makefile	2023-04-27 17:06:25.000000000 +0200
@@ -1,7 +1,7 @@
-RELEASE_DATE := "03 January 2023"
+RELEASE_DATE := "27 April 2023"
 RELEASE_MAJOR := 3
 RELEASE_MINOR := 0
-RELEASE_MICRO := 10
+RELEASE_MICRO := 11
 RELEASE_NAME := dkms
 RELEASE_VERSION := $(RELEASE_MAJOR).$(RELEASE_MINOR).$(RELEASE_MICRO)
 RELEASE_STRING := $(RELEASE_NAME)-$(RELEASE_VERSION)
diff -Naur dkms-3.0.10/README.md dkms-3.0.11/README.md
--- dkms-3.0.10/README.md	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/README.md	2023-04-27 17:06:25.000000000 +0200
@@ -99,20 +99,19 @@
 This requires the `openssl` command to be present on the system.
 
 Private key and certificate are auto generated the first time DKMS is run and
-placed in `/var/lib/dkms`. These certificate files can be prepulated with your
-own certificates of choice.
+placed in `/var/lib/dkms`. These certificate files can be pre-populated with
+your own certificates of choice.
 
 The location as well can be changed by setting the appropriate variables in
-`/etc/dkms/framework.conf`. For example, to awllow usage of the system default
-Debian and Ubuntu `update-secureboot-policy` set the configuration file as
-follows:
+`/etc/dkms/framework.conf`. For example, to allow usage of the system default
+Ubuntu `update-secureboot-policy` set the configuration file as follows:
 ```
-mok_signing_key="/var/lib/shim-signed/mok/MOK.der"
-mok_certificate="/var/lib/shim-signed/mok/MOK.priv"
+mok_signing_key="/var/lib/shim-signed/mok/MOK.priv"
+mok_certificate="/var/lib/shim-signed/mok/MOK.der"
 ```
 
 The paths specified in `mok_signing_key`, `mok_certificate` and `sign_file` can
-use the variable `${kernelver}` to represent the target kernel version. 
+use the variable `${kernelver}` to represent the target kernel version.
 ```
 sign_file="/lib/modules/${kernelver}/build/scripts/sign-file"
 ```
@@ -162,11 +161,13 @@
 
 ![Enroll the key(s)?](/images/mok-key-4.png)
 
-After this, enter the password you set up with `mokutil --import` in the previous step:
+After this, enter the password you set up with `mokutil --import` in the
+previous step:
 
 ![Enroll the key(s)?](/images/mok-key-5.png)
 
-At this point you are done, select "OK" and the computer will reboot trusting the key for your modules:
+At this point you are done, select "OK" and the computer will reboot trusting
+the key for your modules:
 
 ![Perform MOK management](/images/mok-key-6.png)
 
diff -Naur dkms-3.0.10/debian/changelog dkms-3.0.11/debian/changelog
--- dkms-3.0.10/debian/changelog	2023-03-31 14:01:26.000000000 +0200
+++ dkms-3.0.11/debian/changelog	2023-04-27 18:12:51.000000000 +0200
@@ -1,3 +1,24 @@
+dkms (3.0.11-1) experimental; urgency=medium
+
+  * New upstream release.
+    - Adds BUILD_EXCLUSIVE_{CONFIG,_KERNEL_{MIN,MAX}}.  (Closes: #911665)
+    - Fixes BUILD_EXCLUSIVE matches propagating as error.  (Closes: #1031561)
+  * Drop patches that were applied upstream.
+  * Avoid unnecessary rpm comands on Debian based systems.  (Closes: #741399)
+
+ -- Andreas Beckmann <anbe@debian.org>  Thu, 27 Apr 2023 18:12:51 +0200
+
+dkms (3.0.10-9) experimental; urgency=medium
+
+  * Add dkms-test-dkms package with trivial kernel module for dkms tests.
+  * New autopkgtest: Install some-dkms after linux-headers.
+  * New autopkgtest: Install linux-headers after some-dkms.
+  * New autopkgtest: Install some-dkms after linux-image w/o linux-headers.
+  * New autopkgtest: Install linux-image after some-dkms w/o linux-headers.
+  * Upload to experimental.
+
+ -- Andreas Beckmann <anbe@debian.org>  Fri, 31 Mar 2023 14:19:59 +0200
+
 dkms (3.0.10-8) unstable; urgency=medium
 
   * Disable tests broken by fix-builtin-archive-dkms-coinstallation.patch.
@@ -8,7 +29,7 @@
   * Clean up /boot/*.old-dkms on upgrades from bullseye.  (Closes: #717584)
   * Clean up obsolete /etc/dkms/sign_helper.sh on upgrades. (Closes: #1019563)
   * dkms-autopkgtest: Try to 'dkms install' its BUILD_DEPENDS before testing a
-    module. (Single level only, without recursion.)
+    module. (Single level only, without recursion.)  (Closes: #1034303)
   * Fix fallback value for BUILD_MODULE_NAME[0].  (Closes: #651973)
   * dkms.8: Clarify 'dkms add' arguments.  (Closes: #704917)
   * Print a warning if /proc is not mounted.  (Closes: #810665, #968074)
diff -Naur dkms-3.0.10/debian/control dkms-3.0.11/debian/control
--- dkms-3.0.10/debian/control	2023-03-31 14:01:26.000000000 +0200
+++ dkms-3.0.11/debian/control	2023-04-27 18:12:51.000000000 +0200
@@ -13,6 +13,7 @@
 Vcs-Git: https://salsa.debian.org/debian/dkms.git
 Vcs-Browser: https://salsa.debian.org/debian/dkms
 Rules-Requires-Root: no
+Testsuite: autopkgtest-pkg-dkms
 
 Package: dkms
 Architecture: all
@@ -54,3 +55,13 @@
  .
  This package provides a debhelper add-on 'dkms' that simplifies packaging of
  dkms kernel module source packages.
+
+Package: dkms-test-dkms
+Architecture: all
+Depends:
+ ${misc:Depends},
+Description: trivial dkms test kernel module
+ This package provides the dkms source code for the dkms-test kernel module.
+ .
+ This package is only intended for ci tests and not expected to be installed
+ on regular systems
diff -Naur dkms-3.0.10/debian/dkms-test-dkms.dkms dkms-3.0.11/debian/dkms-test-dkms.dkms
--- dkms-3.0.10/debian/dkms-test-dkms.dkms	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/debian/dkms-test-dkms.dkms	2023-04-27 18:12:51.000000000 +0200
@@ -0,0 +1 @@
+test/dkms_test-1.0/dkms.conf
diff -Naur dkms-3.0.10/debian/dkms-test-dkms.install dkms-3.0.11/debian/dkms-test-dkms.install
--- dkms-3.0.10/debian/dkms-test-dkms.install	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/debian/dkms-test-dkms.install	2023-04-27 18:12:51.000000000 +0200
@@ -0,0 +1 @@
+test/dkms_test-1.0	usr/src/
diff -Naur dkms-3.0.10/debian/patches/series dkms-3.0.11/debian/patches/series
--- dkms-3.0.10/debian/patches/series	2023-03-31 14:01:26.000000000 +0200
+++ dkms-3.0.11/debian/patches/series	2023-04-27 18:12:51.000000000 +0200
@@ -1,14 +1,3 @@
-0001-default-built_module_name-0-to-PACKAGE_NAME.patch
-0002-man-clarify-dkms-add-arguments.patch
-0003-print-a-warning-if-proc-is-not-mounted.patch
-0004-use-echo-n-as-fallback-for-log_daemon_msg.patch
-0005-use-log_action_msg-instead-of-log_daemon_msg-w-o-log.patch
-0006-dkms_autoinstaller-skip-autoinstall-if-headers-are-m.patch
-0007-prepare_build-use-return-code-77-if-skipping-due-to-.patch
-
 messaging.patch
-version-sort.patch
-BUILD_EXCLUSIVE_CONFIG.patch
-spelling.patch
-reinstate-enroll.patch
 fix-builtin-archive-dkms-coinstallation.patch
+do-not-perform-rpm-queries-on-Debian-Ubuntu-Arch-bas.patch
diff -Naur dkms-3.0.10/debian/rules dkms-3.0.11/debian/rules
--- dkms-3.0.10/debian/rules	2023-03-31 14:01:26.000000000 +0200
+++ dkms-3.0.11/debian/rules	2023-04-27 18:12:51.000000000 +0200
@@ -21,3 +21,6 @@
 
 override_dh_auto_install:
 	$(MAKE) install-debian DESTDIR=$(CURDIR)/debian/dkms
+
+execute_after_dh_install:
+	DH_AUTOSCRIPTDIR=debian/scripts debian/scripts/dh_dkms
diff -Naur dkms-3.0.10/debian/tests/control dkms-3.0.11/debian/tests/control
--- dkms-3.0.10/debian/tests/control	2023-03-31 14:01:26.000000000 +0200
+++ dkms-3.0.11/debian/tests/control	2023-04-27 18:12:51.000000000 +0200
@@ -3,9 +3,57 @@
 Depends:
  dkms,
  openssl,
- linux-headers-generic,
+ linux-headers-generic
+ | linux-headers-rpi [armel]
+ ,
 Restrictions:
  allow-stderr,
  needs-root,
  breaks-testbed,
  skip-not-installable,
+
+# install some-dkms after linux-headers
+Test-Command: apt-get install -yf dkms-test-dkms
+Features: test-name=install_some-dkms_after_linux-headers
+Architecture: amd64
+Depends:
+ dkms,
+ linux-headers-generic,
+Restrictions:
+ allow-stderr,
+ needs-root,
+ breaks-testbed,
+
+# install linux-headers after some-dkms
+Test-Command: apt-get install -yf linux-headers-generic
+Features: test-name=install_linux-headers_after_some-dkms
+Architecture: amd64
+Depends:
+ dkms-test-dkms,
+Restrictions:
+ allow-stderr,
+ needs-root,
+ breaks-testbed,
+
+# install some-dkms after linux-image w/o linux-headers
+Test-Command: apt-get install -yf dkms-test-dkms
+Features: test-name=install_some-dkms_after_linux-image_without_linux-headers
+Architecture: amd64
+Depends:
+ dkms,
+ linux-image-generic,
+Restrictions:
+ allow-stderr,
+ needs-root,
+ breaks-testbed,
+
+# install linux-image after some-dkms w/o linux-headers
+Test-Command: apt-get install -yf linux-image-generic
+Features: test-name=install_linux-image_after_some-dkms_without_linux-headers
+Architecture: amd64
+Depends:
+ dkms-test-dkms,
+Restrictions:
+ allow-stderr,
+ needs-root,
+ breaks-testbed,
diff -Naur dkms-3.0.10/dkms.8.in dkms-3.0.11/dkms.8.in
--- dkms-3.0.10/dkms.8.in	2023-04-27 18:16:34.000000000 +0200
+++ dkms-3.0.11/dkms.8.in	2023-04-27 17:06:25.000000000 +0200
@@ -149,8 +149,8 @@
 .B --force
 option should be used to override this.
 If you pass a .rpm file, dkms will try to install that file with
-.B rpm -Uvh
-, and it will perform an
+.BR "rpm -Uvh" ,
+and it will perform an
 .B autoinstall
 action to be sure that everything is built for your kernel if the RPM installed successfully.
 .SY uninstall
@@ -429,8 +429,8 @@
 until you manually delete them.
 .SH DKMS.CONF
 When performing an
-.B add
-, a proper
+.BR add ,
+a proper
 .I dkms.conf
 file must be found. A properly formatted conf file is essential
 for communicating to
@@ -454,42 +454,16 @@
 DEST_MODULE_LOCATION[#] and STRIP[#]. When indexing these arrays when creating your
 dkms.conf, each family should start at index value 0.
 .TP
-.B MAKE[#]=
-The MAKE directive array tells DKMS which make command should be used for building your module. The default make command
-should be put into
-.B MAKE[0].
-Other entries in the MAKE array will only be used if their corresponding entry in
-.B MAKE_MATCH[#]
-matches, as a regular expression (using grep -E), the kernel that the module is being built for.
-Note that if no value is placed in
-.B MAKE_MATCH[#]
-for any
-.B MAKE[#]
-where # > 0, then that
-.B MAKE
-directive is ignored.
-.B MAKE_MATCH[0]
-is optional and if it is populated, it will be used to determine
-if MAKE[0] should be used to build the module for that kernel. If multiple
-.B MAKE_MATCH
-directives match against the kernel being built for, the last matching
-.B MAKE[#]
-will be used to build your module. If no MAKE directive is specified or if no
-MAKE_MATCH matches the kernel being built for, DKMS
-will attempt to use a generic MAKE command to build your module.
-
-KERNELRELEASE will be automatically appended to MAKE[#]. If you want to
-suppress this behavior, you can quote the make command: 'make'.
+.B PACKAGE_NAME=
+This directive is used to give the name associated with the entire package of modules. This is the same
+name that is used with the
+.B \-m
+option when building, adding, etc. and may not necessarily be the same as the MODULE_NAME. This
+directive must be present in every dkms.conf.
 .TP
-.B MAKE_MATCH[#]=
-See the above entry on
-.B MAKE[#]
-directives. This array should be populated with regular expressions which, when matched
-against the kernel being built for, will tell
-.B DKMS
-to use the corresponding make command in the
-.B MAKE[#]
-directive array to build your module.
+.B PACKAGE_VERSION=
+This directive is used to give the version associated with the entire package of modules being installed within that dkms
+package. This directive must be present in every dkms.conf.
 .TP
 .B BUILT_MODULE_NAME[#]=
 This directive gives the name of the module just after it is built. If your DKMS module
@@ -550,21 +524,58 @@
 run strip \-g against your built module to remove debug symbols from it.
 STRIP[0] is used as the default for any unset entries in the STRIP array.
 .TP
-.B PACKAGE_NAME=
-This directive is used to give the name associated with the entire package of modules. This is the same
-name that is used with the
-.B \-m
-option when building, adding, etc. and may not necessarily be the same as the MODULE_NAME. This
-directive must be present in every dkms.conf.
+.B MAKE[#]=
+The MAKE directive array tells DKMS which make command should be used for building your module. The default make command
+should be put into
+.B MAKE[0].
+Other entries in the MAKE array will only be used if their corresponding entry in
+.B MAKE_MATCH[#]
+matches, as a regular expression (using grep -E), the kernel that the module is being built for.
+Note that if no value is placed in
+.B MAKE_MATCH[#]
+for any
+.B MAKE[#]
+where # > 0, then that
+.B MAKE
+directive is ignored.
+.B MAKE_MATCH[0]
+is optional and if it is populated, it will be used to determine
+if MAKE[0] should be used to build the module for that kernel. If multiple
+.B MAKE_MATCH
+directives match against the kernel being built for, the last matching
+.B MAKE[#]
+will be used to build your module. If no MAKE directive is specified or if no
+MAKE_MATCH matches the kernel being built for, DKMS
+will attempt to use a generic MAKE command to build your module.
+
+KERNELRELEASE will be automatically appended to MAKE[#]. If you want to
+suppress this behavior, you can quote the make command: 'make'.
 .TP
-.B PACKAGE_VERSION=
-This directive is used to give the version associated with the entire package of modules being installed within that dkms
-package. This directive must be present in every dkms.conf.
+.B MAKE_MATCH[#]=
+See the above entry on
+.B MAKE[#]
+directives. This array should be populated with regular expressions which, when matched
+against the kernel being built for, will tell
+.B DKMS
+to use the corresponding make command in the
+.B MAKE[#]
+directive array to build your module.
 .TP
 .B CLEAN=
 CLEAN specifies the make clean command to be used to clean up both before and after building the
 module. If unset, it is assumed to be "make clean".
 .TP
+.B NO_WEAK_MODULES=
+The
+.B NO_WEAK_MODULES
+parameter prevents dkms from creating a symlink into the weak-updates directory, which is the
+default on Red Hat derivatives. The weak modules facility was designed to eliminate the need to
+rebuild kernel modules when kernel upgrades occur and relies on the symbols within the kABI.
+
+Fedora does not guaranteed a stable kABI so it should be disabled in the specific module override by setting it to "yes". For example, for an Nvidia DKMS module you would set the following in /etc/dkms/nvidia.conf:
+
+NO_WEAK_MODULES="yes"
+.TP
 .B OBSOLETE_BY=
 This directive allows you to specify a kernel version that obsoletes the necessity for this
 particular DKMS module. This can be specified as a particular upstream kernel or an ABI
@@ -648,15 +659,42 @@
 does not the satisfy the constraints of any other
 .B BUILD_EXCLUSIVE_*
 directive), the dkms build will error out with exit code 77.
+Note that dkms autoinstall will ignore this type of error condition and simply
+skip the respective modules.
 For example, if you set it as ="^2\.4.*", your module would not be built for 2.6
 or later kernels.
 .TP
+.B BUILD_EXCLUSIVE_KERNEL_MIN=
+and
+.B BUILD_EXCLUSIVE_KERNEL_MAX=
+These optional directives allow one to specify the minimal and maximal kernel
+versions supported by the module. If one (or both) of these are defined, the
+module will not be built for kernels outside the specified version limits.
+For example, if you set
+.B BUILD_EXCLUSIVE_KERNEL_MIN
+as "=3.5", your module would be built for e.g. "3.5-rc2", "3.6.18" or other
+later versions but not for "3.4.999" or earlier kernels.
+Similarly, if you set
+.B BUILD_EXCLUSIVE_KERNEL_MAX
+as ="4.12", your module would be built for e.g. "4.11.999", "3.9-rc5" or
+other earlier versions, but not for "4.12-rc1" or later kernels.
+.TP
 .B BUILD_EXCLUSIVE_ARCH=
 This optional directive functions very similarly to
 .B BUILD_EXCLUSIVE_KERNEL
 except that it matches against the kernel architecture. For example, if you set
 it to ="i.86", your module would not be built for ia32e, x86_64, amd64, s390, etc.
 .TP
+.B BUILD_EXCLUSIVE_CONFIG=
+This optional directive allows you to specify a space separated list of
+kernel configuration options ("CONFIG_FOO") that must be enabled in the
+targeted kernels ".config" file (either to be compiled in or to be built
+as a module) or absent (if prefixed with an exclamation mark, e.g.
+"!CONFIG_BAR") in order to build the module.
+For example, if you set it as ="CONFIG_PCI !CONFIG_PREEMPT_RT", your module
+would only be built for kernels that have PCI enabled, but the RT patchset
+disabled.
+.TP
 .B POST_ADD=
 The name of the script to be run after an
 .B add
@@ -705,8 +743,8 @@
 .B $kernel_source_dir
 This variable holds the value of the location of your kernel source directory. Usually, this
 will be
-.I /lib/modules/$kernelver/build
-, unless otherwise specified with the
+.IR /lib/modules/$kernelver/build ,
+unless otherwise specified with the
 .B \-\-kernelsourcedir
 option.
 .SH DKMS.CONF OVERRIDES
diff -Naur dkms-3.0.10/dkms.in dkms-3.0.11/dkms.in
--- dkms-3.0.10/dkms.in	2023-04-27 18:16:34.000000000 +0200
+++ dkms-3.0.11/dkms.in	2023-04-27 18:16:44.000000000 +0200
@@ -27,8 +27,8 @@
 # The last group of variables has been deprecated
 readonly dkms_conf_variables="CLEAN PACKAGE_NAME
    PACKAGE_VERSION POST_ADD POST_BUILD POST_INSTALL POST_REMOVE PRE_BUILD
-   PRE_INSTALL BUILD_DEPENDS BUILD_EXCLUSIVE_KERNEL BUILD_EXCLUSIVE_ARCH
-   BUILD_EXCLUSIVE_CONFIG
+   PRE_INSTALL BUILD_DEPENDS BUILD_EXCLUSIVE_ARCH BUILD_EXCLUSIVE_CONFIG
+   BUILD_EXCLUSIVE_KERNEL BUILD_EXCLUSIVE_KERNEL_MIN BUILD_EXCLUSIVE_KERNEL_MAX
    build_exclude OBSOLETE_BY MAKE MAKE_MATCH
    PATCH PATCH_MATCH patch_array BUILT_MODULE_NAME
    built_module_name BUILT_MODULE_LOCATION built_module_location
@@ -278,6 +278,11 @@
             kernelver[0]=$(uname -r)
         fi
         if [[ ! $arch ]]; then
+            case "$running_distribution" in
+                debian* | ubuntu* | arch*)
+                    arch[0]=$(uname -m)
+                    ;;
+                *)
             kernelver_rpm=$(rpm -qf "/lib/modules/$kernelver" 2>/dev/null | \
             grep -v "not owned by any package" | grep kernel | head -n 1)
             if ! arch[0]=$(rpm -q --queryformat "%{ARCH}" "$kernelver_rpm" 2>/dev/null); then
@@ -286,6 +291,8 @@
                     arch[0]="ia32e"
                 fi
             fi
+                ;;
+            esac
         fi
     fi
 
@@ -500,6 +507,18 @@
     pre_install="$PRE_INSTALL"
     obsolete_by="$OBSOLETE_BY"
 
+    # Fail if no PACKAGE_NAME
+    if [[ ! $package_name ]]; then
+        echo $"dkms.conf: Error! No 'PACKAGE_NAME' directive specified.">&2
+        return_value=1
+    fi
+
+    # Fail if no PACKAGE_VERSION
+    if [[ ! $package_version ]]; then
+        echo $"dkms.conf: Error! No 'PACKAGE_VERSION' directive specified.">&2
+        return_value=1
+    fi
+
     # Set module naming/location arrays
     local index array_size=0 s
     for s in ${#BUILT_MODULE_NAME[@]} \
@@ -528,7 +547,7 @@
 
         # If unset, set by defaults
         [[ ! ${built_module_name[$index]} ]] && \
-            ((${#DEST_MODULE_LOCATION[@]} == 1)) && \
+            ((array_size == 1)) && \
             built_module_name[$index]=$PACKAGE_NAME
         [[ ! ${dest_module_name[$index]} ]] && \
             dest_module_name[$index]=${built_module_name[$index]}
@@ -558,7 +577,7 @@
                 ;;
         esac
 
-        # Override location for specific kernels
+        # Override location for specific distributions
         dest_module_location[$index]="$(override_dest_module_location ${dest_module_location[$index]})"
 
         # Fail if no DEST_MODULE_LOCATION
@@ -566,7 +585,8 @@
             echo $"dkms.conf: Error! No 'DEST_MODULE_LOCATION' directive specified for record #$index.">&2
             return_value=1
         fi
-            # Fail if bad DEST_MODULE_LOCATION
+
+        # Fail if bad DEST_MODULE_LOCATION
         case ${DEST_MODULE_LOCATION[$index]} in
             /kernel*)
                 ;;
@@ -582,6 +602,11 @@
         esac
     done
 
+    # Warn if no modules are specified
+    if ((array_size == 0)); then
+        echo $"dkms.conf: Warning! Zero modules specified." >&2
+    fi
+
     # Get the correct make command
     [[ ${MAKE_MATCH[0]} ]] || make_command="${MAKE[0]}"
     for ((index=0; index < ${#MAKE[@]}; index++)); do
@@ -622,35 +647,19 @@
 
     # Set build_exclude
     [[ $BUILD_EXCLUSIVE_KERNEL && ! $1 =~ $BUILD_EXCLUSIVE_KERNEL ]] && build_exclude="yes"
+    [[ $BUILD_EXCLUSIVE_KERNEL_MIN && "$(VER "$1")" < "$(VER "$BUILD_EXCLUSIVE_KERNEL_MIN")" ]] && build_exclude="yes"
+    [[ $BUILD_EXCLUSIVE_KERNEL_MAX && "$(VER "$1")" > "$(VER "$BUILD_EXCLUSIVE_KERNEL_MAX")" ]] && build_exclude="yes"
     [[ $BUILD_EXCLUSIVE_ARCH && ! $2 =~ $BUILD_EXCLUSIVE_ARCH ]] && build_exclude="yes"
-    if [[ $BUILD_EXCLUSIVE_CONFIG && -e $kernel_source_dir/.config ]]; then
+    if [[ $BUILD_EXCLUSIVE_CONFIG && -e "${kernel_config}" ]]; then
         local kconf
         for kconf in $BUILD_EXCLUSIVE_CONFIG ; do
             case "$kconf" in
-                !*) grep -q -E "^${kconf#!}=[ym]" $kernel_source_dir/.config && build_exclude="yes" ;;
-                *)  grep -q -E "^${kconf}=[ym]" $kernel_source_dir/.config || build_exclude="yes" ;;
+                !*) grep -q "^${kconf#!}=[ym]" "${kernel_config}" && build_exclude="yes" ;;
+                *)  grep -q "^${kconf}=[ym]" "${kernel_config}" || build_exclude="yes" ;;
             esac
         done
     fi
 
-    # Fail if absolutely no DEST_MODULE_LOCATION
-    if ((${#dest_module_location[@]} == 0)); then
-        echo $"dkms.conf: Error! No 'DEST_MODULE_LOCATION' directive specified." >&2
-        return_value=1
-    fi
-
-    # Fail if no PACKAGE_NAME
-    if [[ ! $package_name ]]; then
-        echo $"dkms.conf: Error! No 'PACKAGE_NAME' directive specified.">&2
-        return_value=1
-    fi
-
-    # Fail if no PACKAGE_VERSION
-    if [[ ! $package_version ]]; then
-        echo $"dkms.conf: Error! No 'PACKAGE_VERSION' directive specified.">&2
-        return_value=1
-    fi
-
     # Set clean
     [[ $clean ]] || clean="make clean"
 
@@ -729,7 +738,7 @@
     local lib_tree="$install_tree/$1" res=
     echo $"Running module version sanity check."
     local i=0
-    if [ -n $3 ]; then
+    if [ -n "$3" ]; then
         # Magic split into array syntax saves trivial awk and cut calls.
         local -a obs=(${3//-/ })
         local -a my=(${1//-/ })
@@ -786,13 +795,17 @@
                 $"You may override by specifying --force."
             return 1
         fi
-    elif [[ "${cmp_res}" = "="* ]]; then
+    elif [[ "${cmp_res}" = "==" ]]; then
         if [[ ! "$force" ]]; then
-            echo $"Module version $(get_module_verinfo "${dkms_module}" | head -n 1) for $4${module_suffix}" >&2
-            echo $"exactly matches what is already found in kernel $1." >&2
-            echo $"DKMS will not replace this module." >&2
-            echo $"You may override by specifying --force." >&2
-            return 1
+            # if the module has neither version nor srcversion/checksum, check the binary files instead
+            local verinfo="$(get_module_verinfo "${dkms_module}")"
+            if [[ "$(echo "$verinfo" | tr -d '[:space:]')" ]] || diff "${kernels_module}" "${dkms_module}" &>/dev/null; then
+                echo $"Module version $(echo "$verinfo" | head -n 1) for $4${module_suffix}" >&2
+                echo $"exactly matches what is already found in kernel $1." >&2
+                echo $"DKMS will not replace this module." >&2
+                echo $"You may override by specifying --force." >&2
+                return 1
+            fi
         fi
     fi
     return 0
@@ -809,7 +822,7 @@
 read_conf_or_die() {
     read_conf "$@" && return
     die 8 $"Bad conf file."\
-        $"File: $conf does not represent a valid dkms.conf file."
+        $"File: ${3:-$conf} does not represent a valid dkms.conf file."
 }
 
 run_build_script() {
@@ -909,6 +922,20 @@
 
 prepare_signing()
 {
+    do_signing=0
+
+    if [[ ! -f "${kernel_config}" ]]; then
+        echo "Kernel config ${kernel_config} not found, modules won't be signed"
+        return
+    fi
+
+    if ! grep -q "^CONFIG_MODULE_SIG_HASH=" "${kernel_config}"; then
+        echo "The kernel is be built without module signing facility, modules won't be signed"
+        return
+    fi
+
+    sign_hash=$(grep "^CONFIG_MODULE_SIG_HASH=" "${kernel_config}" | cut -f2 -d= | sed 's/"//g')
+
     # Lazy source in signing related configuration
     read_framework_conf $dkms_framework_signing_variables
 
@@ -974,6 +1001,10 @@
     # scripts/sign-file.c in kernel source also supports using "pkcs11:..." as private key
     if [[ "$mok_signing_key" != "pkcs11:"* ]] && ( [ ! -f "$mok_signing_key" ] || [ ! -f "$mok_certificate" ] ); then
         echo "Certificate or key are missing, generating self signed certificate for MOK..."
+        if ! command -v openssl >/dev/null; then
+            echo "openssl not found, can't generate key and certificate."
+            return
+        fi
         openssl req -new -x509 -nodes -days 36500 -subj "/CN=DKMS module signing key" \
             -newkey rsa:2048 -keyout "$mok_signing_key" \
             -outform DER -out "$mok_certificate" > /dev/null 2>&1
@@ -988,14 +1019,6 @@
         return
     fi
 
-    if [[ -f "${kernel_config}" ]]; then
-        sign_hash="$(grep "^CONFIG_MODULE_SIG_HASH=" "${kernel_config}" | sed 's/CONFIG_MODULE_SIG_HASH=//;s/"//g')"
-        # The kernel may be built without module signing facility. CONFIG_MODULE_SIG_HASH is unset in kconfig
-        sign_hash="${sign_hash:-sha512}"
-    else
-        sign_hash="sha512"
-    fi
-
     do_signing=1
 }
 
@@ -1028,8 +1051,6 @@
         $"The directory $source_dir does not appear to have module source located within it."\
         $"Build halted."
 
-    prepare_kernel "$kernelver" "$arch"
-
     # Set up temporary build directory for build
     rm -rf "$build_dir"
     cp -a "$source_dir/" "$build_dir"
@@ -1047,10 +1068,21 @@
             $"Check $build_dir for more information."
     done
 
-    if [[ -e $kernel_source_dir/.config ]]; then
-        cc=$(sed -n 's|^CONFIG_CC_VERSION_TEXT="\([^ ]*\) .*"|\1|p' $kernel_source_dir/.config)
-        if command -v "$cc" >/dev/null; then
-            export CC="$cc"
+    if [[ -e "${kernel_config}" ]]; then
+        if grep -q 'CONFIG_CC_IS_CLANG=y' "${kernel_config}"; then
+            local cc=clang
+            if command -v "$cc" >/dev/null; then
+                export CC="$cc"
+                export KERNEL_CC="$cc"
+            fi
+        fi
+
+        if grep -q 'CONFIG_LD_IS_LLD=y' "${kernel_config}"; then
+            local ld=ld.lld
+            if command -v "$ld" >/dev/null; then
+                export LD="$ld"
+                export KERNEL_LD="$ld"
+            fi
         fi
     fi
 
@@ -1109,7 +1141,7 @@
 
         [[ ${strip[$count]} != no ]] && strip -g "$built_module"
 
-        if [ -n "${do_signing}" ]; then
+        if (( do_signing )); then
             echo "Signing module $built_module"
             "$sign_file" "$sign_hash" "$mok_signing_key" "$mok_certificate" "$built_module"
         fi
@@ -1147,6 +1179,7 @@
 do_build()
 {
     set_kernel_source_dir_and_kconfig "$kernelver"
+    prepare_kernel "$kernelver" "$arch"
     prepare_signing
     prepare_build
     actual_build
@@ -1320,7 +1353,7 @@
 
     done
 
-    if [[ ! "${any_module_installed}" ]]; then
+    if ((${#built_module_name[@]} > 0)) && [[ ! "${any_module_installed}" ]]; then
         die 6 $"Installation aborted."
     fi
 
@@ -1348,7 +1381,7 @@
 
     if [[ $modprobe_on_install ]]; then
         # Make the newly installed modules available immediately
-        find /sys/devices -name modalias -print0 | xargs -0 cat | xargs modprobe -a -b -q
+        find /sys/devices -name modalias -print0 | xargs -0 cat | sort -u | xargs modprobe -a -b -q
         if [ -f /lib/systemd/system/systemd-modules-load.service ]; then
             systemctl restart systemd-modules-load.service
         fi
@@ -1529,7 +1562,15 @@
                 while [ "${dir_to_remove}" != "${dir_to_remove#/}" ]; do
                     dir_to_remove="${dir_to_remove#/}"
                 done
+
+                case "$running_distribution" in
+                    debian* | ubuntu* | arch*)
+                        (if cd "$install_tree/$1"; then rmdir -p --ignore-fail-on-non-empty "${dir_to_remove}"; fi || true)
+                        ;;
+                    *)
                 (if cd "$install_tree/$1"; then rpm -qf "${dir_to_remove}" >/dev/null 2>&1 || rmdir -p --ignore-fail-on-non-empty "${dir_to_remove}"; fi || true)
+                    ;;
+                esac
             else
                 echo $"   - Module was not found within $install_tree/$1/"
             fi
@@ -1946,7 +1987,7 @@
     trap "rm -rf $temp_dir_name" EXIT
     tar -xaf $archive_location -C $temp_dir_name
 
-    if [[ ! $temp_dir_name/dkms_main_tree ]]; then
+    if [[ ! -d $temp_dir_name/dkms_main_tree ]]; then
     # Tarball was not generated from mktarball.
     # Just find the dkms.conf file and load the source.
     conf=$(find $temp_dir_name/ -name dkms.conf 2>/dev/null | head -n 1)
@@ -2187,30 +2228,33 @@
 # functionality, and makes it much easier to reinstall DKMS kernel modules
 # by hand if dkms_autoinstaller is not used.
 autoinstall() {
-    local status mv mvka m v k a last_v last_m tenative
-    local install_count next_depends
+    local status mv mvka m v k a
+    local progress next_depends
     local -a to_install=()
     local -a next_install=()
+    local -a known_modules=()
     local -a installed_modules=()
+    local -a skipped_modules=()
     local -a failed_modules=()
     local -A build_depends=()
+    local -A latest=()
 
     # Walk through our list of installed and built modules, and create
-    # a list of modules that need to be reinstalled.
-    # Assuming all versions of same module to be parsed sequentially.
+    # a list of modules and their latest version.
     while read status mvka; do
         IFS='/' read m v k a <<< "$mvka"
-        [[ ! $last_m ]] && last_m="$m"
-        # autoinstall previous module's latest version after its deps.
-        if [[ $last_m != $m ]]; then
-            if [[ $tenative ]]; then
-                to_install[${#to_install[@]}]="$tenative"
-                build_depends["$last_m"]="${BUILD_DEPENDS[@]}"
-            fi
-            last_m="$m"
-            last_v='0'
-            tenative=''
+        if [[ -z "${latest["$m"]}" ]]; then
+            known_modules[${#known_modules[@]}]="$m"
+            latest["$m"]="$v"
+        elif [[ ("$(VER "$v")" > "$(VER "${latest["$m"]}")") ]]; then
+            latest["$m"]="$v"
         fi
+    done < <(module_status)
+
+    # Walk through our list of known modules, and create
+    # a list of modules that need to be reinstalled.
+    for m in "${known_modules[@]}"; do
+        v="${latest["$m"]}"
         # If the module is already installed or weak-installed, skip it.
         if _is_module_installed "$m" "$v" "$kernelver" "$arch"; then
             installed_modules[${#installed_modules[@]}]="$m"
@@ -2220,36 +2264,27 @@
             installed_modules[${#installed_modules[@]}]="$m"
             continue
         fi
-        # if the module does not want to be autoinstalled, skip it.
-        read_conf_or_die "$k" "$a" "$dkms_tree/$m/$v/source/dkms.conf"
+        # If the module does not want to be autoinstalled, skip it.
+        read_conf_or_die "$kernelver" "$arch" "$dkms_tree/$m/$v/source/dkms.conf"
         if [[ ! $AUTOINSTALL ]]; then
             continue
         fi
-        # otherwise, only autoinstall the latest version we have hanging around.
-        if [[ ($(VER $v) > $(VER $last_v)) ]]; then
-            last_v="$v"
-            tenative="$m/$v"
-        fi
-    done < <(module_status)
-
-    # We may have exited the loop with $tenative set.  If it is,
-    # it contains something that should be updated.
-    if [[ $tenative ]]; then
-        to_install[${#to_install[@]}]="$tenative"
+        # Otherwise, autoinstall the latest version we have hanging around.
+        to_install[${#to_install[@]}]="$m/$v"
         build_depends["$m"]="${BUILD_DEPENDS[@]}"
-    fi
+    done
 
     [[ $to_install ]] || return 0
 
     while true; do
-        install_count=0
+        progress=0
         next_install=( )
 
         # Step 1: Remove installed modules from all dependency lists.
         for m in ${!build_depends[@]}; do
             next_depends=
             for d in ${build_depends[$m]}; do
-                for i in ${installed_modules[@]}; do
+                for i in ${installed_modules[@]} ${skipped_modules[@]}; do
                     [[ "$d" = "$i" ]] && continue 2
                 done
                 next_depends+="$d "
@@ -2261,11 +2296,16 @@
         for mv in "${to_install[@]}"; do
             IFS=/ read m v <<< "$mv"
             if [[ -z "${build_depends[$m]}" ]]; then
-                if (module="$m" module_version="$v" kernelver="$kernelver" arch="$arch" install_module); then
+                (module="$m" module_version="$v" kernelver="$kernelver" arch="$arch" install_module)
+                status=$?
+                if [ "$status" = 0 ]; then
                     installed_modules[${#installed_modules[@]}]="$m"
-                    install_count=$(($install_count +1))
+                    progress=$(($progress +1))
+                elif [ "$status" = 77 ]; then
+                    skipped_modules[${#skipped_modules[@]}]="$m"
+                    progress=$(($progress +1))
                 else
-                    failed_modules=[${#failed_modules[@]}]="$m"
+                    failed_modules[${#failed_modules[@]}]="$m($status)"
                 fi
             else
                 next_install[${#next_install[@]}]="$mv"
@@ -2280,15 +2320,28 @@
 
         # Step 4: Keep going if at least one module was installed during
         # this iteration.
-        [[ "$install_count" -gt 0 ]] || break;
+        [[ "$progress" -gt 0 ]] || break;
 
     done
+
+    if [[ "${#installed_modules[@]}" -gt 0 ]]; then
+        echo "dkms autoinstall on $kernelver/$arch succeeded for ${installed_modules[@]}"
+    fi
+
+    if [[ "${#skipped_modules[@]}" -gt 0 ]]; then
+        echo "dkms autoinstall on $kernelver/$arch was skipped for ${skipped_modules[@]}"
+    fi
+
+    if [[ "${#failed_modules[@]}" -gt 0 ]]; then
+        echo "dkms autoinstall on $kernelver/$arch failed for ${failed_modules[@]}"
+    fi
+
     for mv in "${to_install[@]}"; do
         IFS=/ read m v <<< "$mv"
         echo "$m/$v autoinstall failed due to missing dependencies: ${build_depends[$m]}"
     done
 
-    if [[ "${#failed_modules[@]}" > 0 || "${#to_install[@]}" > 0 ]]; then
+    if [[ "${#failed_modules[@]}" -gt 0 || "${#to_install[@]}" -gt 0 ]]; then
         die 11 $"One or more modules failed to install during autoinstall." \
             $"Refer to previous errors for more information."
     fi
@@ -2313,6 +2366,7 @@
 # Set important variables
 current_kernel=$(uname -r)
 current_os=$(uname -s)
+running_distribution=$(distro_version)
 dkms_tree="/var/lib/dkms"
 source_tree="/usr/src"
 install_tree="/lib/modules"
@@ -2320,10 +2374,17 @@
 verbose=""
 symlink_modules=""
 
+# Check that we can write temporary files
+tmpfile=$(mktemp_or_die)
+echo "Hello, DKMS!" > "$tmpfile"
+if [ "$(cat "$tmpfile")" != "Hello, DKMS!" ]; then
+    warn $"dkms will not function properly without some free space in \$TMPDIR ($tmp_location)."
+fi
+rm -f "$tmpfile"
+
 # These can come from the environment or the config file
 [[ ! ${ADDON_MODULES_DIR} && -e /etc/sysconfig/module-init-tools ]] && . /etc/sysconfig/module-init-tools
 addon_modules_dir="${ADDON_MODULES_DIR}"
-[[ ! ${addon_modules_dir} ]] && running_distribution="$(distro_version)"
 weak_modules="${WEAK_MODULES_BIN}"
 
 # Source in configuration not related to signing
@@ -2494,7 +2555,8 @@
 # Sanity checking
 
 # The <(cmd) idiom does not work if /proc is not mounted
-if [ ! -e <(echo) ]; then
+read line < <(echo "Hello, DKMS!")
+if [ "$line" != "Hello, DKMS!" ]; then
     warn $"dkms will not function properly if /proc is not mounted."
 fi
 
diff -Naur dkms-3.0.10/dkms_autoinstaller dkms-3.0.11/dkms_autoinstaller
--- dkms-3.0.10/dkms_autoinstaller	2023-04-27 18:16:34.000000000 +0200
+++ dkms-3.0.11/dkms_autoinstaller	2023-04-27 18:16:44.000000000 +0200
@@ -84,6 +84,6 @@
 		# Ignore others on debian/ubuntu too
         ;;
     *)
-        echo $"Usage: $0 {start}"
+        echo "Usage: $0 {start}"
         exit 2
 esac
diff -Naur dkms-3.0.10/dkms_find-provides dkms-3.0.11/dkms_find-provides
--- dkms-3.0.10/dkms_find-provides	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/dkms_find-provides	2023-04-27 17:06:25.000000000 +0200
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/bin/bash
 
 # heavily based upon find-suggests.ksyms by Andreas Gruenbacher <agruen@suse.de>.
 # with modifications by Michael Brown <Michael_E_Brown@dell.com>
diff -Naur dkms-3.0.10/dkms_framework.conf dkms-3.0.11/dkms_framework.conf
--- dkms-3.0.10/dkms_framework.conf	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/dkms_framework.conf	2023-04-27 17:06:25.000000000 +0200
@@ -37,5 +37,5 @@
 # mok_signing_key=/var/lib/dkms/mok.key
 # mok_certificate=/var/lib/dkms/mok.pub
 
-# Automatically modprobe the built modules upon succesful installation:
+# Automatically modprobe the built modules upon successful installation:
 # modprobe_on_install="true"
diff -Naur dkms-3.0.10/lsb_release dkms-3.0.11/lsb_release
--- dkms-3.0.10/lsb_release	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/lsb_release	2023-04-27 17:06:25.000000000 +0200
@@ -42,7 +42,7 @@
 # * Changes in 1.2
 # - Fixed more bash'isms
 # - LSB_VERSION is no longer required in /etc/lsb-release file
-# 
+#
 # * Changes in 1.1
 # - removed some bash-ism and typos
 #   Notice: script remains broken with ash because of awk issues
@@ -101,7 +101,7 @@
 ###############################################################################
 
 # Display Program Version for internal use (needed by help2man)
-DisplayProgramVersion() { 
+DisplayProgramVersion() {
     echo "FSG $(basename $0) v$SCRIPTVERSION"
     echo
     echo "Copyright (C) 2000, 2002, 2004 Free Standards Group, Inc."
@@ -389,7 +389,7 @@
     fi
 fi
 
-# Update args to All if requested 
+# Update args to All if requested
 if [ -n "$ARG_A" ]
 then
     [ -z "$ARG_C" ] && ARG_C="y"
diff -Naur dkms-3.0.10/run_test.sh dkms-3.0.11/run_test.sh
--- dkms-3.0.10/run_test.sh	2023-04-27 18:16:34.000000000 +0200
+++ dkms-3.0.11/run_test.sh	2023-04-27 18:16:44.000000000 +0200
@@ -7,13 +7,17 @@
 
 # To use a specific kernel version, use the environment variable KERNEL_VER
 KERNEL_VER="${KERNEL_VER:-$(uname -r)}"
-echo "Using kernel ${KERNEL_VER}"
+KERNEL_ARCH="$(uname -m)"
+echo "Using kernel ${KERNEL_VER}/${KERNEL_ARCH}"
 
-# Override PATH to use the local dkms binary
-PATH="$(pwd):$PATH"
-export PATH
+# debconf can trigger at random points, in the testing process. Where a bunch of
+# the frontends cannot work in our CI. Just opt for the noninteractive one.
+export DEBIAN_FRONTEND=noninteractive
 
-# temporary files, directories, and modules created during tests
+# Avoid output variations due to parallelism
+export parallel_jobs=1
+
+# Temporary files, directories, and modules created during tests
 TEST_MODULES=(
     "dkms_test"
     "dkms_failing_test"
@@ -21,6 +25,10 @@
     "dkms_multiver_test"
     "dkms_nover_test"
     "dkms_emptyver_test"
+    "dkms_nover_update_test"
+    "dkms_conf_test"
+    "dkms_build_exclusive_test"
+    "dkms_build_exclusive_dependencies_test"
 )
 TEST_TMPDIRS=(
     "/usr/src/dkms_test-1.0/"
@@ -30,6 +38,12 @@
     "/usr/src/dkms_multiver_test-2.0"
     "/usr/src/dkms_nover_test-1.0"
     "/usr/src/dkms_emptyver_test-1.0"
+    "/usr/src/dkms_nover_update_test-1.0"
+    "/usr/src/dkms_nover_update_test-2.0"
+    "/usr/src/dkms_nover_update_test-3.0"
+    "/usr/src/dkms_conf_test-1.0"
+    "/usr/src/dkms_build_exclusive_test-1.0"
+    "/usr/src/dkms_build_exclusive_dependencies_test-1.0"
     "/tmp/dkms_test_dir_${KERNEL_VER}/"
 )
 TEST_TMPFILES=(
@@ -38,10 +52,13 @@
     "/tmp/dkms_test_kconfig"
     "/etc/dkms/framework.conf.d/dkms_test_framework.conf"
     "test_cmd_output.log"
+    "test_cmd_stdout.log"
+    "test_cmd_stderr.log"
     "test_cmd_expected_output.log"
 )
 
 SIGNING_MESSAGE=""
+declare -i NO_SIGNING_TOOL
 if [ "$#" = 1 ] && [ "$1" = "--no-signing-tool" ]; then
     echo 'Ignore signing tool errors'
     NO_SIGNING_TOOL=1
@@ -120,7 +137,7 @@
     # $1: module name
     # $2: module version
     # $3: module file name if not the same as $1
-    if [[ "$NO_SIGNING_TOOL" = 0 ]]; then
+    if (( NO_SIGNING_TOOL == 0 )); then
         SIGNING_MESSAGE="Signing module /var/lib/dkms/$1/$2/build/${3:-$1}.ko"$'\n'
     fi
 }
@@ -156,12 +173,16 @@
         sed -i '/^depmod\.\.\.$/d' ${output_log}
     fi
     # Signing related output. Drop it from the output, to be more generic
-    sed -i '/^Sign command:/d' ${output_log}
-    sed -i '/^Signing key:/d' ${output_log}
-    sed -i '/^Public certificate (MOK):/d' ${output_log}
-    sed -i '/^Certificate or key are missing, generating them using update-secureboot-policy...$/d' ${output_log}
-    sed -i '/^Certificate or key are missing, generating self signed certificate for MOK...$/d' ${output_log}
-    if [[ "${NO_SIGNING_TOOL}" = "1" ]]; then
+    if (( NO_SIGNING_TOOL == 0 )); then
+        sed -i '/^EFI variables are not supported on this system/d' ${output_log}
+        sed -i '/^\/sys\/firmware\/efi\/efivars not found, aborting./d' ${output_log}
+        sed -i '/^Sign command:/d' ${output_log}
+        sed -i '/^Signing key:/d' ${output_log}
+        sed -i '/^Public certificate (MOK):/d' ${output_log}
+        sed -i '/^Certificate or key are missing, generating them using update-secureboot-policy...$/d' ${output_log}
+        sed -i '/^Certificate or key are missing, generating self signed certificate for MOK...$/d' ${output_log}
+    else
+        sed -i "/^The kernel is be built without module signing facility, modules won't be signed$/d" ${output_log}
         sed -i "/^Binary .* not found, modules won't be signed$/d" ${output_log}
         # Uncomment the following line to run this script with --no-signing-tool on platforms where the sign-file tool exists
         # sed -i '/^Signing module \/var\/lib\/dkms\/dkms_test\/1.0\/build\/dkms_test.ko$/d' ${output_log}
@@ -175,43 +196,19 @@
 }
 
 run_with_expected_output() {
-    local dkms_command="$2"
-    local output_log=test_cmd_output.log
-    local expected_output_log=test_cmd_expected_output.log
-
-    cat > ${expected_output_log}
-    if "$@" > ${output_log} 2>&1 ; then
-        genericize_expected_output ${output_log} ${dkms_command}
-        if ! diff -U3 ${expected_output_log} ${output_log} ; then
-            echo >&2 "Error: unexpected output from: $*"
-            return 1
-        fi
-        rm ${expected_output_log} ${output_log}
-    else
-        echo "Error: command '$*' returned status $?"
-        cat ${output_log}
-        rm ${expected_output_log} ${output_log}
-        return 1
-    fi
+    run_with_expected_error 0 "$@"
 }
 
 run_with_expected_error() {
     local expected_error_code="$1"
-    local dkms_command="$2"
+    local dkms_command="$3"
     local output_log=test_cmd_output.log
     local expected_output_log=test_cmd_expected_output.log
-    local error_code
+    local error_code=0
 
     shift
     cat > ${expected_output_log}
-    if "$@" > ${output_log} 2>&1 ; then
-        echo "Error: command '$*' was successful"
-        cat ${output_log}
-        rm ${expected_output_log} ${output_log}
-        return 1
-    else
-        error_code=$?
-    fi
+    stdbuf -o L -e L "$@" > ${output_log} 2>&1 || error_code=$?
     if [[ "${error_code}" != "${expected_error_code}" ]] ; then
         echo "Error: command '$*' returned status ${error_code} instead of expected ${expected_error_code}"
         cat ${output_log}
@@ -221,11 +218,19 @@
     genericize_expected_output ${output_log} ${dkms_command}
     if ! diff -U3 ${expected_output_log} ${output_log} ; then
         echo >&2 "Error: unexpected output from: $*"
+        rm ${expected_output_log} ${output_log}
         return 1
     fi
     rm ${expected_output_log} ${output_log}
 }
 
+# sig_hashalgo itself may show bogus value if kmod version < 26
+kmod_broken_hashalgo() {
+    local -ri kmod_ver=$(kmod --version | grep version | cut -f 3 -d ' ')
+
+    (( kmod_ver < 26 ))
+}
+
 # Compute the expected destination module location
 os_id="$(sed -n 's/^ID\s*=\s*\(.*\)$/\1/p' /etc/os-release | tr -d '"')"
 mod_compression_ext=
@@ -242,6 +247,7 @@
         ;;
     alpine)
         expected_dest_loc=kernel/extra
+        mod_compression_ext=.gz
         ;;
     *)
         echo >&2 "Error: unknown Linux distribution ID ${os_id}"
@@ -260,6 +266,10 @@
 EOF
 rm /etc/dkms/framework.conf.d/dkms_test_framework.conf
 
+############################################################################
+### Testing dkms on a regular module                                     ###
+############################################################################
+
 echo 'Adding the test module by version (expected error)'
 run_with_expected_error 2 dkms add -m dkms_test -v 1.0 << EOF
 Error! Could not find module source directory.
@@ -275,7 +285,7 @@
 EOF
 if ! [[ -d /usr/src/dkms_test-1.0 ]] ; then
     echo >&2 'Error: directory /usr/src/dkms_test-1.0 was not created'
-    return 1
+    exit 1
 fi
 
 echo 'Adding the test module again (expected error)'
@@ -296,22 +306,22 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 
 echo 'Building the test module again'
 run_with_expected_output dkms build -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
-Module dkms_test/1.0 already built for kernel ${KERNEL_VER} ($(uname -m)), skip. You may override by specifying --force.
+Module dkms_test/1.0 already built for kernel ${KERNEL_VER} (${KERNEL_ARCH}), skip. You may override by specifying --force.
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 
-if [[ "${NO_SIGNING_TOOL}" = 0 ]]; then
+if (( NO_SIGNING_TOOL == 0 )); then
     echo 'Building the test module with bad sign_file path in framework file'
     cp test/framework/bad_sign_file_path.conf /etc/dkms/framework.conf.d/dkms_test_framework.conf
     run_with_expected_output dkms build -k "${KERNEL_VER}" -m dkms_test -v 1.0 --force << EOF
@@ -319,7 +329,7 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
 Cleaning build area...
 EOF
 
@@ -330,7 +340,7 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
 Cleaning build area...
 EOF
 
@@ -341,7 +351,7 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
 Cleaning build area...
 EOF
     rm /tmp/dkms_test_private_key
@@ -353,18 +363,22 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 EOF
     rm -r "/tmp/dkms_test_dir_${KERNEL_VER}/"
 
-    BUILT_MODULE_PATH="/var/lib/dkms/dkms_test/1.0/${KERNEL_VER}/$(uname -m)/module/dkms_test.ko${mod_compression_ext}"
-    # If sig_key can't be extracted from module, the hash algorithm is also unknown
-    # sig_hashalgo itself may show bogus value if kmod version < 26
-    if [[ "$(modinfo "${BUILT_MODULE_PATH}" | grep '^sig_key:' | tr -d ' ')" != "sig_key:" ]]; then
-        echo 'Building the test module using a different hash algorithm'
+    BUILT_MODULE_PATH="/var/lib/dkms/dkms_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/module/dkms_test.ko${mod_compression_ext}"
+    CURRENT_HASH="$(modinfo -F sig_hashalgo "${BUILT_MODULE_PATH}")"
+
+    echo 'Building the test module using a different hash algorithm'
+    if kmod_broken_hashalgo; then
+        echo 'Current kmod has broken hash algorithm code. Skipping...'
+    elif [[ "${CURRENT_HASH}" == "unknown" ]]; then
+        echo 'Current kmod reports unknown hash algorithm. Skipping...'
+    else
         cp test/framework/temp_key_cert.conf /etc/dkms/framework.conf.d/dkms_test_framework.conf
-        CURRENT_HASH="$(modinfo "${BUILT_MODULE_PATH}" | grep '^sig_hashalgo:' | sed 's/sig_hashalgo: *//')"
+
         if [[ "${CURRENT_HASH}" == "sha512" ]]; then
             ALTER_HASH="sha256"
         else
@@ -375,11 +389,11 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 EOF
-        run_with_expected_output sh -c "modinfo '${BUILT_MODULE_PATH}' | grep '^sig_hashalgo:' | tr -d ' '" << EOF
-sig_hashalgo:${ALTER_HASH}
+        run_with_expected_output sh -c "modinfo -F sig_hashalgo '${BUILT_MODULE_PATH}'" << EOF
+${ALTER_HASH}
 EOF
         rm /tmp/dkms_test_kconfig
     fi
@@ -394,14 +408,14 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 
-if [[ "${NO_SIGNING_TOOL}" = 0 ]]; then
+if (( NO_SIGNING_TOOL == 0 )); then
     echo 'Extracting serial number from the certificate'
     MODULE_SERIAL="$(cert_serial /tmp/dkms_test_certificate)"
 fi
@@ -418,15 +432,15 @@
 depmod...
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): installed
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
 EOF
 
 echo 'Installing the test module again'
 run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
-Module dkms_test/1.0 already installed on kernel ${KERNEL_VER} ($(uname -m)), skip. You may override by specifying --force.
+Module dkms_test/1.0 already installed on kernel ${KERNEL_VER} (${KERNEL_ARCH}), skip. You may override by specifying --force.
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): installed
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
 EOF
 if ! [[ -f "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" ]] ; then
     echo >&2 "Error: module not found in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}"
@@ -435,7 +449,7 @@
 
 echo 'Installing the test module again by force'
 run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_test -v 1.0 --force << EOF
-Module dkms_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
+Module dkms_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
 Before uninstall, this module version was ACTIVE on this kernel.
 
 dkms_test.ko${mod_compression_ext}:
@@ -455,7 +469,7 @@
 depmod...
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): installed
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
 EOF
 
 echo 'Checking modinfo'
@@ -466,25 +480,28 @@
 license:        GPL
 EOF
 
-if [[ "${NO_SIGNING_TOOL}" = 0 ]]; then
+if (( NO_SIGNING_TOOL == 0 )); then
     echo 'Checking module signature'
-    SIG_KEY="$(modinfo "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" | grep '^sig_key:')"
-    run_with_expected_output sh -c "echo '${SIG_KEY}' | cut -f1 -d' '" << EOF
-sig_key:
-EOF
-    if [[ "${SIG_KEY// /}" = "sig_key:" ]]; then
-        # kmod may not be linked with openssl and thus can't extract the key from module
-        echo "Warning: module was signed but the key is unknown"
+    SIG_KEY="$(modinfo -F sig_key "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" | tr -d ':')"
+    SIG_HASH="$(modinfo -F sig_hashalgo "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}")"
+
+    if kmod_broken_hashalgo; then
+        echo 'Current kmod has broken hash algorithm code. Skipping...'
+    elif [[ "${SIG_HASH}" == "unknown" ]]; then
+        echo 'Current kmod reports unknown hash algorithm. Skipping...'
+    elif [[ ! "${SIG_KEY}" ]]; then
+        echo >&2 "Error: module was not signed"
+        exit 1
     else
-        run_with_expected_output sh -c "echo '${SIG_KEY}' | tr -d ' :'" << EOF
-sig_key${MODULE_SERIAL}
+        run_with_expected_output sh -c "echo '${SIG_KEY}'" << EOF
+${MODULE_SERIAL}
 EOF
     fi
 fi
 
 echo 'Uninstalling the test module'
 run_with_expected_output dkms uninstall -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
-Module dkms_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
+Module dkms_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
 Before uninstall, this module version was ACTIVE on this kernel.
 
 dkms_test.ko${mod_compression_ext}:
@@ -495,7 +512,7 @@
    - Use the dkms install command to reinstall any previous module version.
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 if [[ -e "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" ]] ; then
     echo >&2 "Error: module not removed in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}"
@@ -504,15 +521,15 @@
 
 echo 'Uninstalling the test module again'
 run_with_expected_output dkms uninstall -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
-Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 
 echo 'Unbuilding the test module'
 run_with_expected_output dkms unbuild -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
-Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
 dkms_test/1.0: added
@@ -520,8 +537,8 @@
 
 echo 'Unbuilding the test module again'
 run_with_expected_output dkms unbuild -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
-Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
-Module dkms_test 1.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Module dkms_test 1.0 is not built for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
 dkms_test/1.0: added
@@ -529,15 +546,15 @@
 
 echo 'Removing the test module'
 run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
-Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
-Module dkms_test 1.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Module dkms_test 1.0 is not built for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 Deleting module dkms_test-1.0 completely from the DKMS tree.
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
 EOF
 if ! [[ -d /usr/src/dkms_test-1.0 ]] ; then
     echo >&2 'Error: directory /usr/src/dkms_test-1.0 was removed'
-    return 1
+    exit 1
 fi
 
 echo 'Adding the test module by version'
@@ -561,7 +578,7 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 
 dkms_test.ko${mod_compression_ext}:
@@ -573,7 +590,7 @@
 depmod...
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): installed
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
 EOF
 if ! [[ -f "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" ]] ; then
     echo >&2 "Error: module not found in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}"
@@ -588,25 +605,29 @@
 license:        GPL
 EOF
 
-if [[ "${NO_SIGNING_TOOL}" = 0 ]]; then
+if (( NO_SIGNING_TOOL == 0 )); then
     echo 'Checking module signature'
-    SIG_KEY="$(modinfo "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" | grep '^sig_key:')"
-    run_with_expected_output sh -c "echo '${SIG_KEY}' | cut -f1 -d' '" << EOF
-sig_key:
-EOF
-    if [[ "${SIG_KEY// /}" = "sig_key:" ]]; then
+    SIG_KEY="$(modinfo -F sig_key "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}" | tr -d ':')"
+    SIG_HASH="$(modinfo -F sig_hashalgo "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_test.ko${mod_compression_ext}")"
+
+    if kmod_broken_hashalgo; then
+        echo 'Current kmod has broken hash algorithm code. Skipping...'
+    elif [[ "${SIG_HASH}" == "unknown" ]]; then
+        echo 'Current kmod reports unknown hash algorithm. Skipping...'
+    elif [[ ! "${SIG_KEY}" ]]; then
         # kmod may not be linked with openssl and thus can't extract the key from module
-        echo "Warning: module was signed but the key is unknown"
+        echo >&2 "Error: modules was not signed, or key is unknown"
+        exit 1
     else
-        run_with_expected_output sh -c "echo '${SIG_KEY}' | tr -d ' :'" << EOF
-sig_key${MODULE_SERIAL}
+        run_with_expected_output sh -c "echo '${SIG_KEY}'" << EOF
+${MODULE_SERIAL}
 EOF
     fi
 fi
 
 echo 'Removing the test module with --all'
 run_with_expected_output dkms remove --all -m dkms_test -v 1.0 << EOF
-Module dkms_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
+Module dkms_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
 Before uninstall, this module version was ACTIVE on this kernel.
 
 dkms_test.ko${mod_compression_ext}:
@@ -633,11 +654,11 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 EOF
 run_status_with_expected_output 'dkms_test' << EOF
-dkms_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 
 echo "Running dkms autoinstall"
@@ -650,11 +671,21 @@
  - Installation
    - Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
 depmod...
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} succeeded for dkms_test
+EOF
+
+echo "Running dkms autoinstall for a kernel without headers installed (expected error)"
+run_with_expected_error 11 dkms autoinstall -k "${KERNEL_VER}-noheaders" << EOF
+Error! Your kernel headers for kernel ${KERNEL_VER}-noheaders cannot be found at /lib/modules/${KERNEL_VER}-noheaders/build or /lib/modules/${KERNEL_VER}-noheaders/source.
+Please install the linux-headers-${KERNEL_VER}-noheaders package or use the --kernelsourcedir option to tell DKMS where it's located.
+dkms autoinstall on ${KERNEL_VER}-noheaders/x86_64 failed for dkms_test(1)
+Error! One or more modules failed to install during autoinstall.
+Refer to previous errors for more information.
 EOF
 
 echo 'Removing the test module with --all'
 run_with_expected_output dkms remove --all -m dkms_test -v 1.0 << EOF
-Module dkms_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
+Module dkms_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
 Before uninstall, this module version was ACTIVE on this kernel.
 
 dkms_test.ko${mod_compression_ext}:
@@ -669,7 +700,7 @@
 EOF
 
 echo 'Removing temporary files'
-if [[ "${NO_SIGNING_TOOL}" = 0 ]]; then
+if (( NO_SIGNING_TOOL == 0 )); then
     rm /tmp/dkms_test_private_key /tmp/dkms_test_certificate
 fi
 rm /etc/dkms/framework.conf.d/dkms_test_framework.conf
@@ -677,6 +708,112 @@
 echo 'Removing /usr/src/dkms_test-1.0'
 rm -r /usr/src/dkms_test-1.0
 
+echo 'Checking that the environment is clean again'
+check_no_dkms_test
+
+############################################################################
+### Testing malformed/borderline dkms.conf                               ###
+############################################################################
+
+abspwd=$(readlink -f $(pwd))
+
+echo 'Testing dkms add of source tree without dkms.conf (expected error)'
+run_with_expected_error 1 dkms add ${abspwd}/test/dkms_conf_test_no_conf << EOF
+Error! Arguments <module> and <module-version> are not specified.
+Usage: add <module>/<module-version> or
+       add -m <module>/<module-version> or
+       add -m <module> -v <module-version>
+EOF
+
+echo 'Testing dkms add with empty dkms.conf (expected error)'
+run_with_expected_error 8 dkms add test/dkms_conf_test_empty << EOF
+dkms.conf: Error! No 'PACKAGE_NAME' directive specified.
+dkms.conf: Error! No 'PACKAGE_VERSION' directive specified.
+dkms.conf: Warning! Zero modules specified.
+Error! Bad conf file.
+File: ${abspwd}/test/dkms_conf_test_empty/dkms.conf does not represent a valid dkms.conf file.
+EOF
+
+echo 'Testing dkms.conf with invalid values (expected error)'
+run_with_expected_error 8 dkms add test/dkms_conf_test_invalid << EOF
+dkms.conf: Error! No 'BUILT_MODULE_NAME' directive specified for record #0.
+dkms.conf: Error! 'DEST_MODULE_NAME' directive ends in '.o' or '.ko' in record #0.
+dkms.conf: Error! Directive 'DEST_MODULE_LOCATION' does not begin with
+'/kernel', '/updates', or '/extra' in record #0.
+dkms.conf: Error! 'BUILT_MODULE_NAME' directive ends in '.o' or '.ko' in record #1.
+dkms.conf: Error! No 'DEST_MODULE_LOCATION' directive specified for record #1.
+dkms.conf: Error! Directive 'DEST_MODULE_LOCATION' does not begin with
+'/kernel', '/updates', or '/extra' in record #1.
+Error! Bad conf file.
+File: ${abspwd}/test/dkms_conf_test_invalid/dkms.conf does not represent a valid dkms.conf file.
+EOF
+
+echo 'Testing dkms.conf defining zero modules'
+run_with_expected_output dkms add test/dkms_conf_test_zero_modules << EOF
+dkms.conf: Warning! Zero modules specified.
+dkms.conf: Warning! Zero modules specified.
+Creating symlink /var/lib/dkms/dkms_conf_test/1.0/source -> /usr/src/dkms_conf_test-1.0
+EOF
+
+run_with_expected_output dkms remove --all -m dkms_conf_test -v 1.0 << EOF
+Deleting module dkms_conf_test-1.0 completely from the DKMS tree.
+EOF
+
+echo 'Testing add/build/install of a test module building zero kernel modules'
+run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_conf_test -v 1.0 << EOF
+dkms.conf: Warning! Zero modules specified.
+Creating symlink /var/lib/dkms/dkms_conf_test/1.0/source -> /usr/src/dkms_conf_test-1.0
+
+Building module:
+Cleaning build area...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_conf_test/1.0/build...
+Cleaning build area...
+depmod...
+EOF
+run_status_with_expected_output 'dkms_conf_test' << EOF
+dkms.conf: Warning! Zero modules specified.
+dkms_conf_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
+EOF
+
+run_with_expected_output dkms remove --all -m dkms_conf_test -v 1.0 << EOF
+dkms.conf: Warning! Zero modules specified.
+dkms.conf: Warning! Zero modules specified.
+Module dkms_conf_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
+Before uninstall, this module version was ACTIVE on this kernel.
+Deleting module dkms_conf_test-1.0 completely from the DKMS tree.
+EOF
+
+echo 'Removing /usr/src/dkms_conf_test-1.0'
+rm -r /usr/src/dkms_conf_test-1.0
+
+echo 'Testing dkms.conf with defaulted BUILT_MODULE_NAME'
+run_with_expected_output dkms add test/dkms_conf_test_defaulted_BUILT_MODULE_NAME << EOF
+Creating symlink /var/lib/dkms/dkms_conf_test/1.0/source -> /usr/src/dkms_conf_test-1.0
+EOF
+
+echo 'Building test module without source (expected error)'
+run_with_expected_error 8 dkms build -k "${KERNEL_VER}" -m dkms_conf_test -v 1.0 << EOF
+Error! The directory /var/lib/dkms/dkms_conf_test/1.0/source does not appear to have module source located within it.
+Build halted.
+EOF
+run_status_with_expected_output 'dkms_conf_test' << EOF
+dkms_conf_test/1.0: added
+EOF
+
+run_with_expected_output dkms remove --all -m dkms_conf_test -v 1.0 << EOF
+Deleting module dkms_conf_test-1.0 completely from the DKMS tree.
+EOF
+
+echo 'Removing /usr/src/dkms_conf_test-1.0'
+rm -r /usr/src/dkms_conf_test-1.0
+
+echo 'Checking that the environment is clean again'
+check_no_dkms_test
+
+############################################################################
+### Testing dkms on a module with multiple versions                      ###
+############################################################################
+
 echo 'Adding the multiver test modules by directory'
 run_with_expected_output dkms add test/dkms_multiver_test/1.0 << EOF
 Creating symlink /var/lib/dkms/dkms_multiver_test/1.0/source -> /usr/src/dkms_multiver_test-1.0
@@ -706,11 +843,11 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_multiver_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_multiver_test/1.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
-dkms_multiver_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_multiver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 dkms_multiver_test/2.0: added
 EOF
 set_signing_message "dkms_multiver_test" "2.0"
@@ -718,12 +855,12 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_multiver_test/2.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_multiver_test/2.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
-dkms_multiver_test/1.0, ${KERNEL_VER}, $(uname -m): built
-dkms_multiver_test/2.0, ${KERNEL_VER}, $(uname -m): built
+dkms_multiver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+dkms_multiver_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 
 if false ; then
@@ -739,8 +876,8 @@
 depmod...
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
-dkms_multiver_test/1.0, ${KERNEL_VER}, $(uname -m): installed
-dkms_multiver_test/2.0, ${KERNEL_VER}, $(uname -m): built
+dkms_multiver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
+dkms_multiver_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_multiver_test -v 2.0 << EOF
 
@@ -753,8 +890,8 @@
 depmod...
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
-dkms_multiver_test/1.0, ${KERNEL_VER}, $(uname -m): built
-dkms_multiver_test/2.0, ${KERNEL_VER}, $(uname -m): installed
+dkms_multiver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+dkms_multiver_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
 EOF
 run_with_expected_error 6 dkms install -k "${KERNEL_VER}" -m dkms_multiver_test -v 1.0 << EOF
 
@@ -766,20 +903,20 @@
 Error! Installation aborted.
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
-dkms_multiver_test/1.0, ${KERNEL_VER}, $(uname -m): built
-dkms_multiver_test/2.0, ${KERNEL_VER}, $(uname -m): installed
+dkms_multiver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+dkms_multiver_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
 EOF
 
 echo 'Uninstalling the multiver test modules'
 run_with_expected_output dkms uninstall -k "${KERNEL_VER}" -m dkms_multiver_test -v 1.0 << EOF
-Module dkms_multiver_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_multiver_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
-dkms_multiver_test/1.0, ${KERNEL_VER}, $(uname -m): built
-dkms_multiver_test/2.0, ${KERNEL_VER}, $(uname -m): installed
+dkms_multiver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+dkms_multiver_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
 EOF
 run_with_expected_output dkms uninstall -k "${KERNEL_VER}" -m dkms_multiver_test -v 2.0 << EOF
-Module dkms_multiver_test-2.0 for kernel ${KERNEL_VER} ($(uname -m)).
+Module dkms_multiver_test-2.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
 Before uninstall, this module version was ACTIVE on this kernel.
 
 dkms_multiver_test.ko${mod_compression_ext}:
@@ -790,8 +927,8 @@
    - Use the dkms install command to reinstall any previous module version.
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
-dkms_multiver_test/1.0, ${KERNEL_VER}, $(uname -m): built
-dkms_multiver_test/2.0, ${KERNEL_VER}, $(uname -m): built
+dkms_multiver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+dkms_multiver_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 if [[ -e "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_multiver_test.ko${mod_compression_ext}" ]] ; then
     echo >&2 "Error: module not removed in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_multiver_test.ko${mod_compression_ext}"
@@ -801,14 +938,14 @@
 
 echo 'Unbuilding the multiver test modules'
 run_with_expected_output dkms unbuild -k "${KERNEL_VER}" -m dkms_multiver_test -v 1.0 << EOF
-Module dkms_multiver_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_multiver_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
 dkms_multiver_test/1.0: added
-dkms_multiver_test/2.0, ${KERNEL_VER}, $(uname -m): built
+dkms_multiver_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 run_with_expected_output dkms unbuild -k "${KERNEL_VER}" -m dkms_multiver_test -v 2.0 << EOF
-Module dkms_multiver_test 2.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_multiver_test 2.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
 dkms_multiver_test/1.0: added
@@ -817,16 +954,16 @@
 
 echo 'Removing the multiver test modules'
 run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_multiver_test -v 1.0 << EOF
-Module dkms_multiver_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
-Module dkms_multiver_test 1.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_multiver_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Module dkms_multiver_test 1.0 is not built for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 Deleting module dkms_multiver_test-1.0 completely from the DKMS tree.
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
 dkms_multiver_test/2.0: added
 EOF
 run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_multiver_test -v 2.0 << EOF
-Module dkms_multiver_test 2.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
-Module dkms_multiver_test 2.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_multiver_test 2.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Module dkms_multiver_test 2.0 is not built for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 Deleting module dkms_multiver_test-2.0 completely from the DKMS tree.
 EOF
 run_status_with_expected_output 'dkms_multiver_test' << EOF
@@ -835,6 +972,9 @@
 echo 'Removing /usr/src/dkms_multiver_test-1.0 /usr/src/dkms_multiver_test-2.0'
 rm -r /usr/src/dkms_multiver_test-1.0 /usr/src/dkms_multiver_test-2.0
 
+############################################################################
+### Testing dkms operations ...
+############################################################################
 
 echo 'Adding the nover/emptyver test modules by directory'
 run_with_expected_output dkms add test/dkms_nover_test << EOF
@@ -864,22 +1004,22 @@
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_nover_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_nover_test/1.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 EOF
 run_status_with_expected_output 'dkms_nover_test' << EOF
-dkms_nover_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_nover_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 set_signing_message "dkms_emptyver_test" "1.0"
 run_with_expected_output dkms build -k "${KERNEL_VER}" -m dkms_emptyver_test -v 1.0 << EOF
 
 Building module:
 Cleaning build area...
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_emptyver_test/1.0/build...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_emptyver_test/1.0/build...
 ${SIGNING_MESSAGE}Cleaning build area...
 EOF
 run_status_with_expected_output 'dkms_emptyver_test' << EOF
-dkms_emptyver_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_emptyver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 
 echo 'Installing the nover/emptyver test modules'
@@ -894,7 +1034,7 @@
 depmod...
 EOF
 run_status_with_expected_output 'dkms_nover_test' << EOF
-dkms_nover_test/1.0, ${KERNEL_VER}, $(uname -m): installed
+dkms_nover_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
 EOF
 run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_emptyver_test -v 1.0 << EOF
 
@@ -907,12 +1047,12 @@
 depmod...
 EOF
 run_status_with_expected_output 'dkms_emptyver_test' << EOF
-dkms_emptyver_test/1.0, ${KERNEL_VER}, $(uname -m): installed
+dkms_emptyver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
 EOF
 
 echo 'Uninstalling the nover/emptyver test modules'
 run_with_expected_output dkms uninstall -k "${KERNEL_VER}" -m dkms_nover_test -v 1.0 << EOF
-Module dkms_nover_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
+Module dkms_nover_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
 Before uninstall, this module version was ACTIVE on this kernel.
 
 dkms_nover_test.ko${mod_compression_ext}:
@@ -923,14 +1063,14 @@
    - Use the dkms install command to reinstall any previous module version.
 EOF
 run_status_with_expected_output 'dkms_nover_test' << EOF
-dkms_nover_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_nover_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 if [[ -e "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_nover_test.ko${mod_compression_ext}" ]] ; then
     echo >&2 "Error: module not removed in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_nover_test.ko${mod_compression_ext}"
     exit 1
 fi
 run_with_expected_output dkms uninstall -k "${KERNEL_VER}" -m dkms_emptyver_test -v 1.0 << EOF
-Module dkms_emptyver_test-1.0 for kernel ${KERNEL_VER} ($(uname -m)).
+Module dkms_emptyver_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
 Before uninstall, this module version was ACTIVE on this kernel.
 
 dkms_emptyver_test.ko${mod_compression_ext}:
@@ -941,7 +1081,7 @@
    - Use the dkms install command to reinstall any previous module version.
 EOF
 run_status_with_expected_output 'dkms_emptyver_test' << EOF
-dkms_emptyver_test/1.0, ${KERNEL_VER}, $(uname -m): built
+dkms_emptyver_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
 EOF
 if [[ -e "/lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_emptyver_test.ko${mod_compression_ext}" ]] ; then
     echo >&2 "Error: module not removed in /lib/modules/${KERNEL_VER}/${expected_dest_loc}/dkms_emptyver_test.ko${mod_compression_ext}"
@@ -950,13 +1090,13 @@
 
 echo 'Unbuilding the nover/emptyver test modules'
 run_with_expected_output dkms unbuild -k "${KERNEL_VER}" -m dkms_nover_test -v 1.0 << EOF
-Module dkms_nover_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_nover_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 EOF
 run_status_with_expected_output 'dkms_nover_test' << EOF
 dkms_nover_test/1.0: added
 EOF
 run_with_expected_output dkms unbuild -k "${KERNEL_VER}" -m dkms_emptyver_test -v 1.0 << EOF
-Module dkms_emptyver_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_emptyver_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 EOF
 run_status_with_expected_output 'dkms_emptyver_test' << EOF
 dkms_emptyver_test/1.0: added
@@ -964,15 +1104,15 @@
 
 echo 'Removing the nover/emptyver test modules'
 run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_nover_test -v 1.0 << EOF
-Module dkms_nover_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
-Module dkms_nover_test 1.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_nover_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Module dkms_nover_test 1.0 is not built for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 Deleting module dkms_nover_test-1.0 completely from the DKMS tree.
 EOF
 run_status_with_expected_output 'dkms_nover_test' << EOF
 EOF
 run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_emptyver_test -v 1.0 << EOF
-Module dkms_emptyver_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
-Module dkms_emptyver_test 1.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_emptyver_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Module dkms_emptyver_test 1.0 is not built for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 Deleting module dkms_emptyver_test-1.0 completely from the DKMS tree.
 EOF
 run_status_with_expected_output 'dkms_emptyver_test' << EOF
@@ -982,9 +1122,162 @@
 rm -r /usr/src/dkms_nover_test-1.0 /usr/src/dkms_emptyver_test-1.0
 
 
+echo 'Adding the nover update test modules 1.0 by directory'
+run_with_expected_output dkms add test/dkms_nover_update_test/1.0 << EOF
+Creating symlink /var/lib/dkms/dkms_nover_update_test/1.0/source -> /usr/src/dkms_nover_update_test-1.0
+EOF
+run_status_with_expected_output 'dkms_nover_update_test' << EOF
+dkms_nover_update_test/1.0: added
+EOF
+if ! [[ -d /usr/src/dkms_nover_update_test-1.0 ]] ; then
+    echo >&2 'Error: directory /usr/src/dkms_nover_update_test-1.0 was not created'
+    exit 1
+fi
+
+echo 'Installing the nover update test 1.0 modules'
+set_signing_message "dkms_nover_update_test" "1.0"
+run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_nover_update_test -v 1.0 << EOF
+
+Building module:
+Cleaning build area...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_nover_update_test/1.0/build...
+${SIGNING_MESSAGE}Cleaning build area...
+
+dkms_nover_update_test.ko${mod_compression_ext}:
+Running module version sanity check.
+ - Original module
+   - No original module exists within this kernel
+ - Installation
+   - Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
+depmod...
+EOF
+run_status_with_expected_output 'dkms_nover_update_test' << EOF
+dkms_nover_update_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
+EOF
+
+echo 'Adding the nover update test modules 2.0 by directory'
+run_with_expected_output dkms add test/dkms_nover_update_test/2.0 << EOF
+Creating symlink /var/lib/dkms/dkms_nover_update_test/2.0/source -> /usr/src/dkms_nover_update_test-2.0
+EOF
+run_status_with_expected_output 'dkms_nover_update_test' << EOF
+dkms_nover_update_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
+dkms_nover_update_test/2.0: added
+EOF
+if ! [[ -d /usr/src/dkms_nover_update_test-2.0 ]] ; then
+    echo >&2 'Error: directory /usr/src/dkms_nover_update_test-2.0 was not created'
+    exit 1
+fi
+
+echo 'Installing the nover update test 2.0 modules'
+set_signing_message "dkms_nover_update_test" "2.0"
+run_with_expected_output dkms install -k "${KERNEL_VER}" -m dkms_nover_update_test -v 2.0 << EOF
+
+Building module:
+Cleaning build area...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_nover_update_test/2.0/build...
+${SIGNING_MESSAGE}Cleaning build area...
+
+dkms_nover_update_test.ko${mod_compression_ext}:
+Running module version sanity check.
+ - Original module
+   - This kernel never originally had a module by this name
+ - Installation
+   - Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
+depmod...
+EOF
+run_status_with_expected_output 'dkms_nover_update_test' << EOF
+dkms_nover_update_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+dkms_nover_update_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
+EOF
+
+echo 'Adding the nover update test modules 3.0 by directory'
+run_with_expected_output dkms add test/dkms_nover_update_test/3.0 << EOF
+Creating symlink /var/lib/dkms/dkms_nover_update_test/3.0/source -> /usr/src/dkms_nover_update_test-3.0
+EOF
+run_status_with_expected_output 'dkms_nover_update_test' << EOF
+dkms_nover_update_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+dkms_nover_update_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
+dkms_nover_update_test/3.0: added
+EOF
+if ! [[ -d /usr/src/dkms_nover_update_test-3.0 ]] ; then
+    echo >&2 'Error: directory /usr/src/dkms_nover_update_test-3.0 was not created'
+    exit 1
+fi
+
+echo 'Building the nover update test 3.0 modules'
+set_signing_message "dkms_nover_update_test" "3.0"
+run_with_expected_output dkms build -k "${KERNEL_VER}" -m dkms_nover_update_test -v 3.0 << EOF
+
+Building module:
+Cleaning build area...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_nover_update_test/3.0/build...
+${SIGNING_MESSAGE}Cleaning build area...
+EOF
+run_status_with_expected_output 'dkms_nover_update_test' << EOF
+dkms_nover_update_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+dkms_nover_update_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
+dkms_nover_update_test/3.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+EOF
+
+MODULE_PATH_2="/var/lib/dkms/dkms_nover_update_test/2.0/${KERNEL_VER}/${KERNEL_ARCH}/module/dkms_nover_update_test.ko${mod_compression_ext}"
+MODULE_PATH_3="/var/lib/dkms/dkms_nover_update_test/3.0/${KERNEL_VER}/${KERNEL_ARCH}/module/dkms_nover_update_test.ko${mod_compression_ext}"
+if ! modinfo "${MODULE_PATH_3}" | grep -q '^srcversion:' && ! diff "${MODULE_PATH_2}" "${MODULE_PATH_3}" &>/dev/null; then
+    # On debian, no srcversion in modinfo's output, the installation will always succeed
+    echo 'Notice: Skip installation test on this platform'
+else
+    echo 'Installing the nover update test 3.0 modules (expected error)'
+    set_signing_message "dkms_nover_update_test" "3.0"
+    run_with_expected_error 6 dkms install -k "${KERNEL_VER}" -m dkms_nover_update_test -v 3.0 << EOF
+
+dkms_nover_update_test.ko${mod_compression_ext}:
+Running module version sanity check.
+Module version  for dkms_nover_update_test.ko${mod_compression_ext}
+exactly matches what is already found in kernel ${KERNEL_VER}.
+DKMS will not replace this module.
+You may override by specifying --force.
+Error! Installation aborted.
+EOF
+    run_status_with_expected_output 'dkms_nover_update_test' << EOF
+dkms_nover_update_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+dkms_nover_update_test/2.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
+dkms_nover_update_test/3.0, ${KERNEL_VER}, ${KERNEL_ARCH}: built
+EOF
+fi
+
+echo 'Removing the nover update test modules'
+run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_nover_update_test -v 3.0 << EOF
+Module dkms_nover_update_test 3.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Deleting module dkms_nover_update_test-3.0 completely from the DKMS tree.
+EOF
+run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_nover_update_test -v 2.0 << EOF
+Module dkms_nover_update_test-2.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
+Before uninstall, this module version was ACTIVE on this kernel.
+
+dkms_nover_update_test.ko${mod_compression_ext}:
+ - Uninstallation
+   - Deleting from: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
+ - Original module
+   - No original module was found for this module on this kernel.
+   - Use the dkms install command to reinstall any previous module version.
+Deleting module dkms_nover_update_test-2.0 completely from the DKMS tree.
+EOF
+run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_nover_update_test -v 1.0 << EOF
+Module dkms_nover_update_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Deleting module dkms_nover_update_test-1.0 completely from the DKMS tree.
+EOF
+run_status_with_expected_output 'dkms_nover_update_test' << EOF
+EOF
+
+echo 'Removing /usr/src/dkms_nover_update_test-{1,2,3}.0'
+rm -r /usr/src/dkms_nover_update_test-{1,2,3}.0
+
 echo 'Checking that the environment is clean'
 check_no_dkms_test
 
+############################################################################
+### Testing dkms autoinstall                                             ###
+############################################################################
+
 echo 'Running autoinstall error testing'
 
 echo 'Adding failing test module by directory'
@@ -995,10 +1288,11 @@
 run_with_expected_error 11 dkms autoinstall -k "${KERNEL_VER}" << EOF
 
 Building module:
-Cleaning build area...(bad exit status: 2)
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} all...(bad exit status: 2)
-Error! Bad return status for module build on kernel: ${KERNEL_VER} ($(uname -m))
+Cleaning build area...
+make -j1 KERNELRELEASE=${KERNEL_VER} all...(bad exit status: 2)
+Error! Bad return status for module build on kernel: ${KERNEL_VER} (${KERNEL_ARCH})
 Consult /var/lib/dkms/dkms_failing_test/1.0/build/make.log for more information.
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} failed for dkms_failing_test(10)
 Error! One or more modules failed to install during autoinstall.
 Refer to previous errors for more information.
 EOF
@@ -1011,10 +1305,11 @@
 run_with_expected_error 11 dkms autoinstall -k "${KERNEL_VER}" << EOF
 
 Building module:
-Cleaning build area...(bad exit status: 2)
-make -j$(nproc) KERNELRELEASE=${KERNEL_VER} all...(bad exit status: 2)
-Error! Bad return status for module build on kernel: ${KERNEL_VER} ($(uname -m))
+Cleaning build area...
+make -j1 KERNELRELEASE=${KERNEL_VER} all...(bad exit status: 2)
+Error! Bad return status for module build on kernel: ${KERNEL_VER} (${KERNEL_ARCH})
 Consult /var/lib/dkms/dkms_failing_test/1.0/build/make.log for more information.
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} failed for dkms_failing_test(10)
 dkms_dependencies_test/1.0 autoinstall failed due to missing dependencies: dkms_failing_test
 Error! One or more modules failed to install during autoinstall.
 Refer to previous errors for more information.
@@ -1022,8 +1317,8 @@
 
 echo 'Removing failing test module'
 run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_failing_test -v 1.0 << EOF
-Module dkms_failing_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
-Module dkms_failing_test 1.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_failing_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Module dkms_failing_test 1.0 is not built for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 Deleting module dkms_failing_test-1.0 completely from the DKMS tree.
 EOF
 echo 'Removing /usr/src/dkms_failing_test-1.0'
@@ -1038,8 +1333,8 @@
 
 echo 'Removing test module with dependencies'
 run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_dependencies_test -v 1.0 << EOF
-Module dkms_dependencies_test 1.0 is not installed for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
-Module dkms_dependencies_test 1.0 is not built for kernel ${KERNEL_VER} ($(uname -m)). Skipping...
+Module dkms_dependencies_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Module dkms_dependencies_test 1.0 is not built for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
 Deleting module dkms_dependencies_test-1.0 completely from the DKMS tree.
 EOF
 echo 'Removing /usr/src/dkms_dependencies_test-1.0'
@@ -1047,5 +1342,205 @@
 
 echo 'Checking that the environment is clean again'
 check_no_dkms_test
+
+############################################################################
+### Testing BUILD_EXCLUSIVE_*                                            ###
+############################################################################
+
+echo 'Running tests with BUILD_EXCLUSIVE_* modules'
+set_signing_message "dkms_test" "1.0"
+
+echo 'Adding the build-exclusive test module by directory'
+run_with_expected_output dkms add test/dkms_build_exclusive_test-1.0 << EOF
+Creating symlink /var/lib/dkms/dkms_build_exclusive_test/1.0/source -> /usr/src/dkms_build_exclusive_test-1.0
+EOF
+run_status_with_expected_output 'dkms_build_exclusive_test' << EOF
+dkms_build_exclusive_test/1.0: added
+EOF
+if ! [[ -d /usr/src/dkms_build_exclusive_test-1.0 ]] ; then
+    echo >&2 'Error: directory /usr/src/dkms_build_exclusive_test-1.0 was not created'
+    return 1
+fi
+
+# Should this really fail?
+echo '(Not) building the build-exclusive test module'
+run_with_expected_error 77 dkms build -k "${KERNEL_VER}" -m dkms_build_exclusive_test -v 1.0 << EOF
+Error! The /var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf for module dkms_build_exclusive_test includes a BUILD_EXCLUSIVE directive which does not match this kernel/arch/config.
+This indicates that it should not be built.
+EOF
+run_status_with_expected_output 'dkms_build_exclusive_test' << EOF
+dkms_build_exclusive_test/1.0: added
+EOF
+
+echo "Running dkms autoinstall (1 x skip)"
+run_with_expected_output dkms autoinstall -k "${KERNEL_VER}" << EOF
+Error! The /var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf for module dkms_build_exclusive_test includes a BUILD_EXCLUSIVE directive which does not match this kernel/arch/config.
+This indicates that it should not be built.
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} was skipped for dkms_build_exclusive_test
+EOF
+run_status_with_expected_output 'dkms_build_exclusive_test' << EOF
+dkms_build_exclusive_test/1.0: added
+EOF
+
+echo 'Adding the test module by directory'
+run_with_expected_output dkms add test/dkms_test-1.0 << EOF
+Creating symlink /var/lib/dkms/dkms_test/1.0/source -> /usr/src/dkms_test-1.0
+EOF
+run_status_with_expected_output 'dkms_test' << EOF
+dkms_test/1.0: added
+EOF
+
+echo "Running dkms autoinstall (1 x skip, 1 x pass)"
+run_with_expected_output dkms autoinstall -k "${KERNEL_VER}" << EOF
+Error! The /var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf for module dkms_build_exclusive_test includes a BUILD_EXCLUSIVE directive which does not match this kernel/arch/config.
+This indicates that it should not be built.
+
+Building module:
+Cleaning build area...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+${SIGNING_MESSAGE}Cleaning build area...
+
+dkms_test.ko${mod_compression_ext}:
+Running module version sanity check.
+ - Original module
+   - No original module exists within this kernel
+ - Installation
+   - Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
+depmod...
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} succeeded for dkms_test
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} was skipped for dkms_build_exclusive_test
+EOF
+run_status_with_expected_output 'dkms_build_exclusive_test' << EOF
+dkms_build_exclusive_test/1.0: added
+EOF
+run_status_with_expected_output 'dkms_test' << EOF
+dkms_test/1.0, ${KERNEL_VER}, ${KERNEL_ARCH}: installed
+EOF
+
+echo 'Unbuilding the test module'
+run_with_expected_output dkms unbuild -k "${KERNEL_VER}" -m dkms_test -v 1.0 << EOF
+Module dkms_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
+Before uninstall, this module version was ACTIVE on this kernel.
+
+dkms_test.ko${mod_compression_ext}:
+ - Uninstallation
+   - Deleting from: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
+ - Original module
+   - No original module was found for this module on this kernel.
+   - Use the dkms install command to reinstall any previous module version.
+EOF
+run_status_with_expected_output 'dkms_test' << EOF
+dkms_test/1.0: added
+EOF
+
+echo 'Adding failing test module by directory'
+run_with_expected_output dkms add test/dkms_failing_test-1.0 << EOF
+Creating symlink /var/lib/dkms/dkms_failing_test/1.0/source -> /usr/src/dkms_failing_test-1.0
+EOF
+
+echo "Running dkms autoinstall (1 x skip, 1 x fail, 1 x pass) (expected error)"
+run_with_expected_error 11 dkms autoinstall -k "${KERNEL_VER}" << EOF
+Error! The /var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf for module dkms_build_exclusive_test includes a BUILD_EXCLUSIVE directive which does not match this kernel/arch/config.
+This indicates that it should not be built.
+
+Building module:
+Cleaning build area...
+make -j1 KERNELRELEASE=${KERNEL_VER} all...(bad exit status: 2)
+Error! Bad return status for module build on kernel: ${KERNEL_VER} (${KERNEL_ARCH})
+Consult /var/lib/dkms/dkms_failing_test/1.0/build/make.log for more information.
+
+Building module:
+Cleaning build area...
+make -j1 KERNELRELEASE=${KERNEL_VER} -C /lib/modules/${KERNEL_VER}/build M=/var/lib/dkms/dkms_test/1.0/build...
+${SIGNING_MESSAGE}Cleaning build area...
+
+dkms_test.ko${mod_compression_ext}:
+Running module version sanity check.
+ - Original module
+   - No original module exists within this kernel
+ - Installation
+   - Installing to /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
+depmod...
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} succeeded for dkms_test
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} was skipped for dkms_build_exclusive_test
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} failed for dkms_failing_test(10)
+Error! One or more modules failed to install during autoinstall.
+Refer to previous errors for more information.
+EOF
+
+echo 'Removing failing test module'
+run_with_expected_output dkms remove -k "${KERNEL_VER}" -m dkms_failing_test -v 1.0 << EOF
+Module dkms_failing_test 1.0 is not installed for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Module dkms_failing_test 1.0 is not built for kernel ${KERNEL_VER} (${KERNEL_ARCH}). Skipping...
+Deleting module dkms_failing_test-1.0 completely from the DKMS tree.
+EOF
+echo 'Removing /usr/src/dkms_failing_test-1.0'
+rm -r /usr/src/dkms_failing_test-1.0
+
+echo 'Removing the test module'
+run_with_expected_output dkms remove --all -m dkms_test -v 1.0 << EOF
+Module dkms_test-1.0 for kernel ${KERNEL_VER} (${KERNEL_ARCH}).
+Before uninstall, this module version was ACTIVE on this kernel.
+
+dkms_test.ko${mod_compression_ext}:
+ - Uninstallation
+   - Deleting from: /lib/modules/${KERNEL_VER}/${expected_dest_loc}/
+ - Original module
+   - No original module was found for this module on this kernel.
+   - Use the dkms install command to reinstall any previous module version.
+Deleting module dkms_test-1.0 completely from the DKMS tree.
+EOF
+run_status_with_expected_output 'dkms_test' << EOF
+EOF
+echo 'Removing /usr/src/dkms_test-1.0'
+rm -r /usr/src/dkms_test-1.0
+
+echo 'Adding the build-exclusive dependencies test module by directory'
+run_with_expected_output dkms add test/dkms_build_exclusive_dependencies_test-1.0 << EOF
+Creating symlink /var/lib/dkms/dkms_build_exclusive_dependencies_test/1.0/source -> /usr/src/dkms_build_exclusive_dependencies_test-1.0
+EOF
+run_status_with_expected_output 'dkms_build_exclusive_dependencies_test' << EOF
+dkms_build_exclusive_dependencies_test/1.0: added
+EOF
+if ! [[ -d /usr/src/dkms_build_exclusive_dependencies_test-1.0 ]] ; then
+    echo >&2 'Error: directory /usr/src/dkms_build_exclusive_dependencies_test-1.0 was not created'
+    return 1
+fi
+
+echo "Running dkms autoinstall (2 x skip, with dependency)"
+run_with_expected_output dkms autoinstall -k "${KERNEL_VER}" << EOF
+Error! The /var/lib/dkms/dkms_build_exclusive_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf for module dkms_build_exclusive_test includes a BUILD_EXCLUSIVE directive which does not match this kernel/arch/config.
+This indicates that it should not be built.
+Error! The /var/lib/dkms/dkms_build_exclusive_dependencies_test/1.0/${KERNEL_VER}/${KERNEL_ARCH}/dkms.conf for module dkms_build_exclusive_dependencies_test includes a BUILD_EXCLUSIVE directive which does not match this kernel/arch/config.
+This indicates that it should not be built.
+dkms autoinstall on ${KERNEL_VER}/${KERNEL_ARCH} was skipped for dkms_build_exclusive_test dkms_build_exclusive_dependencies_test
+EOF
+run_status_with_expected_output 'dkms_build_exclusive_test' << EOF
+dkms_build_exclusive_test/1.0: added
+EOF
+run_status_with_expected_output 'dkms_build_exclusive_dependencies_test' << EOF
+dkms_build_exclusive_dependencies_test/1.0: added
+EOF
+
+echo 'Removing the build-exclusive dependencies test module'
+run_with_expected_output dkms remove --all -m dkms_build_exclusive_dependencies_test -v 1.0 << EOF
+Deleting module dkms_build_exclusive_dependencies_test-1.0 completely from the DKMS tree.
+EOF
+run_status_with_expected_output 'dkms_build_exclusive_dependencies_test' << EOF
+EOF
+echo 'Removing /usr/src/dkms_build_exclusive_dependencies_test-1.0'
+rm -r /usr/src/dkms_build_exclusive_dependencies_test-1.0
+
+echo 'Removing the build-exclusive test module'
+run_with_expected_output dkms remove --all -m dkms_build_exclusive_test -v 1.0 << EOF
+Deleting module dkms_build_exclusive_test-1.0 completely from the DKMS tree.
+EOF
+run_status_with_expected_output 'dkms_build_exclusive_test' << EOF
+EOF
+echo 'Removing /usr/src/dkms_build_exclusive_test-1.0'
+rm -r /usr/src/dkms_build_exclusive_test-1.0
+
+echo 'Checking that the environment is clean again'
+check_no_dkms_test
 
 echo 'All tests successful :)'
diff -Naur dkms-3.0.10/test/dkms_build_exclusive_dependencies_test-1.0/Makefile dkms-3.0.11/test/dkms_build_exclusive_dependencies_test-1.0/Makefile
--- dkms-3.0.10/test/dkms_build_exclusive_dependencies_test-1.0/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_build_exclusive_dependencies_test-1.0/Makefile	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,3 @@
+all:
+	@echo ERROR: This module fails to build.
+	@exit 1
diff -Naur dkms-3.0.10/test/dkms_build_exclusive_dependencies_test-1.0/dkms.conf dkms-3.0.11/test/dkms_build_exclusive_dependencies_test-1.0/dkms.conf
--- dkms-3.0.10/test/dkms_build_exclusive_dependencies_test-1.0/dkms.conf	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_build_exclusive_dependencies_test-1.0/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,6 @@
+PACKAGE_NAME="dkms_build_exclusive_dependencies_test"
+PACKAGE_VERSION="1.0"
+BUILD_DEPENDS="dkms_build_exclusive_test"
+DEST_MODULE_LOCATION="/updates/dkms"
+BUILD_EXCLUSIVE_ARCH="none"
+AUTOINSTALL="yes"
diff -Naur dkms-3.0.10/test/dkms_build_exclusive_test-1.0/Makefile dkms-3.0.11/test/dkms_build_exclusive_test-1.0/Makefile
--- dkms-3.0.10/test/dkms_build_exclusive_test-1.0/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_build_exclusive_test-1.0/Makefile	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,3 @@
+all:
+	@echo ERROR: This module fails to build.
+	@exit 1
diff -Naur dkms-3.0.10/test/dkms_build_exclusive_test-1.0/dkms.conf dkms-3.0.11/test/dkms_build_exclusive_test-1.0/dkms.conf
--- dkms-3.0.10/test/dkms_build_exclusive_test-1.0/dkms.conf	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_build_exclusive_test-1.0/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,5 @@
+PACKAGE_NAME="dkms_build_exclusive_test"
+PACKAGE_VERSION="1.0"
+DEST_MODULE_LOCATION="/updates/dkms"
+BUILD_EXCLUSIVE_ARCH="none"
+AUTOINSTALL="yes"
diff -Naur dkms-3.0.10/test/dkms_conf_test_defaulted_BUILT_MODULE_NAME/dkms.conf dkms-3.0.11/test/dkms_conf_test_defaulted_BUILT_MODULE_NAME/dkms.conf
--- dkms-3.0.10/test/dkms_conf_test_defaulted_BUILT_MODULE_NAME/dkms.conf	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_conf_test_defaulted_BUILT_MODULE_NAME/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,3 @@
+PACKAGE_NAME="dkms_conf_test"
+PACKAGE_VERSION="1.0"
+DEST_MODULE_LOCATION="/updates-dkms-test"
diff -Naur dkms-3.0.10/test/dkms_conf_test_invalid/dkms.conf dkms-3.0.11/test/dkms_conf_test_invalid/dkms.conf
--- dkms-3.0.10/test/dkms_conf_test_invalid/dkms.conf	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_conf_test_invalid/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,6 @@
+PACKAGE_NAME="dkms_conf_test"
+PACKAGE_VERSION="1.0"
+DEST_MODULE_NAME[0]="bar.ko"
+DEST_MODULE_LOCATION="/wrong/path"
+BUILT_MODULE_NAME[1]="bar.o"
+DEST_MODULE_NAME[1]="foo"
diff -Naur dkms-3.0.10/test/dkms_conf_test_zero_modules/dkms.conf dkms-3.0.11/test/dkms_conf_test_zero_modules/dkms.conf
--- dkms-3.0.10/test/dkms_conf_test_zero_modules/dkms.conf	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_conf_test_zero_modules/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,3 @@
+PACKAGE_NAME="dkms_conf_test"
+PACKAGE_VERSION="1.0"
+AUTOINSTALL="yes"
diff -Naur dkms-3.0.10/test/dkms_dependencies_test-1.0/Makefile dkms-3.0.11/test/dkms_dependencies_test-1.0/Makefile
--- dkms-3.0.10/test/dkms_dependencies_test-1.0/Makefile	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/test/dkms_dependencies_test-1.0/Makefile	2023-04-27 17:06:25.000000000 +0200
@@ -1,3 +1,3 @@
 all:
-    @echo ERROR: This module should never build.
-    @exit 1
+	@echo ERROR: This module should never build.
+	@exit 1
diff -Naur dkms-3.0.10/test/dkms_dependencies_test-1.0/dkms.conf dkms-3.0.11/test/dkms_dependencies_test-1.0/dkms.conf
--- dkms-3.0.10/test/dkms_dependencies_test-1.0/dkms.conf	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/test/dkms_dependencies_test-1.0/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -1,4 +1,3 @@
-
 PACKAGE_NAME="dkms_dependencies_test"
 PACKAGE_VERSION="1.0"
 BUILT_MODULE_NAME="dkms_dependencies_test"
diff -Naur dkms-3.0.10/test/dkms_emptyver_test/dkms.conf dkms-3.0.11/test/dkms_emptyver_test/dkms.conf
--- dkms-3.0.10/test/dkms_emptyver_test/dkms.conf	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/test/dkms_emptyver_test/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -1,12 +1,7 @@
-
 PACKAGE_NAME="dkms_emptyver_test"
 PACKAGE_VERSION="1.0"
 BUILT_MODULE_NAME="dkms_emptyver_test"
 
-# MAKE="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules"
-# CLEAN="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build  M=$PWD clean"
-
 AUTOINSTALL="yes"
 
 DEST_MODULE_LOCATION="/kernel/extra"
-
diff -Naur dkms-3.0.10/test/dkms_failing_test-1.0/Makefile dkms-3.0.11/test/dkms_failing_test-1.0/Makefile
--- dkms-3.0.10/test/dkms_failing_test-1.0/Makefile	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/test/dkms_failing_test-1.0/Makefile	2023-04-27 17:06:25.000000000 +0200
@@ -1,3 +1,3 @@
 all:
-    @echo ERROR: This module fails to build.
-    @exit 1"
+	@echo ERROR: This module fails to build.
+	@exit 1
diff -Naur dkms-3.0.10/test/dkms_failing_test-1.0/dkms.conf dkms-3.0.11/test/dkms_failing_test-1.0/dkms.conf
--- dkms-3.0.10/test/dkms_failing_test-1.0/dkms.conf	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/test/dkms_failing_test-1.0/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -1,4 +1,3 @@
-
 PACKAGE_NAME="dkms_failing_test"
 PACKAGE_VERSION="1.0"
 BUILT_MODULE_NAME="dkms_failing_test"
diff -Naur dkms-3.0.10/test/dkms_nover_test/dkms.conf dkms-3.0.11/test/dkms_nover_test/dkms.conf
--- dkms-3.0.10/test/dkms_nover_test/dkms.conf	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_test/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -1,12 +1,7 @@
-
 PACKAGE_NAME="dkms_nover_test"
 PACKAGE_VERSION="1.0"
 BUILT_MODULE_NAME="dkms_nover_test"
 
-# MAKE="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules"
-# CLEAN="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build  M=$PWD clean"
-
 AUTOINSTALL="yes"
 
 DEST_MODULE_LOCATION="/kernel/extra"
-
diff -Naur dkms-3.0.10/test/dkms_nover_update_test/1.0/Makefile dkms-3.0.11/test/dkms_nover_update_test/1.0/Makefile
--- dkms-3.0.10/test/dkms_nover_update_test/1.0/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_update_test/1.0/Makefile	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,7 @@
+obj-m += dkms_nover_update_test.o
+
+all:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
+
+clean:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
diff -Naur dkms-3.0.10/test/dkms_nover_update_test/1.0/dkms.conf dkms-3.0.11/test/dkms_nover_update_test/1.0/dkms.conf
--- dkms-3.0.10/test/dkms_nover_update_test/1.0/dkms.conf	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_update_test/1.0/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,12 @@
+
+PACKAGE_NAME="dkms_nover_update_test"
+PACKAGE_VERSION="1.0"
+BUILT_MODULE_NAME="dkms_nover_update_test"
+
+# MAKE="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules"
+# CLEAN="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build  M=$PWD clean"
+
+AUTOINSTALL="yes"
+
+DEST_MODULE_LOCATION="/kernel/extra"
+
diff -Naur dkms-3.0.10/test/dkms_nover_update_test/1.0/dkms_nover_update_test.c dkms-3.0.11/test/dkms_nover_update_test/1.0/dkms_nover_update_test.c
--- dkms-3.0.10/test/dkms_nover_update_test/1.0/dkms_nover_update_test.c	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_update_test/1.0/dkms_nover_update_test.c	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("A Simple dkms test module with no version");
+
+static int __init dkms_test_init(void)
+{
+    printk(KERN_INFO "DKMS Test Module - Loaded\n");
+    return 0;
+}
+
+static void __exit dkms_test_cleanup(void)
+{
+    printk(KERN_INFO "Cleaning up after dkms test module.\n");
+}
+
+module_init(dkms_test_init);
+module_exit(dkms_test_cleanup);
diff -Naur dkms-3.0.10/test/dkms_nover_update_test/2.0/Makefile dkms-3.0.11/test/dkms_nover_update_test/2.0/Makefile
--- dkms-3.0.10/test/dkms_nover_update_test/2.0/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_update_test/2.0/Makefile	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,7 @@
+obj-m += dkms_nover_update_test.o
+
+all:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
+
+clean:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
diff -Naur dkms-3.0.10/test/dkms_nover_update_test/2.0/dkms.conf dkms-3.0.11/test/dkms_nover_update_test/2.0/dkms.conf
--- dkms-3.0.10/test/dkms_nover_update_test/2.0/dkms.conf	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_update_test/2.0/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,12 @@
+
+PACKAGE_NAME="dkms_nover_update_test"
+PACKAGE_VERSION="2.0"
+BUILT_MODULE_NAME="dkms_nover_update_test"
+
+# MAKE="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules"
+# CLEAN="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build  M=$PWD clean"
+
+AUTOINSTALL="yes"
+
+DEST_MODULE_LOCATION="/kernel/extra"
+
diff -Naur dkms-3.0.10/test/dkms_nover_update_test/2.0/dkms_nover_update_test.c dkms-3.0.11/test/dkms_nover_update_test/2.0/dkms_nover_update_test.c
--- dkms-3.0.10/test/dkms_nover_update_test/2.0/dkms_nover_update_test.c	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_update_test/2.0/dkms_nover_update_test.c	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("A Simple dkms test module with no version!");
+
+static int __init dkms_test_init(void)
+{
+    printk(KERN_INFO "DKMS Test Module - Loaded\n");
+    return 0;
+}
+
+static void __exit dkms_test_cleanup(void)
+{
+    printk(KERN_INFO "Cleaning up after dkms test module.\n");
+}
+
+module_init(dkms_test_init);
+module_exit(dkms_test_cleanup);
diff -Naur dkms-3.0.10/test/dkms_nover_update_test/3.0/Makefile dkms-3.0.11/test/dkms_nover_update_test/3.0/Makefile
--- dkms-3.0.10/test/dkms_nover_update_test/3.0/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_update_test/3.0/Makefile	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,7 @@
+obj-m += dkms_nover_update_test.o
+
+all:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
+
+clean:
+	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
diff -Naur dkms-3.0.10/test/dkms_nover_update_test/3.0/dkms.conf dkms-3.0.11/test/dkms_nover_update_test/3.0/dkms.conf
--- dkms-3.0.10/test/dkms_nover_update_test/3.0/dkms.conf	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_update_test/3.0/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,12 @@
+
+PACKAGE_NAME="dkms_nover_update_test"
+PACKAGE_VERSION="3.0"
+BUILT_MODULE_NAME="dkms_nover_update_test"
+
+# MAKE="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules"
+# CLEAN="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build  M=$PWD clean"
+
+AUTOINSTALL="yes"
+
+DEST_MODULE_LOCATION="/kernel/extra"
+
diff -Naur dkms-3.0.10/test/dkms_nover_update_test/3.0/dkms_nover_update_test.c dkms-3.0.11/test/dkms_nover_update_test/3.0/dkms_nover_update_test.c
--- dkms-3.0.10/test/dkms_nover_update_test/3.0/dkms_nover_update_test.c	1970-01-01 01:00:00.000000000 +0100
+++ dkms-3.0.11/test/dkms_nover_update_test/3.0/dkms_nover_update_test.c	2023-04-27 17:06:25.000000000 +0200
@@ -0,0 +1,20 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("A Simple dkms test module with no version!");
+
+static int __init dkms_test_init(void)
+{
+    printk(KERN_INFO "DKMS Test Module - Loaded\n");
+    return 0;
+}
+
+static void __exit dkms_test_cleanup(void)
+{
+    printk(KERN_INFO "Cleaning up after dkms test module.\n");
+}
+
+module_init(dkms_test_init);
+module_exit(dkms_test_cleanup);
diff -Naur dkms-3.0.10/test/dkms_test-1.0/dkms.conf dkms-3.0.11/test/dkms_test-1.0/dkms.conf
--- dkms-3.0.10/test/dkms_test-1.0/dkms.conf	2023-01-03 10:29:53.000000000 +0100
+++ dkms-3.0.11/test/dkms_test-1.0/dkms.conf	2023-04-27 17:06:25.000000000 +0200
@@ -1,12 +1,7 @@
-
 PACKAGE_NAME="dkms_test"
 PACKAGE_VERSION="1.0"
 BUILT_MODULE_NAME="dkms_test"
 
-# MAKE="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build modules"
-# CLEAN="make -C /lib/modules/${kernelver}/build SUBDIRS=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build  M=$PWD clean"
-
 AUTOINSTALL="yes"
 
 DEST_MODULE_LOCATION="/kernel/extra"
-
