| #!/bin/bash |
| # vim:ts=4 |
| # Distributed under the terms of the GNU General Public License v2 |
| # |
| # This script will do: |
| # - create /etc/modules.conf from /etc/modules.d/* |
| # - create /etc/modprobe.conf from /etc/modprobe.d/* |
| # - update modules.dep if modules.conf has been updated so depmod doesnt whine |
| # |
| # This is all for backwards compatibility. In the perfect world, we would be |
| # running a linux-2.6 kernel and not have any modules.d directory. Then there |
| # would be no work for us as module-init-tools automatically scans modprobe.d. |
| # Until that happens, we'll keep scanning and warning and being a pita. |
| # |
| |
| |
| ROOT="${ROOT%/}/" |
| [ "${ROOT}" = "${ROOT#/}" ] && ROOT="${PWD}/${ROOT}" |
| cd "${ROOT}" |
| |
| argv0=${0##*/} |
| . /etc/init.d/functions.sh || { |
| echo "${argv0}: Could not source /etc/init.d/functions.sh!" 1>&2 |
| exit 1 |
| } |
| umask 022 |
| esyslog() { :; } |
| export PATH=/sbin:${PATH} |
| |
| [ "${argv0}" = "modules-update" ] && ewarn "Please run 'update-modules' from now on; 'modules-update' is going away" |
| |
| |
| # |
| # Setup some variables |
| # |
| |
| HEADER="### This file is automatically generated by update-modules" |
| |
| # |
| # Parse command-line |
| # |
| |
| VERBOSE=0 |
| DEBUG=0 |
| FORCE="false" |
| BACKUP="false" |
| KV= |
| while [ -n "$1" ] ; do |
| case $1 in |
| --assume-kernel=*) KV=${1#*=};; |
| -b|--backup) BACKUP="true";; |
| -f|--force|force) FORCE="true";; |
| -v|--verbose) ((VERBOSE+=1));; |
| -d|--debug) ((DEBUG+=1));; |
| -V|--version) exec echo "${argv0}$Revision: 1.1 $ $Date: 2008/10/25 23:55:43 $";; |
| -h|--help) |
| cat <<-EOF |
| Usage: update-modules [options] |
| |
| Options: |
| --assume-kernel=KV Assume the kernel is at least version KV |
| -b, --backup Backup existing config files (add .old ext) |
| -f, --force Force execution in face of bad things |
| -v, --verbose Be a bit more verbose in what we do |
| -d, --debug Helpful debug output |
| -V, --version Dump version info |
| -h, --help This help screen, duh |
| EOF |
| exit 0 |
| ;; |
| *) |
| eerror "Error: I don't understand $1" |
| exit 1 |
| ;; |
| esac |
| shift |
| done |
| |
| if [ ! -w ./etc ] ; then |
| eerror "You must be root to do this" |
| exit 2 |
| fi |
| |
| [ ${DEBUG} -gt 0 ] && set -x |
| |
| veinfo() { [ ${VERBOSE} -gt 0 ] && einfo "$*" ; return 0 ; } |
| vewarn() { [ ${VERBOSE} -gt 0 ] && ewarn "$*" ; return 0 ; } |
| |
| [ "${ROOT}" != "/" ] && veinfo "Operating on ROOT = '${ROOT}'" |
| |
| # |
| # Let's check the optimal case first: nothing to do |
| # |
| if ! ${FORCE} ; then |
| if [ ! -d "./etc/modules.d" ] ; then |
| if [ ! -d "./etc/modprobe.d" ] ; then |
| veinfo "No /etc/modules.d or /etc/modprobe.d dir; Nothing to do!" |
| exit 0 |
| |
| elif [ -e "./etc/modprobe.conf" ] ; then |
| vewarn "You should put settings in /etc/modprobe.d/ rather than modprobe.conf" |
| |
| elif [ -e "./etc/modules.conf" ] ; then |
| vewarn "If you only run linux-2.4, you should delete /etc/modules.conf" |
| |
| else |
| veinfo "We have just /etc/modprobe.d; Nothing to do!" |
| exit 0 |
| fi |
| else |
| vewarn "You have /etc/modules.d, so things need to get coalesced" |
| fi |
| fi |
| |
| # |
| # Build list of config files to generate and verify none |
| # have been modified in any way |
| # |
| for x in modprobe.conf modules.conf ; do |
| x="./etc/${x}" |
| [ -r ${x} ] || continue |
| |
| if [ "$(sed -ne 1p ${x})" != "${HEADER}" ] ; then |
| ewarn "Warning: ${x#.} has not been automatically generated" |
| |
| if ${FORCE} ; then |
| ewarn "--force specified, (re)generating file anyway" |
| else |
| eerror "Use \"update-modules force\" to force (re)generation" |
| exit 1 |
| fi |
| fi |
| done |
| |
| |
| # |
| # If the system doesnt have old modutils, then this is prob linux-2.6 only |
| # |
| if type -P modprobe.old > /dev/null || \ |
| LC_ALL=C modprobe -V 2>/dev/null | grep -qs "modprobe version" |
| then |
| GENERATE_OLD="true" |
| else |
| GENERATE_OLD="false" |
| fi |
| |
| |
| # Reset the sorting order since we depend on it |
| export LC_COLLATE="C" |
| |
| KV=${KV:-$(uname -r)} |
| |
| |
| # |
| # Desc: backup a config file if need be and replace with new one |
| # Usage: backup <old config file to backup> <new config file to replace with> |
| # Ex: backup /etc/modules.conf /etc/modules.conf.tempfile |
| # |
| backup() { |
| if ${BACKUP} && [ -e "$1" ] ; then |
| mv -f "$1" "$1".old |
| fi |
| mv -f "$2" "$1" |
| } |
| |
| |
| # |
| # Desc: Create module header |
| # Usage: create_header <config dir> |
| # Ex: create_header /etc/modules.d |
| create_header() { |
| local moddir=$1 |
| |
| cat <<-EOF |
| ${HEADER} |
| # |
| # Please do not edit this file directly. If you want to change or add |
| # anything please take a look at the files in ${moddir} and read |
| # the manpage for update-modules(8). |
| # |
| EOF |
| } |
| |
| |
| # |
| # Desc: Combine all config files in a dir and place output in a file |
| # Usage: generate_config <output config file> <config dir> <reference config dir> <silent> |
| # Ex: generate_config /etc/modules.conf /etc/modules.d |
| # |
| generate_config() { |
| local config=$1 |
| local moddir=$2 |
| local refdir=$3 |
| local silent=$4 |
| local tmpfile="${config}.$$" |
| |
| [ -z "${silent}" ] && ebegin "Updating ${config#./etc/}" |
| |
| create_header ${refdir:-${moddir}} > "${tmpfile}" |
| |
| for cfg in "${moddir}"/* ; do |
| [ -d "${cfg}" ] && continue |
| [ ! -r "${cfg}" ] && continue |
| |
| # Skip backup and RCS files #20597 |
| case ${cfg} in *~|*.bak|*,v) continue;; esac |
| |
| # If config file is found in the reference dir, then skip it |
| [ -n "${refdir}" ] && [ -e "${refdir}/${cfg##*/}" ] && continue |
| |
| ( |
| echo "### update-modules: start processing ${cfg#.}" |
| if [ -x "${cfg}" ] ; then |
| # $cfg can be executable; nice touch, Wichert! :) |
| "${cfg}" |
| else |
| cat "${cfg}" |
| fi |
| echo |
| echo "### update-modules: end processing ${cfg#.}" |
| echo |
| ) >> "${tmpfile}" |
| done |
| |
| backup "${config}" "${tmpfile}" |
| |
| [ -z "${silent}" ] && eend 0 |
| |
| return 0 |
| } |
| |
| |
| # |
| # Generate the old modules.conf file based upon all the snippets in |
| # modules.d. Since modprobe doesnt handle modules.d, we need to gather |
| # the files together in modules.conf for it. |
| # |
| |
| if [ ! -d "./etc/modules.d" ] ; then |
| veinfo "No need to generate modules.conf :)" |
| |
| elif ${FORCE} || is_older_than ./etc/modules.conf ./etc/modules.d ; then |
| generate_config ./etc/modules.conf ./etc/modules.d |
| |
| else |
| veinfo "modules.conf: already up-to-date wheatness" |
| fi |
| |
| # |
| # Call depmod to keep insmod from complaining that modules.conf is more |
| # recent then the modules.dep file. |
| # |
| if [ -e "./etc/modules.conf" ] ; then |
| depfile=$( |
| # the modules.conf file has optional syntax: |
| # depfile=/path/to/modules.dep |
| ret=$(sed -n -e '/^[[:space:]]*depfile=/s:.*=::p' ./etc/modules.conf) |
| eval echo "${ret:-/lib/modules/${KV}/modules.dep}" |
| ) |
| |
| if [ -d "${depfile%/*}" ] ; then |
| if [ ./etc/modules.conf -nt "${depfile}" ] ; then |
| arch=$(uname -m) |
| ebegin "Updating modules.dep" |
| for cfg in /lib/modules/${KV}/build /usr/src/linux-${KV} \ |
| /lib/modules/${KV} /boot /usr/src/linux "" |
| do |
| cfg=".${cfg}/System.map" |
| for suffix in -genkernel-${arch}-${KV} -genkernel-'*'-${KV} -${KV} "" ; do |
| scfg=$(echo ${cfg}${suffix}) |
| scfg=${scfg%% *} |
| [ -f "${scfg}" ] && cfg=${scfg} && break 2 |
| done |
| cfg="" |
| done |
| [ -n "${cfg}" ] && cfg="-F ${cfg}" |
| depmod -b "${ROOT}" -a ${cfg} ${KV} |
| eend $? |
| veinfo "Ran: depmod -b '${ROOT}' -a ${cfg} ${KV}" |
| else |
| veinfo "modules.dep: already up-to-date goodness" |
| fi |
| else |
| vewarn "The dir '${depfile}' does not exist, skipping call to depmod" |
| fi |
| fi |
| |
| |
| # |
| # Generate the new modprobe.conf file if possible. What this entails is |
| # grabbing details from the old modprobe via the -c option and sticking |
| # it in the newer config file. This is useful for backwards compat support |
| # and for packages that provide older style /etc/modules.d/ files but not |
| # newer style /etc/modprobe.d/ files. |
| # |
| # First we try to use the script `generate-modprobe.conf` from the |
| # module-init-tools and if that fails us, we try and generate modprobe.conf |
| # ourselves from the /etc/modules.d/ files. |
| # |
| if ! type -P generate-modprobe.conf > /dev/null ; then |
| vewarn "Skipping /etc/modprobe.conf generation (generate-modprobe.conf doesn't exist)" |
| |
| elif ! ${FORCE} && ! is_older_than ./etc/modprobe.conf ./etc/modules.d ./etc/modprobe.d ; then |
| veinfo "modprobe.conf: already up-to-date nutness" |
| |
| elif [ ! -e ./etc/modules.conf -a ! -e ./etc/modules.d ] ; then |
| veinfo "No need to generate modprobe.conf :)" |
| rm -f ./etc/modprobe.conf |
| |
| else |
| # |
| # First, bitch like crazy |
| # |
| for f in ./etc/modules.d/* ; do |
| # hack: ignore baselayout ;x |
| case ${f##*/} in |
| aliases|i386) continue;; |
| esac |
| [ -e "${f}" ] || continue |
| if [ ! -e "./etc/modprobe.d/${f##*/}" ] ; then |
| ewarn "Please file a bug about ${f#.}: it needs an /etc/modprobe.d/${f##*/}" |
| fi |
| done |
| |
| generated_ok=0 |
| tmpfile="./etc/modprobe.conf.$$" |
| |
| # |
| # First we try to use regular generate-modprobe.conf |
| # |
| if ${GENERATE_OLD} ; then |
| ebegin "Updating modprobe.conf" |
| create_header /etc/modprobe.d > "${tmpfile}" |
| if generate-modprobe.conf ${ASSUME_KV:+--assume-kernel=${KV}} \ |
| >> "${tmpfile}" 2> "${tmpfile}.err" |
| then |
| backup "./etc/modprobe.conf" "${tmpfile}" |
| eend 0 |
| generated_ok=1 |
| else |
| [[ ${VERBOSE} -gt 0 ]] && cat "${tmpfile}.err" |
| eend 1 "Warning: could not generate /etc/modprobe.conf!" |
| fi |
| fi |
| |
| # |
| # If the helper script failed, we fall back to doing it by hand |
| # |
| if [[ ${generated_ok} -eq 0 ]] ; then |
| ebegin "Updating modprobe.conf by hand" |
| |
| generate_config ./etc/modprobe.conf ./etc/modules.d ./etc/modprobe.d 0 |
| create_header /etc/modprobe.d > "${tmpfile}" |
| |
| # Just use generate-modprobe.conf to filter compatible syntax |
| if TESTING_MODPROBE_CONF=./etc/modprobe.conf \ |
| generate-modprobe.conf ${ASSUME_KV:+--assume-kernel=${KV}} \ |
| >> "${tmpfile}" 2> "${tmpfile}.err" |
| then |
| # we use mv here instead of backup_config() as the call to |
| # generate_config() above already took care of the backup |
| mv -f "${tmpfile}" "./etc/modprobe.conf" |
| eend $? |
| else |
| [[ ${VERBOSE} -gt 0 ]] && cat "${tmpfile}.err" |
| eend 1 "Warning: could not generate /etc/modprobe.conf!" |
| fi |
| fi |
| |
| # |
| # Now append all the new files ... modprobe will not scan /etc/modprobe.d/ |
| # if /etc/modprobe.conf exists, so we need to append /etc/modprobe.conf with |
| # /etc/modprobe.d/* ... http://bugs.gentoo.org/145962 |
| # |
| if [[ -e ./etc/modprobe.conf ]] ; then |
| for cfg in ./etc/modprobe.d/* ; do |
| [ -d "${cfg}" ] && continue |
| [ ! -r "${cfg}" ] && continue |
| |
| # Skip backup and RCS files #20597 |
| case ${cfg} in *~|*.bak|*,v) continue;; esac |
| |
| ( |
| echo |
| echo "### update-modules: start processing ${cfg#.}" |
| cat "${cfg}" |
| echo "### update-modules: end processing ${cfg#.}" |
| ) >> "./etc/modprobe.conf" |
| done |
| fi |
| |
| rm -f "${tmpfile}" "${tmpfile}.err" |
| fi |
| |
| : # make sure we fall through with 0 exit status |