Occasionally, my system gets into a state where some kernels are missing a module or two, because DKMS somehow forgot to compile those modules for that kernel. Rather than spend time diagnosing the problem, it would be nice if there was a single command I could run that woudl just rebuild every dkms-controlled module for every installed kernel. Is there such a command?
-
I always get the output Module broadcom-sta/5.100.82.112 already installed on kernel 2.6.38jon-64/x86_64 I really want a --force or a --rebuild --just-do-what-i-say option ;) – Mar 14 '13 at 21:14
8 Answers
I figured out a shell one-liner to do it:
ls /var/lib/initramfs-tools | \
sudo xargs -n1 /usr/lib/dkms/dkms_autoinstaller start
This works because the names of the directories in /var/lib/initramfs-tools
are exactly the kernel version names that you need to pass to dkms_autoinstaller
to tell it to rebuild all modules for those kernel versions. Note that if you have uninstalled some old kernels, their directories might still be lying around and cause some errors to be reported, but this isn't a problem because dkms_autoinstaller
will just do nothing for those kernel versions that aren't installed.

- 4,426
-
1it gave some errors because it came up headers-xxx and headers-xxx-generic but it seemed to rebuild the correct stuff despite the errors – frankster Feb 14 '12 at 19:09
-
@frankster After finding multiple "Error! Could not locate dkms.conf file." for a new kernel installation, I was able to install previous kernel modules listed by
dkms status
to the new kernel using the following per specific modules I wanted from "/usr/src" . Parameters need to be changed as needed for -c, -m, -v . Here is an example for the nvidia-384-384.90 module:
ls /var/lib/initramfs-tools | \ sudo xargs -n1 /usr/sbin/dkms install -c /usr/src/nvidia-384-384.90/dkms.conf -m nvidia -v 384-384.90 -k
– m1st0 Oct 24 '17 at 11:14 -
1
/var/lib/initramfs-tools
is no more populated forLTS 22.04
nor Debianbullseye
(directory is missing) – Tino May 16 '23 at 09:46 -
/usr/lib/dkms/dkms_autoinstaller start
worked after booting into the kernel I needed to build for. – tmm1 Aug 18 '23 at 00:16
Doesn't look like the dkms
command allows you to do that. I created a small Python script that should do what you want. You can put an alias in your ~/.bashrc
like
alias dkms-buildall='sudo ./wherever/your/script/is'
Of course you'd need to make it executable first. Here's the code:
#!/bin/env python
#
# NOTE: This assumes that all modules and versions are built for at
# least one kernel. If that's not the case, adapt parsing as needed.
import os
import subprocess
# Permission check.
if os.geteuid() != 0:
print "You need to be root to run this script."
exit(1)
# Get DKMS status output.
cmd = ['dkms', 'status']
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
dkms_status = process.communicate()[0].strip('\n').split('\n')
dkms_status = [x.split(', ') for x in dkms_status]
# Get kernel versions (probably crap).
cmd = ['ls', '/var/lib/initramfs-tools/']
# Alternative (for use with Arch Linux for example)
# cmd = ['ls', '/usr/lib/modules/']
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
kernels = process.communicate()[0].strip('\n').split('\n')
# Parse output, 'modules' will contain all modules pointing to a set
# of versions.
modules = {}
for entry in dkms_status:
module = entry[0]
version = entry[1].split(': ')[0]
try:
modules[module].add(version)
except KeyError:
# We don't have that module, add it.
modules[module] = set([version])
# For each module, build all versions for all kernels.
for module in modules:
for version in modules[module]:
for kernel in kernels:
cmd = ['dkms', 'build', '-m', module, '-v', version, '-k', kernel]
ret = subprocess.call(cmd)
Tested it here, seems to work just fine:
$ dkms status
nvidia-current, 275.09.07, 3.0.0-5-generic, x86_64: installed
virtualbox, 4.0.10, 3.0.0-5-generic, x86_64: installed
$ sudo python dkms.py
...
$ dkms status
nvidia-current, 275.09.07, 3.0.0-5-generic, x86_64: installed
nvidia-current, 275.09.07, 3.0-2-generic, x86_64: built
nvidia-current, 275.09.07, 3.0-3-generic, x86_64: built
virtualbox, 4.0.10, 3.0.0-5-generic, x86_64: installed
virtualbox, 4.0.10, 3.0-2-generic, x86_64: built
virtualbox, 4.0.10, 3.0-3-generic, x86_64: built
If you also want to install the modules, replace build with install in the second last line.

