50 votes

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

Occasionnellement, mon système se retrouve dans un état où il manque un ou deux modules à certains noyaux, parce que DKMS a oublié de compiler ces modules pour ce noyau. Plutôt que de passer du temps à diagnostiquer le problème, ce serait bien s'il existait une commande unique que je pourrais exécuter et qui reconstruirait simplement les modules suivants tous module contrôlé par dkms pour tous le noyau installé. Existe-t-il une telle commande ?

66voto

lfaraone Points 1571

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

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

Cela fonctionne parce que les noms des répertoires dans /var/lib/initramfs-tools sont exactement les noms de version du noyau que vous devez passer à dkms_autoinstaller pour lui demander de reconstruire tous les modules pour ces versions du noyau. Notez que si vous avez désinstallé d'anciens noyaux, leurs répertoires peuvent encore traîner et provoquer des erreurs, mais ce n'est pas un problème parce que dkms_autoinstaller ne fera rien pour les versions du noyau qui ne sont pas installées.

8voto

Maciek Gryka Points 1807

Il ne semble pas que le dkms vous permet de le faire. J'ai créé un petit script Python script 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, il faut 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)

Je l'ai testé ici, il semble fonctionner correctement :

$ 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 construire avec installer à l'avant-dernière ligne.

6voto

Ulf Lindback Points 5235

En combinant les réponses de @htorque et de @Ryan Thompson, voici mon one-liner (en tant que racine) :

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

3voto

Alex Potapenko Points 31

Une édition de script par @htorque. Utilisez-le au cas où vous voudriez un force la reconstruction (et l'installation) des modules déjà construits. Passage à python3, subprocess.run() nécessite 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)

2voto

Dillmo Points 141

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

$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

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X