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 ?
Réponses
Trop de publicités?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.
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.
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)
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
- Réponses précédentes
- Plus de réponses