- 64,798
Combining @htorque and @Ryan Thompson's answers, here's my (as root) one-liner:
dkms status | sed s/,//g | awk '{print "-m",$1,"-v",$2}' | while read line; do ls /var/lib/initramfs-tools | xargs -n 1 dkms install $line -k; done

- 309
Don't have enough reputation to comment @Ryan Thompson
's answer, but this might be useful to somebody. In Ubuntu 22.04 there's no /var/lib/initramfs-tools
directory, however, there're initrd.img-<kernel version>
images present in /boot
per every installed kernel version, and these <kernel version>
are exactly what dkms
(and dkms_autoinstaller
) needs. So let's use them:
ls /boot/initrd.img-* | cut -d- -f2- | \
sudo xargs -n1 /usr/lib/dkms/dkms_autoinstaller start
An edit of script by @htorque. Use it in case you want a forcerebuild (and install) of already built modules. Switched to python3, subprocess.run()
requires Python 3.5+.
#!/usr/bin/env python3
#
# NOTE: This assumes that all modules and versions are built for at
# least one kernel. If that's not the case, adapt parsing as needed.
import os
import subprocess
import re
Permission check.
if os.geteuid() != 0:
print("You need to be root to run this script.")
exit(1)
Get DKMS status output.
cmd = ['dkms', 'status']
dkms_status = subprocess.run(cmd, stdout=subprocess.PIPE).stdout.decode("utf-8").strip('\n').split('\n')
dkms_status = [re.split(', |/', x) for x in dkms_status]
Get kernel versions (probably crap).
#cmd = ['ls', '/var/lib/initramfs-tools/'] # Does not work on Ubuntu 22.04
Alternative (for use with Arch Linux for example)
cmd = ['ls', '/usr/lib/modules/']
#kernels = subprocess.run(cmd, stdout=subprocess.PIPE).stdout.decode("utf-8").strip('\n').split('\n')
Works on 22.04
prefix = 'initrd.img-'
kernels = [k[len(prefix):] for k in os.listdir('/boot')
if k.startswith(prefix)]
Parse output, 'modules' will contain all modules pointing to a set
of versions.
modules = {}
for entry in dkms_status:
module = entry[0]
version = entry[1].split(': ')[0]
try:
modules[module].add(version)
except KeyError:
# We don't have that module, add it.
modules[module] = set([version])
For each module, build all versions for all kernels.
for module in modules:
for version in modules[module]:
for kernel in kernels:
for action in ['remove', 'install']:
cmd = ['dkms', action, '-m', module, '-v', version, '-k', kernel]
subprocess.run(cmd)
The above don't work on all variants, this might be a bit more helpful in those cases...
$modulename="whatever"
$moduleversion=`modinfo $modulename | grep "^version:" | awk '{ print $2 }'`
dkms status | grep $modulename | tr -d ',' | awk '{ print $3 }' | xargs -n1 dkms build $modulename/$moduleversion -k

- 173
-
Could you elaborate on what this does that the other methods don't? – Ryan C. Thompson Feb 19 '16 at 23:00
-
1It works on systems that don't have /usr/src/linux-headers-* and /var/lib/initramfs-tools – stu Feb 21 '16 at 12:43
-
1consider the situation where you need it to run on many various linux distros that only have the fact that dkms (sort of) works, in common. – stu Feb 21 '16 at 12:43
dkms status
and dkms_autoinstaller
does not work in ubuntu 16.x. So some shell script will do.
This script assumed you have proper *-dkms
deb-package installed, and bash
is your shell.
for k in $(ls /var/lib/initramfs-tools) ; do
for d in $(cd /usr/src; ls -d *-*) ; do
[[ -f /usr/src/${d}/dkms.conf ]] || continue
m=$(echo $d | sed -r -e 's/-([0-9]).+//')
v=$(echo $d | sed -r -e 's/[^0-9]+-([0-9])/\1/')
sudo /usr/sbin/dkms install -c /usr/src/$d/dkms.conf -m $m -v $v -k $k
done
done

- 101
You can also simply invoke update-initramfs -u and it will do it for you.
-
2
update-initramfs -u
only does it for one kernel, not "all installed kernels" as the question asks – Daniel T Feb 29 '24 at 18:30 -
2This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - From Review – Daniel T Feb 29 '24 at 18:31