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, der einfach neu erstellt alle dkms-gesteuertes Modul für alle installierten Kernel. Gibt es so einen Befehl?
Ich habe einen Shell-Einzeiler dafür gefunden:
ls /var/lib/initramfs-tools | \
Sudo xargs -n1 /usr/lib/dkms/dkms_autoinstaller start
Dies funktioniert, da die Namen der Verzeichnisse in /var/lib/initramfs-tools
genau die Namen der Kernelversionen sind, die Sie an dkms_autoinstaller
übergeben müssen, damit alle Module für diese Kernelversionen neu erstellt werden. 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_autoinstaller
nur nichts für die Kernelversionen tut, die es nicht sind Eingerichtet.
Sieht nicht so aus, als ob Sie dies mit dem Befehl dkms
tun könnten. Ich habe ein kleines Python Skript erstellt, das tun soll, was Sie wollen. Sie können einen Alias in Ihr ~/.bashrc
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.
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
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
dkms status
und dkms_autoinstaller
funktionieren in Ubuntu 16.x nicht. Also genügt ein Shell-Skript. In diesem Skript wird davon ausgegangen, dass Sie das richtige Deb-Paket *-dkms
installiert haben und bash
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