webentwicklung-frage-antwort-db.com.de

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

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?

38
Ryan Thompson

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.

47
Ryan Thompson

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.

8
htorque

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
3
phs

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
1
stu

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 
0
sehari24jam