Command to rebuild all DKMS modules for all installed kernels?

671

Solution 1

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.

Solution 2

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.

Solution 3

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

Solution 4

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)

Solution 5

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
Share:
671

Related videos on Youtube

scatman
Author by

scatman

Updated on September 18, 2022

Comments

  • scatman
    scatman over 1 year

    i am using VS08 to build/run the following c++ code:

    #include <stdlib.h>
    
    struct Header
    {   
      int count;
    }*lstHeader=NULL;
    
    int main()
    {
        for(int i=0;i<10;i++)
        {
            lstHeader=(Header*)realloc(lstHeader,sizeof(Header)+i);
            lstHeader[i].count=i;
        }
        return 1;
    }
    

    and after running i get the following VS exception:

    Windows has triggered a breakpoint in MyProgram.exe.
    
    This may be due to a corruption of the heap, which indicates a bug in 
    MyProgram.exe or any of the DLLs it has loaded.
    
    This may also be due to the user pressing F12 while MyProgram.exe has focus.
    
    The output window may have more diagnostic information.
    

    i have tried to malloc lstHeader instead of assigning it to NULL, but the same VS exception occured and i can't figure y.

    • Admin
      Admin about 11 years
      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 ;)
  • frankster
    frankster about 12 years
    it gave some errors because it came up headers-xxx and headers-xxx-generic but it seemed to rebuild the correct stuff despite the errors
  • Ryan C. Thompson
    Ryan C. Thompson about 8 years
    Could you elaborate on what this does that the other methods don't?
  • stu
    stu about 8 years
    It works on systems that don't have /usr/src/linux-headers-* and /var/lib/initramfs-tools
  • stu
    stu about 8 years
    consider 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.
  • m1st0
    m1st0 over 6 years
    @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