ELRepo's kmod packages provide new or updated kernel drivers (.ko files). When the driver is an update, that is it replaces a distro kernel driver of the same name, the system needs to know which driver to load. This is handled by depmod and is based on a search ordering system defined in /etc/depmod.d/dist.conf
# # depmod.conf # # override default search ordering for kmod packaging search updates extra built-in weak-updates
This shows us the defined order from where kernel modules will be loaded. For example, consider an imaginary kernel module foo.ko. The system will search in /lib/modules/{kernel_version}/{updates,extra,kernel,weak-updates/} for the module to load (built-in in the list above represents the native kernel driver).
ELRepo's kmod packages install the driver to extra under the kernel for which it was built. For example, if kmod-foo was built against kernel-5.14.0.el9 then it would be installed to /lib/modules/5.14.0.el9/extra/foo/foo.ko. Because extra takes precedence over the native built-in kernel driver, when kernel-5.14.0.el9 is booted the updated foo driver would be loaded.
But what about other kernels? ELRepo's kmod packages are kABI-tracking and this allows the driver to be automatically installed for all kABI compatible kernels. This is achieved by the weak-modules script which is run during package installation and creates a symlink for all compatible kernels to /lib/modules/5.14.0.el9/extra/foo/foo.ko in /lib/modules/{kernel_version}/weak-updates.
However, above we saw that the native built-in kernel driver takes precedence over any driver in weak-updates, so each kmod package ships with an override file (/etc/depmod.d/kmod-foo.conf) that overrides the order for that individual driver.
The format of the the override file is:
override module_name kernel_to_override module_location
So for our imaginary package kmod-foo, we would have an override file containing a single line:
override foo * weak-updates/foo
which says we wish to “override” the module “foo” in all kernels “*” and that the new module is located in “weak-updates/foo”
Note we use a wildcard (*) to represent that we wish this override to apply for all kernels.
Now we know how to override a driver for all kernel releases. What happens when we want to deprecate a driver? Maybe the latest Red Hat update series kernel has a newer native kernel driver and we wish to default back to that.
For reference, the RHEL-9 kernel series are:
kernel-5.14.0-70.13.1.el9_0 kernel-5.14.0-162.6.1.el9_1 kernel-5.14.0-284.11.1.el9_2 kernel-5.14.0-362.8.1.el9_3
Lets look at an example for kmod-foo. In this example we need to deprecate our driver because Red Hat releases a newer driver.
1. RHEL-9.0 is released
We release an updated driver kmod-foo for RHEL-9.0. It is built against kernel-5.14.0-70.13.1.el9_0 and installed to /lib/modules/5.14.0-70.13.1.el9_0/extra/foo/foo.ko
Our override file will look like:
override foo * weak-updates/foo
and will override foo for all kernels.
2. RHEL-9.1 is released
Our driver is still newer than the distro driver and because it's still kABI-compatible the module is weak-linked and continues to override the native kernel driver for the new 5.14.0-162.6.1.el9_1 series kernels so we don't need to do anything.
3. RHEL-9.2 is released
With the release of kernel-5.14.0-284.11.1.el9_2 we see that Red Hat has updated foo to the very latest version and it's now equal or newer than our kmod driver so we would like to deprecate our driver in favour of the native kernel driver. But we still want to use the newer driver for older 9.0 and 9.1 kernels. Therefore we only want to deprecate against the newer 9.2 series kernels.
To achieve this we adjust our override file to only override the desired kernel series:
override foo 5.14.0-70.* weak-updates/foo override foo 5.14.0-162.* weak-updates/foo
Now we have explicitly listed each kernel series we wish to override allowing older kernels to still benefit from the an updated driver whilst allowing newer kernels not matched by the expressions to use the newer native kernel driver.
4. RHEL-9.3 is released
Red Hat haven't updated the driver any further, but during the life cycle of RHEL-9.3 a newer driver becomes available upstream and we wish to update kmod-foo to this newer version. Because it's a newer version we can simply update the package and revert to overriding all kernels again:
override foo * weak-updates/foo