Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dkms remove fails if /lib/modules/XXXX/modules.dep file not found #166

Open
frankcrawford opened this issue Oct 10, 2021 · 4 comments
Open

Comments

@frankcrawford
Copy link

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.

@evelikov
Copy link
Collaborator

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.

@frankcrawford
Copy link
Author

frankcrawford commented Oct 12, 2021 via email

@joanbm
Copy link

joanbm commented Aug 20, 2023

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.

@evelikov
Copy link
Collaborator

evelikov commented Aug 29, 2023

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 the dkms status; mv back; repeat with install
  • loop through none, gzip, xz, zstd - set the CONFIG_MODULE_COMPRESS in .config as applicable, dkms add/build foobar; test -f ....ko.$extension

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants