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

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

Попробуй пройти бота-учителя. Он научит тебя Linux в виде игры: Курсы Linux и DevOPS Бесплатный урок

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

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

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

Попробуй пройти бота-учителя. Он научит тебя Linux в виде игры: Курсы Linux и DevOPS Бесплатный урок

Не похоже на то, что 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 osimport 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 statusnvidia-current, 275.09.07, 3.0.0-5-generic, x86_64: installedvirtualbox, 4.0.10, 3.0.0-5-generic, x86_64: installed$ sudo python dkms.py...$ dkms statusnvidia-current, 275.09.07, 3.0.0-5-generic, x86_64: installednvidia-current, 275.09.07, 3.0-2-generic, x86_64: builtnvidia-current, 275.09.07, 3.0-3-generic, x86_64: builtvirtualbox, 4.0.10, 3.0.0-5-generic, x86_64: installedvirtualbox, 4.0.10, 3.0-2-generic, x86_64: builtvirtualbox, 4.0.10, 3.0-3-generic, x86_64: built

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

Объединив ответы @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

Редактирование сценария @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 osimport 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)

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

$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 не работает в ubuntu 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 donedone 

Я всегда получаю выходной модуль broadcom-sta/5.100.82.112, уже установленный на ядре 2.6.38jon-64/x86_64, я действительно хочу опцию --force или --rebuild --just-do-what-i-say :wink:

Попробуй пройти бота-учителя. Он научит тебя Linux в виде игры: Курсы Linux и DevOPS Бесплатный урок