dkms remove fails if /lib/modules/XXXX/modules.dep file not found
If the file modules.dep does not exist, because the directory has been removed or just cleaned up from an uninstall, then dkms remove fails with the message:
There is no instance of $module $module_version for kernel $1 ($2) located in the DKMS tree
Tracing back through the code, the issue is that the variable "module_compressed_suffix" is not set, as modules.dep does not exist, and hence it does not find the built module in the DKMS tree, if it is a compressed module. This then fails the remove_module function, and does not remove the files out of the DKMS tree.
A reasonable thing to do is to simply ignore the compressed_suffix and use rm /path/to/module/module.ko*. Although it might not be as trivial - haven't looked at that code.
Emil,
While I agree that using "module.ko*" would be a sensible idea, it wouldn't work in this case, as actually fails in a test to see if the file with different extensions exist. It would need to further code rearrangements for it to work.
Frank
On Mon, 2021-10-11 at 12:15 -0700, Emil Velikov wrote:
A reasonable thing to do is to simply ignore the compressed_suffix and use rm /path/to/module/module.ko*. Although it might not be as trivial - haven't looked at that code. — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.
I ran into a problem related to this issue on Arch Linux, which allows installing and uninstalling the kernel image and headers independently. If you uninstall the kernel image first (which removes modules.dep, and thus due to this issue various commands like dkms status return wrong results), then the kernel headers later, Arch's hooks get confused and fail to properly remove the modules. I tried to explain the flow though which this happens here: https://bugs.archlinux.org/task/73654#comment221041 (CC @evelikov)
As others have noted, the problem comes from the variable $module_compressed_suffix being set from reading modules.dep, which may not be always available. And in Arch's case, actually none of the kernel image's files may be available - only the headers.
My first idea was that you could set the value by reading (CONFIG_MODULE_COMPRESS_(GZIP|XZ|ZSTD)) from Kconfig (/lib/modules/$kernel_ver/build/.config) instead. But, I found that some distributions like as Almalinux 8, which have .xz-compressed modules, leave CONFIG_MODULE_COMPRESS unset (and presumably compress the modules using something else instead). So this appears to be a dead end.
The best fix I found is to remove the use of $module_compressed_suffix in compressed_or_uncompressed() and try all extensions instead:
diff --git a/dkms.in b/dkms.in
index ef94ad1..9de3a33 100644
--- a/dkms.in
+++ b/dkms.in
@@ -193,13 +193,13 @@ compressed_or_uncompressed()
{
# module dir = $1
# module = $2
- local test1="$1/$2$module_uncompressed_suffix"
- local test2="$1/$2$module_uncompressed_suffix$module_compressed_suffix"
- if [[ -e "$test1" ]]; then
- echo "$test1"
- elif [[ -e "$test2" ]]; then
- echo "$test2"
- fi
+ for suffix in "" .gz .xz .zst; do
+ local test="$1/$2$module_uncompressed_suffix$suffix"
+ if [[ -e "$test" ]]; then
+ echo "$test"
+ break
+ fi
+ done
}
# Finds .ko or .ko.xz based on a tree and module name
As far as I can tell, this fixes the issue as reported by the OP. The only loose end is that there is another use of $module_compressed_suffix outside compressed_or_uncompressed() which is used to compress a module once it is built, but the only side effect of failing to set $module_compressed_suffix is that the built module would be left uncompressed.
My first idea was that you could set the value by reading (CONFIG_MODULE_COMPRESS_(GZIP|XZ|ZSTD)) from Kconfig (/lib/modules/$kernel_ver/build/.config) instead.
First ideas are usually the best ;-)
Not a fan of the proposed semi-random file look-ups since it's not an indication that a) the user did not manually un/compressed the file and b) it will work.
Usually it's kmod (or the busybox variant) doing the decompression before passing the module to the kernel, although upcoming work will defer the decompression to the kernel itself. While I don't think we can easily ~~cannot~~ check for the kmod capabilities (if at all), the CONFIG is a clear explicit agreement that things should work.
As an example the default make ... kernel command will honour the CONFIG option, so on my Arch box dkms rightfully produces zstd compressed modules.
But, I found that some distributions like as Almalinux 8, which have .xz-compressed modules, leave CONFIG_MODULE_COMPRESS unset (and presumably compress the modules using something else instead). So this appears to be a dead end.
Is that for distro modules or dkms ones? I'm not sure how this can affect us*, although if needed we can add a quirk/override via /etc/dkms/framework.conf - say force_module_extension. Look for modprobe_on_install across the codebase for details.
If you can submit a MR + a trivial test or two that would be amazing.
Couple of test ideas, feel free to add extra/change/extend as you see fit:
dkms add foobar; dkms build foobar; mv ..../modules.dep{,.missing};check thedkms status;mv back; repeat withinstall- loop through none, gzip, xz, zstd - set the CONFIG_MODULE_COMPRESS in .config as applicable, dkms add/build foobar; test -f ....ko.$extension