Befehl, alle DKMS-Module für alle installierten Kernel neu zu erstellen?


39

Gelegentlich gerät mein System in einen Zustand, in dem einigen Kerneln ein oder zwei Module fehlen, weil die DKMS irgendwie vergessen hat, diese Module für diesen Kernel zu kompilieren. Anstatt Zeit damit zu verbringen, das Problem zu diagnostizieren, wäre es schön, wenn es einen einzigen Befehl gäbe, den ich ausführen könnte, um einfach jedes dkms-gesteuerte Modul für jeden installierten Kernel neu zu erstellen . Gibt es so einen Befehl?


Ich bekomme immer das Ausgangsmodul broadcom-sta / 5.100.82.112, das bereits auf Kernel 2.6.38jon-64 / x86_64 installiert ist. Ich möchte wirklich eine Option --force oder --rebuild --just-do-what-i-say;)

Antworten:


47

Ich habe einen Shell-One-Liner dafür gefunden:

ls /var/lib/initramfs-tools | \
    sudo xargs -n1 /usr/lib/dkms/dkms_autoinstaller start

Dies funktioniert, da die Namen der Verzeichnisse /var/lib/initramfs-toolsgenau die Namen der Kernelversionen sind, die Sie übergeben müssen, um dkms_autoinstalleranzugeben, dass alle Module für diese Kernelversionen neu erstellt werden sollen. Beachten Sie, dass, wenn Sie einige alte Kernel deinstalliert haben, deren Verzeichnisse möglicherweise immer noch herumliegen und Fehler melden. Dies ist jedoch kein Problem, da dkms_autoinstallerdies für die nicht installierten Kernelversionen nichts bewirkt .


1
es gab einige fehler, weil es auftauchte headers-xxx und headers-xxx-generic, aber es schien trotz der fehler das richtige
zeug wiederherzustellen

@frankster Nach dem Auffinden mehrerer "Fehler! Konnte die Datei dkms.conf nicht finden." Für eine neue Kernel-Installation konnte ich frühere Kernel-Module, die von aufgelistet wurden dkms status, mit den folgenden spezifischen Modulen, die ich von "/ usr / src" wollte, auf dem neuen Kernel installieren . Die Parameter müssen nach Bedarf für -c, -m, -v geändert werden. Hier ist ein Beispiel für das nvidia-384-384.90-Modul: 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

8

Sieht nicht so aus, als ob der dkmsBefehl dies zulässt. Ich habe ein kleines Python-Skript erstellt, das tun soll, was Sie wollen. Sie können einen Alias ​​in Ihr ~/.bashrcLike einfügen

alias dkms-buildall='sudo ./wherever/your/script/is'

Natürlich müssen Sie es zuerst ausführbar machen. Hier ist der 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)

Hier getestet, scheint gut zu funktionieren:

$ 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

Wenn Sie auch die Module installieren möchten, ersetzen Sie build durch install in der vorletzten Zeile.


4

Hier ist mein (als Root) Einzeiler, der die Antworten von @htorque und @Ryan Thompson kombiniert:

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

1

Die obigen Einstellungen funktionieren nicht bei allen Varianten, dies könnte in diesen Fällen etwas hilfreicher sein ...

$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

Könnten Sie näher erläutern, was die anderen Methoden nicht bewirken?
Ryan Thompson

Es funktioniert auf Systemen ohne / usr / src / linux-headers- * und / var / lib / initramfs-tools
stu

Betrachten Sie die Situation, in der Sie es benötigen, um auf vielen verschiedenen Linux-Distributionen zu laufen, die nur die Tatsache haben, dass dkms (irgendwie) gemeinsam funktioniert.
Dienstag,

0

dkms statusund dkms_autoinstallerfunktioniert nicht in Ubuntu 16.x. Also genügt ein Shell-Skript. Dieses Skript setzt voraus, dass Sie das richtige *-dkmsDeb-Paket installiert haben und bashes Ihre Shell ist.

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 
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.