How do you define dkms.conf such that a DKMS module will only be built for specific kernel version or range of versions?
Background:
A buggy driver is present in the the current kernels we are using (eg 4.4) but fixed in 4.10. I produced as dkms package with the 4.10 source code in it, which all works fine on kernel 4.4. But as we update to later OS releases (or HWE releases) with later kernel releases - eg 4.15 - I want to avoid rebuilding the (now possibly older) 4.10 kernel driver when the kernel version is 4.10 or higher.
Here's my base dkms.conf
file
PACKAGE_NAME="cp210x"
PACKAGE_VERSION="#MODULE_VERSION#"
BUILT_MODULE_NAME[0]="$PACKAGE_NAME"
DEST_MODULE_LOCATION[0]="/updates/dkms"
AUTOINSTALL="YES"
REMAKE_INITRD="YES"
I tried BUILD_EXCLUSIVE_KERNEL
matching to 4.N kernel versions
BUILD_EXCLUSIVE_KERNEL="^4\.[0-9]\.*"
Expected behaviour - will not install the kernel module for kernel 4.15.0-43-generic
. Actual behaviour - installs as normal
My reading suggests an alternate might work (for this test I'm just matching my current kernel version) to change the compile rule to be a no-op.
MAKE_MATCH[1]="^4\.15\.*"
MAKE[1]=":"
I'm on Debian/Ubuntu platforms if that makes any difference.
Ok - the problem was between keyboard and chair - my BUILD_EXCLUSIVE_KERNEL
regexp had an error in it - the .*
suffix got mixed with the \.
number separator. But I'll document a working example here since google didn't find any good examples before I posted here:
Firstly I wasn't sure what regexp dialect I needed to be using (grep, pcre, etc,..) especially since there is shell escaping mixed in, so thought perhaps the mismatch was there.
Turns out dkms
is a bash
script and so uses [[ $ver =~ $match_regexp ]]
. So to test the matching this worked:
re="^(3\.[0-9]+\.|4\.[0-9]\.)" ; [[ "4.15.0-43-generic" =~ $re ]] && echo true
# but this didn't
[[ "4.15.0-43-generic" =~ "^(3\.[0-9]+\.|4\.[0-9]\.)" ]] && echo true
Here's the config file I ended up using:
PACKAGE_NAME="cp210x"
PACKAGE_VERSION="#MODULE_VERSION#"
BUILT_MODULE_NAME[0]="$PACKAGE_NAME"
DEST_MODULE_LOCATION[0]="/updates/dkms"
AUTOINSTALL="YES"
REMAKE_INITRD="YES"
# Since this code comes from 4.10 only update kernels 4.9 and earlier
BUILD_EXCLUSIVE_KERNEL="^(3\.[0-9]+\.|4\.[0-9]\.)"
Which looks like this when installed via dpkg
.
First Installation: checking all kernels...
Building only for 4.15.0-43-generic
Building initial module for 4.15.0-43-generic
Error! The dkms.conf for this module includes a BUILD_EXCLUSIVE directive which
does not match this kernel/arch. This indicates that it should not be built.
Skipped.
But installs correctly against lower kernel versions.
Additionally the wording of the BUILD_EXCLUSIVE_KERNEL
documentation suggests it is an error if the kernel mismatches which might not be desirable, however if you check the output above you'll see that the "Error" does not cause a package installation failure, just marked as skipped.