Polecenie przebudowania wszystkich modułów DKMS dla wszystkich zainstalowanych jąder?

39

Czasami mój system przechodzi w stan, w którym w niektórych jądrach brakuje modułu lub dwóch, ponieważ DKMS jakoś zapomniał skompilować te moduły dla tego jądra. Zamiast spędzać czas na diagnozowaniu problemu, byłoby miło, gdyby istniało jedno polecenie, które mógłbym uruchomić, aby po prostu odbudować każdy moduł kontrolowany przez dkms dla każdego zainstalowanego jądra. Czy istnieje takie polecenie?

Ryan Thompson
źródło
Zawsze otrzymuję moduł wyjściowy broadcom-sta / 5.100.82.112 już zainstalowany na jądrze 2.6.38jon-64 / x86_64 Naprawdę chcę opcji --force lub --rebuild - just-do-what-i-say;)

Odpowiedzi:

47

Wymyśliłem skorupkę z jedną wkładką, aby to zrobić:

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

Działa to, ponieważ nazwy katalogów w /var/lib/initramfs-toolssą dokładnie tymi nazwami wersji jądra, które należy przekazać, dkms_autoinstalleraby nakazać przebudowę wszystkich modułów dla tych wersji jądra. Zauważ, że jeśli odinstalowałeś niektóre stare jądra, ich katalogi mogą nadal leżeć i powodować zgłaszanie błędów, ale to nie jest problem, ponieważ dkms_autoinstallernic nie zrobi dla tych wersji jądra, które nie są zainstalowane.

Ryan Thompson
źródło
1
dało trochę błędów, ponieważ pojawiło się nagłówki-xxx i nagłówki-xxx-ogólne, ale mimo błędów wydawało się, że odbudowuje prawidłowe rzeczy
frankster
@frankster Po znalezieniu wielu „Błąd! Nie można znaleźć pliku dkms.conf”. w przypadku nowej instalacji jądra byłem w stanie zainstalować poprzednie moduły jądra wymienione na liście dkms statusdo nowego jądra, korzystając z poniższych dla określonych modułów, które chciałem od „/ usr / src”. Parametry należy zmienić zgodnie z potrzebami dla opcji -c, -m, -v. Oto przykład modułu nvidia-384-384.90: 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

Nie wygląda na to, że dkmspolecenie to pozwala. Stworzyłem mały skrypt Pythona, który powinien robić, co chcesz. Można umieścić aliasu w ~/.bashrcLike

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

Oczywiście najpierw musisz go wykonać. Oto kod:

#!/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)

Testowałem to tutaj, wydaje się działać dobrze:

$ 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

Jeśli chcesz także zainstalować moduły, wymienić build z zainstalowania w przedostatnim wierszu.

htorque
źródło
4

Łącząc odpowiedzi @htorque i @Ryan Thompson, oto moja (jako root) jedna linijka:

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
phs
źródło
1

Powyższe nie działa na wszystkich wariantach, może to być nieco bardziej pomocne w tych przypadkach ...

$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
stu
źródło
Czy możesz wyjaśnić, na czym to polegają inne metody?
Ryan Thompson,
Działa na systemach, które nie mają / usr / src / linux-headers- * i / var / lib / initramfs-tools
stu
rozważ sytuację, w której potrzebujesz, aby działał na wielu różnych dystrybucjach linuksa, które mają tylko to, że dkms (rodzaj) działa, razem.
stu
0

dkms statusi dkms_autoinstallernie działa w Ubuntu 16.x. Tak zrobi jakiś skrypt powłoki. Ten skrypt zakłada, że ​​masz *-dkmszainstalowany odpowiedni pakiet deb i bashjest twoją powłoką.

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 
sehari24jam
źródło