命令为所有已安装的内核重建所有DKMS模块?


39

有时,我的系统进入某些内核缺少一个或两个模块的状态,因为DKMS忘记了为该内核编译这些模块。如果没有一个我可以运行的命令,那就是woudl只是为每个已安装的内核重建每个 dkms控制的模块,而不是花时间诊断问题。有这样的命令吗?


我总是得到已经安装在内核2.6.38jon-64 / x86_64上的输出模块broadcom-sta / 5.100.82.112我真的想要--force或--rebuild --just-do-what-i-say选项;)

Answers:


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 2012年

@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

如果您还想安装模块,在最后第二行将build替换为install


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

您能否详细说明其他方法不具备的功能?
Ryan Thompson

它适用于没有/ usr / src / linux-headers- *和/ var / lib / initramfs-tools的系统
stu

考虑一下需要它在许多各种Linux发行版上运行的情况,这些发行版仅具有dkms(某种)可以正常工作的事实。
stu 2016年

0

dkms status并且dkms_autoinstaller在ubuntu 16.x中不起作用。因此,一些shell脚本会执行。该脚本假定您已经*-dkms安装了正确的deb-package,并且bash是您的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 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.