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

39

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

Ryan C. Thompson
la source
J'ai toujours le module de sortie broadcom-sta / 5.100.82.112 déjà installé sur le noyau 2.6.38jon-64 / x86_64, je veux vraiment une option --force ou --rebuild --just-do-what-i-say;)

Réponses:

47

J'ai imaginé un shell one-liner 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 /var/lib/initramfs-toolssont exactement les noms de version du noyau que vous devez passer pour dkms_autoinstallerlui indiquer de reconstruire tous les modules pour ces versions de 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_autoinstallerrien ne sera fait pour les versions de noyau non installées.

Ryan C. Thompson
la source
1
il y a eu des erreurs parce que les en-têtes-xxx et en-têtes-xxx-génériques sont apparus, mais il a semblé reconstruire les données correctes malgré les erreurs
Frank
@frankster Après avoir trouvé plusieurs "Erreur! Impossible de localiser le fichier dkms.conf." pour une nouvelle installation de noyau, j'ai pu installer les modules de noyau précédents listés par dkms statusdans le nouveau noyau en utilisant les modules suivants que je voulais dans "/ usr / src". Les paramètres doivent être modifiés selon les besoins pour -c, -m, -v. Voici un exemple pour le module 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

Ne semble pas que la dkmscommande 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 ~/.bashrccomme

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 dans l'avant dernière ligne.

htorque
la source
4

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
phs
la source
1

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
stu
la source
Pourriez-vous préciser ce que cela fait que les autres méthodes ne font pas?
Ryan C. Thompson
Cela fonctionne sur les systèmes qui n'ont pas / usr / src / linux-headers- * et / var / lib / initramfs-tools
mardi
Pensez à la situation où vous en avez besoin pour fonctionner sur de nombreuses distributions Linux qui n'ont que le fait que dkms (en quelque sorte) fonctionne en commun.
STU
0

dkms statuset dkms_autoinstallerne fonctionne pas dans Ubuntu 16.x. Donc, un script shell fera l'affaire. Ce script suppose que vous avez *-dkmsinstallé le paquetage approprié et bashconstitue 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 
sehari24jam
la source
0

Une édition de script par @htorque. Utilisez-le si vous voulez forcer la reconstruction (et l'installation) de modules déjà construits. Basculé sur 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)
Alex Potapenko
la source