Comando per ricostruire tutti i moduli DKMS per tutti i kernel installati?


39

Occasionalmente, il mio sistema entra in uno stato in cui alcuni kernel mancano di un modulo o due, perché DKMS in qualche modo ha dimenticato di compilare quei moduli per quel kernel. Piuttosto che perdere tempo a diagnosticare il problema, sarebbe bello se ci fosse un solo comando in grado di eseguire quel woudl semplicemente ricostruire ogni modulo controllato da dkms per ogni kernel installato. Esiste un tale comando?


Ottengo sempre il modulo di output broadcom-sta / 5.100.82.112 già installato sul kernel 2.6.38jon-64 / x86_64 Voglio davvero un'opzione --force o --rebuild --just-do-what-i-say;)

Risposte:


47

Ho pensato a una fodera di un guscio per farlo:

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

Questo funziona perché i nomi delle directory in /var/lib/initramfs-toolssono esattamente i nomi della versione del kernel che è necessario passare dkms_autoinstallerper dirgli di ricostruire tutti i moduli per quelle versioni del kernel. Nota che se hai disinstallato alcuni vecchi kernel, le loro directory potrebbero essere ancora in giro e causare la segnalazione di alcuni errori, ma questo non è un problema perché dkms_autoinstallernon farà nulla per quelle versioni del kernel che non sono installate.


1
ha dato alcuni errori perché è venuto fuori headers-xxx e headers-xxx-generic ma sembrava ricostruire le cose giuste nonostante gli errori
Frank

@frankster Dopo aver trovato più "Errore! Impossibile trovare il file dkms.conf." per una nuova installazione del kernel, sono stato in grado di installare i moduli del kernel precedenti elencati dkms statusnel nuovo kernel usando i seguenti moduli specifici desiderati da "/ usr / src". I parametri devono essere modificati secondo necessità per -c, -m, -v. Ecco un esempio per il modulo 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

Non sembra che il dkmscomando ti permetta di farlo. Ho creato un piccolo script Python che dovrebbe fare quello che vuoi. Puoi mettere un alias nel tuo ~/.bashrclike

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

Naturalmente dovresti prima renderlo eseguibile. Ecco il codice:

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

Testato qui, sembra funzionare bene:

$ 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

Se si desidera installare anche i moduli, sostituire build con install nell'ultima riga.


4

Combinando le risposte di @htorque e @Ryan Thompson, ecco il mio one-liner (come root):

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

Quanto sopra non funziona su tutte le varianti, questo potrebbe essere un po 'più utile in quei casi ...

$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

Potresti approfondire cosa fa ciò che non fanno gli altri metodi?
Ryan C. Thompson,

Funziona su sistemi che non hanno / usr / src / linux-headers- * e / var / lib / initramfs-tools
stu,

considera la situazione in cui ne hai bisogno per funzionare su molte distro linux che hanno solo il fatto che dkms (sorta di) funziona, in comune.
stu

0

dkms statuse dkms_autoinstallernon funziona in Ubuntu 16.x. Quindi alcuni script di shell lo faranno. Questo script presupponeva che fosse *-dkmsinstallato il deb-package corretto ed bashè la shell.

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

Una modifica della sceneggiatura di @htorque. Usalo nel caso in cui desideri una ricostruzione forzata (e installazione) di moduli già creati. Passato a python3, subprocess.run()richiede 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

# 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 = [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/']
kernels = subprocess.run(cmd, stdout=subprocess.PIPE).stdout.decode("utf-8").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:
         for action in ['remove', 'install']:
            cmd = ['dkms', action, '-m', module, '-v', version, '-k', kernel]
            subprocess.run(cmd)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.