Команда для восстановления всех модулей DKMS для всех установленных ядер?

Иногда, моя система входит в состояние, где некоторые ядра пропускают модуль или два, потому что DKMS так или иначе забыл компилировать те модули для того ядра. Вместо того, чтобы проводить время, диагностируя проблему, было бы хорошо, если бы была единственная команда, которую я мог бы выполнить, который просто восстановил бы каждый dkms-управляемый модуль для каждого установленного ядра. Есть ли такая команда?

39
задан 16 July 2011 в 10:56

6 ответов

Я выяснил остроту оболочки, чтобы сделать это:

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

Это работает потому что названия каталогов в /var/lib/initramfs-tools точно имена версии ядра, которым необходимо передать dkms_autoinstaller сказать этому восстанавливать все модули для тех версий ядра. Обратите внимание, что при удалении некоторых старых ядер их каталоги могли бы все еще лежать вокруг и заставлять некоторые ошибки сообщаться, но это не проблема потому что dkms_autoinstaller ничего просто не сделает для тех версий ядра, которые не установлены.

47
ответ дан 23 November 2019 в 00:12

Не похож dkms команда позволяет Вам делать это. Я создал маленький сценарий Python, который должен сделать то, что Вы хотите. Можно вставить псевдоним Ваш ~/.bashrc как

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

Конечно, необходимо было бы сделать это исполняемым файлом сначала. Вот код:

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

Протестированный это здесь, кажется, работает просто великолепно:

$ 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

Если Вы также хотите установить модули, сборку замены с установкой в предпоследней строке.

8
ответ дан 23 November 2019 в 00:12

При объединении @htorque и ответы @Ryan Thompson's, вот является мой (как корень) остротой:

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
4
ответ дан 23 November 2019 в 00:12

Вышеупомянутое не работает над всеми вариантами, это могло бы быть немного более полезно в тех случаях...

$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
ответ дан 23 November 2019 в 00:12

dkms status и dkms_autoinstaller не работает в человечности 16.x. Таким образом, некоторый сценарий оболочки сделает. Этот сценарий предположил, что Вы имеете надлежащий *-dkms deb-пакет, установленный, и bash Ваша оболочка.

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
ответ дан 23 November 2019 в 00:12

Редактирование скрипта @htorque. Используйте его, если вы хотите принудительно перестроить (и установить) уже построенные модули. При переключении на python3 subprocess.run () требует 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)
3
ответ дан 23 November 2019 в 20:56

Другие вопросы по тегам:

Похожие вопросы: