web-dev-qa-db-fra.com

Commande pour reconstruire tous les modules DKMS pour tous les noyaux installés?

Parfois, mon système entre dans un état où il manque un module ou deux à certains noyaux, car DKMS a en quelque sorte oublié de compiler ces modules pour ce noyau. Plutôt que de passer du temps à diagnostiquer le problème, ce serait bien s'il y avait une seule commande pour exécuter ce woudl reconstruire juste tous module contrôlé par dkms pour tous noyau installé. Y a-t-il une telle commande?

38
Ryan Thompson

J'ai imaginé un one-liner Shell pour le faire:

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

Cela fonctionne car les noms des répertoires dans /var/lib/initramfs-tools sont exactement les noms de version du noyau que vous devez transmettre à dkms_autoinstaller pour lui indiquer de reconstruire tous les modules pour ces versions du noyau. Notez que si vous avez désinstallé d'anciens noyaux, leurs répertoires risquent de traîner et de générer des erreurs, mais cela ne pose pas de problème, car dkms_autoinstaller ne fera rien pour les versions de noyau non installées.

47
Ryan Thompson

Cela ne ressemble pas à la commande dkms qui vous permet de le faire. J'ai créé un petit script Python qui devrait faire ce que vous voulez. Vous pouvez mettre un alias dans votre ~/.bashrc comme

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

Bien sûr, vous devez d'abord le rendre exécutable. Voici le 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)

Testé ici, semble bien fonctionner:

$ 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

Si vous souhaitez également installer les modules, remplacez build par install à la dernière dernière ligne.

8
htorque

En combinant les réponses de @htorque et de @Ryan Thompson, voici mon one-line (en tant que 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
3
phs

Ce qui précède ne fonctionne pas sur toutes les variantes, cela pourrait être un peu plus utile dans ces cas ...

$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 et dkms_autoinstaller ne fonctionne pas dans ubuntu 16.x. Donc, un script Shell fera l'affaire. Ce script supposait que vous disposiez de *-dkms deb-package correct et que bash correspond à votre 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
sehari24jam