Comando para reconstruir todos os módulos DKMS para todos os kernels instalados?

39

Ocasionalmente, meu sistema entra em um estado em que alguns kernels estão faltando um ou dois módulos, porque o DKMS de alguma forma esqueceu de compilar esses módulos para esse kernel. Em vez de gastar algum tempo diagnosticando o problema, seria bom se houvesse um único comando que eu pudesse executar que apenas restaurasse todos os módulos controlados por dkms para cada kernel instalado. Existe esse comando?

Ryan C. Thompson
fonte
Eu sempre recebo o módulo de saída broadcom-sta / 5.100.82.112 já instalado no kernel 2.6.38jon-64 / x86_64. Eu realmente quero uma opção --force ou --rebuild - just-do-what-i-say;)

Respostas:

47

Eu descobri uma linha de shell para fazer isso:

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

Isso funciona porque os nomes dos diretórios /var/lib/initramfs-toolssão exatamente os nomes da versão do kernel para os quais você precisa passar dkms_autoinstallerpara solicitar a reconstrução de todos os módulos dessas versões do kernel. Observe que se você desinstalou alguns kernels antigos, seus diretórios ainda podem estar por aí e causar alguns erros a serem relatados, mas isso não é um problema, porque dkms_autoinstallersimplesmente não fará nada pelas versões do kernel que não estão instaladas.

Ryan C. Thompson
fonte
11
deu alguns erros, porque ele veio cabeçalhos-xxx e-headers-xxx genérico, mas parecia para reconstruir o material correto, apesar dos erros
frankster
@frankster Depois de encontrar vários "Erro! Não foi possível localizar o arquivo dkms.conf." para uma nova instalação do kernel, consegui instalar os módulos anteriores listados dkms statusno novo kernel usando o seguinte por módulos específicos que eu queria em "/ usr / src". Os parâmetros precisam ser alterados conforme necessário para -c, -m, -v. Aqui está um exemplo para o módulo 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 24/10
8

Não parece que o dkmscomando permite que você faça isso. Criei um pequeno script Python que deve fazer o que você deseja. Você pode colocar um alias no seu ~/.bashrclike

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

Claro que você precisaria torná-lo executável primeiro. Aqui está o código:

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

Testei aqui, parece funcionar muito bem:

$ 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 você também deseja instalar os módulos, substitua build por install na segunda última linha.

htorque
fonte
4

Combinando as respostas de @htorque e @Ryan Thompson, aqui está a minha linha (como 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
fonte
1

As opções acima não funcionam em todas as variantes; isso pode ser um pouco mais útil nesses casos ...

$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
fonte
Você poderia elaborar o que isso faz com os outros métodos?
Ryan C. Thompson
Funciona em sistemas que não possuem / usr / src / linux-headers- * e / var / lib / initramfs-tools
stu
considere a situação em que você precisa que ele seja executado em várias distribuições Linux que apenas têm o fato de que o dkms (mais ou menos) funciona em comum.
2131616
0

dkms statuse dkms_autoinstallernão funciona no ubuntu 16.x. Então, algum script shell fará. Este script assumiu que você possui o *-dkmspacote deb instalado apropriado e bashé o seu 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
fonte