I don’t know how many times you have to do something before you decide that enough is enough. I wrote a service to autorecompile kernel modules. It checks in a config file (/etc/modautocompile.conf) which modules to autorecompile and if they are not found in the /lib/modules directory of the current kernel runs the command associated with the module to recompile it. I bet such a service already exists hundred times under different names … but it’s going to save me time and probably explanations (as the ATI fglrx module should be the first of your list!)
Here’s a sample config file (adding modules to that list and comment them out would be a good idea).
# kernel modules to autocompile after kernel update
# name command
vboxdrv service vboxdrv setup
fglrx /usr/bin/fglrx-kernel-build.sh
And here’s the script:
#! /bin/sh
# Linux kernel module init script
#: Title : modautocompile
#: Date Created: Sat Oct 16 06:00:29 PDT 2010
#: Last Edit : Sat Oct 16 06:00:29 PDT 2010
#: Author : please_try_again
#: Version : 1.0
#: Description : Automatically recompile modules after kernel update
# chkconfig: 35 30 70
# description: recompile modules
#
### BEGIN INIT INFO
# Provides: modautocompile
# Required-Start: $syslog
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: recomppile kernel modules
### END INIT INFO
# Define the modules you want to autorecompile in the file /etc/modautocompile.conf
# or in the file specified by the variable CFG below
CFG=/etc/modautocompile.conf
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# /etc/modautocompile.conf example
# kernel modules to autocompile after kernel update
# module command
# vboxdrv service vboxdrv setup
# fglrx /usr/bin/fglrx-kernel-build.sh
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
start()
{
# check if $CFG exist
if [ ! -e $CFG ] ; then
echo $CFG not found
exit 1
fi
# parse /etc/modautocompile.conf
eval `awk 'BEGIN { I=-1 } ; !/^#/ { if ( NF ) { MOD=$1 ; I++ ; $1="" ; sub(/ /, "", $0) ; printf "MOD[%i]=%s; CMD[%i]=\"%s\";", I, MOD, I, $0 } }' $CFG`
# exit if no modules defined in /etc/modautocompile.conf
if [ ${#MOD[li]} -eq 0 ] ; then[/li] exit 2
fi
# kernel modules dir
MDIR=/lib/modules/$(uname -r)
i=0
while [ $i -lt ${#MOD[li]} ] ; do[/li] mod=${MOD[$i]}
cmd=${CMD[$i]}
unset mof
if [ "x$mod"!="x" -a "x$cmd"!="x" ] ; then
mod=${mod}.ko
mof=`find $MDIR -name $mod`
if [ "$mof" == "" ] ; then
echo " - compiling module $mod"
$cmd
fi
fi
let i++
done
}
case "$1" in
start)
start
;;
esac
exit 0
copy/paste the script into a file, name it modautocompile, put it in /etc/rc.d, chmod to 755, enable with insserv.
Even more amazing stuff from please_try_again. Might I ask if your script would work for anyone using the nVidia driver as well? Would you add this to your config file?
Hi James,
You can autorecompile any module you need, but
you have to provide the name of the module (without the extension .ko) and this file is expected to be a ‘real’ file (not a symlink) in the kernel /lib/modules directory.
you have to provide the command or the script used to compile the module.
I haven’t compiled the nvidia module a single time since I installed 11.3. I use nvidia-gfxG02-kmp from the Nvidia repo and the nividia module I have is actually a symlink to the one installed with the first kernel.
I think I already experienced some Xorg no-start issues whenever this symlink was missing - maybe on Fedora, I don’t remember.
If you need to recompile the nvidia module and the expected result is the file nvidia.ko (not a symlink!) in the /lib/module subdirectory of the updated kernel, yes, it should work, provided you put the correct command or script to compile it in /etc/modautocompile.conf (I don’t know that command).
@ken_yap
No problem. It was clear to me that I wasn’t reinventing the wheel, I was just tired of recompiling and reexplaining, but I was quite sure that something should take care of that (it would have been absurd otherwise). DKMS? Yes, that’s what I was looking for. How do we enable/use it?
Ok, I found it in some personnal repos for 11.3. It wasn’t that obvious after all! A framework? Does it mean that you have to rewrite each service for each module? Well … I think for now i’ll stick with a single line of awk. But I will pay attention when modules get recompiled automatically, as I think I saw that already happening on other distros (not sure though).
When I enable this in yast system services I get this error and it will not show enabled.
/etc/init.d/modautocompile start returned 1 (unspecified error):
copy/paste the code in post #1 into the file /etc/init.d/modautocompile. You have to create this file, as it doesn’t exist. You also have to be root to be allowed to write in the directory /etc/init.d.
once you have put this file in the right place, type the following in a terminal:
su -l
chown root:root /etc/init.d/modautocompile
chmod 755 /etc/init.d/modautocompile
You also need the file /etc/modautocompile.conf with the following or a similar content:
# kernel modules to autocompile after kernel update
# name command
vboxdrv service vboxdrv setup
fglrx /usr/bin/fglrx-kernel-build.sh
Lines starting with “#” are comments and are ignored. So if you don’t need to recompile VirtualBox module (vboxdrv), comment out this line. You can add other entries to autocompile other modules.
Once you have this file in the right place, type the following in a terminal:
su -l
chown root:root /etc/modautocompile.conf
chmod 644 /etc/modautocompile.conf
Then you should be able to enable/disable this service from YaST.
I just noticed that the latest fglrx package built by the ATI installer (whether you call it from atiupgrade or not) now includes a service by Sebastian Siebert to rebuild the fglrx module automatically. That’s what modautocompile also does (in a more elegant way ). In any case, there is no need for checking twice if the fglrx module is present, one time at boot and one time later in the runlevels before X is started. If you installed the latest ATI driver (11.1) , I’ll recommend to disable modautocompile for the ATI driver, either by disabling the service or if you use it to autocompile other modules by commenting out the fglrx entry in /etc/modautocompile.conf.
It’s quicker when you have several files as you don’t have to create directories or change permissions (since this info is stored in the archive).
But you can still write a script to generate a script to automate the automation …
It would have to do the following:
get the list of files to put in the archive (with full path of course)
put the files in an archive (either .tgz or .bz2) by using respectively:
tar -cvzf someArchive.tgz file1 file2 ...
or
tar -cvjf someArchive.bz2 file1 file2 ...
Or you can read the list of files from a file:
tar -cvzf someArchive.tgz -T listOfFiles
encode the archive in base64:
base64 someArchive.tgz > someScript
base64 is in coreutils
add the commands in red (in the example above) in the script to display and decode the text and pipe the output to the tar command, which extracts the resulting archive or just add both in one step:
cat << EOS
#! /bin/bash
cat << EOF | base64 -di | tar -C / -xvjf -
`base64 yourArchive.bz2`
EOF
EOS
Notice that the example uses bzip2 compression (tar -xvjf). For gzip, you would use z instead of j.
Another possibility would be a script which generates a rpm from a list of files (using rpmbuild). It’s even better but a little bit more work.
So I think I am going to create a new thread for the script installer. As far as I can tell, compressing the files to take up less room is not of a big concern to me. In fact, once the script installer is loaded with a job, it could surely then be compressed. Lets think about our fellow users here and what we could provide to them that would allow a single script to create several scripts and or files, stored in the right locations and allowing for certain command(s) to be run on them. Now a compressed archive can save the fact that a file is executable, but not to run a command like “/sbin/insserv /etc/rc.d/modautocompile” on it. Let put up my solution, then you put up yours, but trying to do the same task. First off, dual with you over bash script functions/commands will surely leave me dead in the street. Lets look at total functionality instead, if for no other reason than so I might live another day. lol!
It can be generated with this (by either outputing to a file or redirecting the second cat).
#! /bin/bash
tar -czf /tmp/modautocompile.tgz $(find /etc -name "*modautocompile*") 2>/dev/null
cat << EOS
#! /bin/bash
cat << EOF | base64 -di | tar -C / -xvzf -
`base64 /tmp/modautocompile.tgz`
EOF
EOS
Reminds me of the infinite “cat” though. lol!
I first thought you were asking for my comments … but reading your post again, I noticed that you did actually ask for commands? You know, “comments” and “commands” sound for me like “paper” and “pepper”. So I might (once again) have provided the right solution but the wrong answer.
After doing what said here (by the way, that one is a fantastic post), I get this output.
# /sbin/insserv /etc/rc.d/modautocompile
insserv: Service vboxdrv is missed in the runlevels 4 to use service vboxweb-service
insserv: Service syslog is missed in the runlevels 4 to use service modautocompile
You did nothing wrong. The vboxdrv init script is wrong. This is how I get rid of these messages - because they are annoying but harmless (users can safely ignore them).