Иногда, моя система входит в состояние, где некоторые ядра пропускают модуль или два, потому что DKMS так или иначе забыл компилировать те модули для того ядра. Вместо того, чтобы проводить время, диагностируя проблему, было бы хорошо, если бы была единственная команда, которую я мог бы выполнить, который просто восстановил бы каждый dkms-управляемый модуль для каждого установленного ядра. Есть ли такая команда?
Я выяснил остроту оболочки, чтобы сделать это:
ls /var/lib/initramfs-tools | \
sudo xargs -n1 /usr/lib/dkms/dkms_autoinstaller start
Это работает потому что названия каталогов в /var/lib/initramfs-tools
точно имена версии ядра, которым необходимо передать dkms_autoinstaller
сказать этому восстанавливать все модули для тех версий ядра. Обратите внимание, что при удалении некоторых старых ядер их каталоги могли бы все еще лежать вокруг и заставлять некоторые ошибки сообщаться, но это не проблема потому что dkms_autoinstaller
ничего просто не сделает для тех версий ядра, которые не установлены.
Не похож 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
Если Вы также хотите установить модули, сборку замены с установкой в предпоследней строке.
При объединении @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
Вышеупомянутое не работает над всеми вариантами, это могло бы быть немного более полезно в тех случаях...
$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
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
Редактирование скрипта @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)