#!/bin/bash # # functions used by mkinitrd and other tools. # # Copyright 2005-2008 Red Hat, Inc. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Authors: # Peter Jones # Jeremy Katz # Jakub Jelinek # # IF_verbose="" function set_verbose() { case $1 in 1|true|yes|on) IF_verbose="-v" ;; 0|false|no|off) IF_verbose="" ;; esac } function is_verbose() { [ -n "$IF_verbose" ] && return 0 return 1 } function get_verbose() { echo "$IF_verbose" is_verbose } function vecho() { local NONL="" if [ "$1" == "-n" ]; then NONL="-n" shift fi is_verbose && echo $NONL "$@" } function error() { local NONL="" if [ "$1" == "-n" ]; then NONL="-n" shift fi echo $NONL "$@" > /dev/stderr } IF_RTLD="" IF_dynamic="" function get_dso_deps() { local bin="$1" ; shift declare -a FILES declare -a NAMES local LDSO=$(echo nash-showelfinterp $bin | /sbin/nash --forcequiet) [ -z "$LDSO" -o "$LDSO" == "$bin" ] && local LDSO="$IF_RTLD" [ -z "$LDSO" -o "$LDSO" == "$bin" ] && return 1 [ -z "$IF_RTLD" ] && IF_RTLD="$LDSO" # I hate shell. declare -i n=0 while read NAME I0 FILE ADDR I1 ; do [ "$FILE" == "not" ] && FILE="$FILE $ADDR" [ "$NAME" == "not" ] && NAME="$NAME $I0" NAMES[$n]="$NAME" FILES[$n]="$FILE" let n++ done << EOF $(LD_TRACE_PRELINKING=1 LD_WARN= LD_TRACE_LOADED_OBJECTS=1 \ $LDSO $bin 2>/dev/null) EOF [ ${#FILES[*]} -eq 0 ] && return 1 # we don't want the name of the binary in the list if [ "${FILES[0]}" == "$bin" ]; then FILES[0]="" NAMES[0]="" [ ${#FILES[*]} -eq 1 ] && return 1 fi declare -i n=0 while [ $n -lt ${#FILES[*]} ]; do local FILE="${FILES[$n]}" local NAME="${NAMES[$n]}" if [ "$FILE" == "not found" -o "$NAME" == "not found" ]; then cat 1>&2 < []" return 1 fi local file="$1" ; shift local root="${1%%/}/" ; shift local dest="${1##/}" [ -z "$dest" ] && local dest="${file##/}" local old_indent_chars=${IF_indent_chars} IF_indent_chars="${IF_indent_chars} " local indent=${IF_indent_chars:2} mkdir -p "$root/$(dirname $dest)" local RET=0 local target="" [ -L "$file" ] && target=$(readlink "$file") if [ -n "$target" -a "$dest" != "$target" ]; then if [ -e "$root$dest" ]; then #vecho "${indent}$root/$dest already exists" RET=0 else vecho "${indent}$file -> $root$dest" ln -sf "$target" "$root$dest" #inst "$target" "$root" local BASE=`basename "$target"` local TLIBDIR=`echo "$target" | sed -e 's,\(^/lib[^/]*\)/.*$,\1/,' \ -e 's,\(\(.*\)/\)[^/]\+$,\1,'` if [ "$TLIBDIR" = "$BASE" ]; then local TLIBDIR=`echo "/$dest" | sed \ -e 's,\(^/lib[^/]*\)/.*$,\1/,' \ -e 's,\(\(.*\)/\)[^/]\+$,\1,'` fi inst "$TLIBDIR/$BASE" "$root" "$TLIBDIR/$BASE" RET=$? IF_indent_chars=${old_indent_chars} return $RET fi fi local SHEBANG=$(dd if="$file" bs=2 count=1 2>/dev/null) if [ "$SHEBANG" == '#!' ]; then # We're intentionally not playing the "what did this moron run # in his shell script" game. There's nothing but pain in that. local interp=$(head -1 "$file" | sed 's/^#! *//') inst "$interp" "$root" RET=$? IF_indent_chars=${old_indent_chars} return $RET fi if [ -e "$root$dest" ]; then #vecho "${indent}$root$dest already exists" RET=0 else if [ -n "$target" -a -L "$target" ]; then inst "$target" "$root" RET=$? else vecho "${indent}$file -> $root$dest" cp -aL "$file" "$root$dest" # local DEPS=$(get_dso_deps "$file") # if [ -n "$DEPS" ]; then # IF_dynamic="yes" # fi # for x in $DEPS ; do # local TLIBDIR=`echo "$x" | sed 's,\(/lib[^/]*\)/.*$,\1,'` # local BASE=`basename "$x"` # inst "$x" "$root" "$TLIBDIR/$BASE" # done RET=$? fi fi IF_indent_chars=${old_indent_chars} return $RET } findone() { echo nash-find "$@" | /sbin/nash --force --quiet \ | /bin/awk '{ print $1; exit; }' } findall() { echo nash-find "$@" | /sbin/nash --force --quiet } # module dep finding and installation functions moduledep() { MPARGS="" if [ "$1" == "--ignore-install" ]; then MPARGS="$MPARGS --ignore-install" shift fi vecho -n "Looking for deps of module $1" deps="" deps=$(modprobe $MPARGS --set-version $kernel --show-depends $1 2>/dev/null| awk '/^insmod / { print gensub(".*/","","g",$2) }' | while read foo ; do [ "${foo%%.ko}" != "$1" ] && echo -n "${foo%%.ko} " ; done) [ -n "$deps" ] && vecho ": $deps" || vecho } locatemodule() { MPARGS="" if [ "$1" == "--ignore-install" ]; then MPARGS="$MPARGS --ignore-install" shift fi fmPath=$(modprobe $MPARGS --set-version $kernel --show-depends $1 2>/dev/null | awk '/^insmod / { print $2; }' | tail -1) if [ -n "$fmPath" -a -f "$fmPath" ]; then return 0 fi for modExt in o.gz o ko ; do for modDir in /lib/modules/$kernel/updates /lib/modules/$kernel ; do if [ -d $modDir ]; then fmPath=$(findone $modDir -name $1.$modExt) if [ -n "$fmPath" -a -f "$fmPath" ]; then return 0 fi fi done done return 1 } expandModules() { items=$* for m in $items ; do char=$(echo $m | cut -c1) if [ $char = '=' ]; then NAME=$(echo $m | cut -c2-) if [ "$NAME" = "ata" ]; then MODS="$MODS $(cat /lib/modules/$kernel/modules.block |egrep '(ata|ahci)' |sed -e 's/.ko//')" else # Ignore if group list does not exist if [ -e /lib/modules/$kernel/modules.$NAME ]; then MODS="$MODS $(cat /lib/modules/$kernel/modules.$NAME |sed -e 's/.ko//')" fi fi else MODS="$MODS $m" fi done echo $MODS } installmodule() { MPARGS="" if [ "$1" == "--ignore-install" ]; then MPARGS="$MPARGS --ignore-install" shift fi MODULE=$1 fmPath="" locatemodule $MPARGS $MODULE MODULE=$fmPath if [ -z "$MODULE" ]; then return fi if [ -x /usr/bin/strip ]; then /usr/bin/strip -g $(get_verbose) $MODULE -o $MNTIMAGE/lib/modules/$kernel/$(basename $MODULE) else inst "$MODULE" "$MNTIMAGE" "/lib/modules/$kernel/$(basename $MODULE)" fi for fw in $(/sbin/modinfo -F firmware $MODULE 2>/dev/null); do if [ -f /lib/firmware/$fw ]; then inst "/lib/firmware/$fw" "$MNTIMAGE" "/lib/firmware/$fw" fi done } # This loops to make sure it resolves dependencies of dependencies of... resdeps () { modlist="$1" before=1 after=2 items=$(eval echo \${$modlist}) vecho "resolving for $modlist" vecho "and that has items of $items" while [ $before != $after ]; do before=$(echo $items | wc -c) list="" for i in $items ; do deps="" moduledep $i list="$list $deps" # need to handle prescsimods here -- they need # to go _after_ scsi_mod if [ "$i" = "scsi_mod" ]; then NEW_PRESCSIMODS="" for modName in $PRESCSIMODS ; do list="$list $modName" if [[ "$items " =~ " $modName " ]]; then NEW_PRESCSIMODS="$NEW_PRESCSIMODS $modName" else items="$items $modName" fi done PRESCSIMODS="$NEW_PRESCSIMODS" locatemodule scsi_wait_scan if [ -n "$fmPath" -a -f "$fmPath" ]; then scsi_wait_scan="yes" fi fi done items=$(for n in $items $list; do echo $n; done | sort -u) after=`echo $items | wc -c` done resolved="$items" } # vim:ts=8:sw=4:sts=4:et