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


39

Інколи моя система потрапляє в стан, коли в деяких ядрах відсутній модуль або два, оскільки DKMS якось забув скласти ці модулі для цього ядра. Замість того, щоб витрачати час на діагностику проблеми, було б непогано, якби була одна команда, яку я міг би запустити, який би просто відновив кожен керований модулем dkms для кожного встановленого ядра. Чи є така команда?


Я завжди отримую вихідний модуль broadcom-sta / 5.100.82.112, уже встановлений на ядрі 2.6.38jon-64 / x86_64. Я дуже хочу --force або --rebuild - just-do-what-i-say;)

Відповіді:


47

Я розібрався з одноклассником оболонки, щоб це зробити:

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

Це працює, тому що імена каталогів у - /var/lib/initramfs-toolsце саме імена версій ядра, які вам потрібно передати, dkms_autoinstallerщоб сказати йому, щоб відновити всі модулі для цих версій ядра. Зауважте, що якщо ви видалили кілька старих ядер, їхні каталоги можуть все-таки лежати навколо і викликати повідомлення про деякі помилки, але це не проблема, тому що dkms_autoinstallerпросто нічого не зробить для тих версій ядра, які не встановлені.


1
це дало деякі помилки, тому що з'явилися headers-xxx та headers-xxx-generic, але, здавалося, відновити правильні речі, незважаючи на помилки
frankster

@frankster Після виявлення декількох "Помилка! Не вдалося знайти файл dkms.conf." для нової установки ядра я зміг встановити попередні модулі ядра, перелічені dkms statusновим ядром, використовуючи наступні для конкретних модулів, які я хотів від "/ usr / src". Параметри потрібно змінювати в міру необхідності для -c, -m, -v. Ось приклад модуля 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

Не схоже, що 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

Якщо ви також хочете встановити модулі, замініть збірку на інсталяцію у другому останньому рядку.


4

Поєднуючи відповіді @htorque та @Ryan Thompson, ось мій (як корінь) однолінійний:

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

1

Наведене не працює у всіх варіантах, це може бути трохи корисніше в тих випадках ...

$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

Не могли б ви детальніше зупинитися на тому, що це робить, що інші методи не роблять?
Райан Томпсон,

Він працює в системах, які не мають / usr / src / linux-headers- * та / var / lib / initramfs-tools
stu

розглянемо ситуацію, коли потрібно, щоб він працював на багатьох різних Linux-дистрибутивах, які мають лише те, що dkms (роду) працює.
Ст

0

dkms statusі dkms_autoinstallerне працює в ubuntu 16.x. Отже, деякі сценарії оболонки будуть робити. Цей сценарій передбачав, що у вас встановлений належний *-dkmsдеб-пакет і 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 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.