|
|
|
#!/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 <http://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
|
|
# Authors:
|
|
|
|
# Peter Jones <pjones@redhat.com>
|
|
|
|
# Jeremy Katz <katzj@redhat.com>
|
|
|
|
# Jakub Jelinek <jakub@redhat.com>
|
|
|
|
|
|
|
|
IF_RTLD=""
|
|
|
|
IF_dynamic=""
|
|
|
|
get_dso_deps() {
|
|
|
|
local bin="$1" ; shift
|
|
|
|
local FILES=() LDSO NAME IO FILE ADDR I1 n f TLIBDIR
|
|
|
|
|
|
|
|
LDSO=$(LANG=C eu-readelf -l $bin 2>/dev/null | \
|
|
|
|
awk '/interpreter/ {print $4}' |sed -e 's/]$//')
|
|
|
|
[[ $LDSO && $LDSO != $bin ]] || LDSO="$IF_RTLD"
|
|
|
|
[[ $LDSO && $LDSO != $bin ]] || return 1
|
|
|
|
[[ $IF_RTLD ]] || IF_RTLD="$LDSO"
|
|
|
|
|
|
|
|
# I love bash!
|
|
|
|
while read NAME I0 FILE ADDR I1 ; do
|
|
|
|
[[ $FILE = $bin ]] && continue
|
|
|
|
[[ $FILE = not || $NAME = not ]] && {
|
|
|
|
echo "Missing a shared library required by $bin." >&2
|
|
|
|
echo "dracut cannot create an initrd." >&2
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
# see if we are loading an optimized version of a shared lib.
|
|
|
|
[[ $FILE =~ '(/lib[^/]*).*' ]] && {
|
|
|
|
TLIBDIR=${BASH_REMATCH[1]}
|
|
|
|
BASE="${FILE##*/}"
|
|
|
|
# prefer nosegneg libs, then unoptimized ones.
|
|
|
|
for f in "$TLIBDIR/i686/nosegneg" "$TLIBDIR"; do
|
|
|
|
[[ -f $f/$BASE ]] || continue
|
|
|
|
FILE="$f/$BASE"
|
|
|
|
break
|
|
|
|
done
|
|
|
|
IF_dynamic="yes"
|
|
|
|
}
|
|
|
|
FILES+=("$FILE")
|
|
|
|
done < <(LD_TRACE_PRELINKING=1 LD_WARN= LD_TRACE_LOADED_OBJECTS=1 \
|
|
|
|
$LDSO $bin 2>/dev/null)
|
|
|
|
|
|
|
|
echo "${FILES[@]}"
|
|
|
|
}
|
|
|
|
|
|
|
|
inst() {
|
|
|
|
if (($# != 2 && $# != 3));then
|
|
|
|
echo "usage: inst <file> <root> [<destination file>]"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
local file="$1" ; shift
|
|
|
|
local root="${1%%/}" ; shift
|
|
|
|
local dest="${1##/}"
|
|
|
|
[[ $dest ]] || dest="${file##/}"
|
|
|
|
|
|
|
|
mkdir -p "$root/${dest%/*}"
|
|
|
|
|
|
|
|
local RET=0
|
|
|
|
local target=""
|
|
|
|
[ -L "$file" ] && target=$(readlink "$file")
|
|
|
|
if [[ $target && $dest != $target ]]; then
|
|
|
|
if [[ -e $root/$dest ]]; then
|
|
|
|
RET=0
|
|
|
|
else
|
|
|
|
ln -sf "$target" "$root/$dest"
|
|
|
|
#inst "$target" "$root"
|
|
|
|
local BASE=${target##*/}
|
|
|
|
local LIBDIR=`echo "$file" | sed -e 's,\(\(.*\)/\)[^/]\+$,\1,'`
|
|
|
|
if [[ $LIBDIR = $BASE ]]; then
|
|
|
|
local LIBDIR=`echo "/$dest" | sed -e 's,\(\(.*\)/\)[^/]\+$,\1,'`
|
|
|
|
fi
|
|
|
|
|
|
|
|
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 "$LIBDIR/$BASE" "$root" "$TLIBDIR/$BASE"
|
|
|
|
RET=$?
|
|
|
|
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=$?
|
|
|
|
return $RET
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [[ -e $root/$dest ]]; then
|
|
|
|
RET=0
|
|
|
|
else
|
|
|
|
if [[ $target && -L $target ]]; then
|
|
|
|
inst "$target" "$root"
|
|
|
|
RET=$?
|
|
|
|
else
|
|
|
|
cp -aL "$file" "$root/$dest"
|
|
|
|
|
|
|
|
local DEPS=$(get_dso_deps "$file")
|
|
|
|
if [[ $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
|
|
|
|
return $RET
|
|
|
|
}
|
|
|
|
|
|
|
|
# module dep finding and installation functions
|
|
|
|
moduledep() {
|
|
|
|
MPARGS=""
|
|
|
|
if [ "$1" == "--ignore-install" ]; then
|
|
|
|
MPARGS="$MPARGS --ignore-install"
|
|
|
|
shift
|
|
|
|
fi
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
|
|
|
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=$(find $modDir -name $1.ko |awk {'print $1; exit;'})
|
|
|
|
if [ -n "$fmPath" -a -f "$fmPath" ]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
done
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
resolveAndExpandModules() {
|
|
|
|
items=$*
|
|
|
|
|
|
|
|
mods=$(expandModules $items)
|
|
|
|
resdeps mods
|
|
|
|
echo $resolved
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
MNTIMAGE=$2
|
|
|
|
fmPath=""
|
|
|
|
locatemodule $MPARGS $MODULE
|
|
|
|
MODULE=$fmPath
|
|
|
|
if [ -z "$MODULE" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
if [ -x /usr/bin/strip ]; then
|
|
|
|
/usr/bin/strip -g $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})
|
|
|
|
while [ $before != $after ]; do
|
|
|
|
before=$(echo $items | wc -c)
|
|
|
|
list=""
|
|
|
|
|
|
|
|
for i in $items ; do
|
|
|
|
deps=""
|
|
|
|
moduledep $i
|
|
|
|
list="$list $deps"
|
|
|
|
done
|
|
|
|
items=$(for n in $items $list; do echo $n; done | sort -u)
|
|
|
|
after=`echo $items | wc -c`
|
|
|
|
done
|
|
|
|
|
|
|
|
resolved="$items"
|
|
|
|
}
|
|
|
|
|
|
|
|
findkeymap () {
|
|
|
|
local MAP=$1
|
|
|
|
|
|
|
|
if [ ! -f "$MAP" ]; then
|
|
|
|
MAP=$(find /lib/kbd/keymaps -type f -name $MAP -o -name $MAP.\* | head -n1)
|
|
|
|
fi
|
|
|
|
|
|
|
|
case " $KEYMAPS " in
|
|
|
|
*" $MAP "*)
|
|
|
|
return
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
KEYMAPS="$KEYMAPS $MAP"
|
|
|
|
|
|
|
|
case $MAP in
|
|
|
|
*.gz)
|
|
|
|
cmd=zgrep
|
|
|
|
;;
|
|
|
|
*.bz2)
|
|
|
|
cmd=bzgrep
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
cmd=grep
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
for INCL in $($cmd "^include " $MAP | cut -d' ' -f2 | tr -d '"'); do
|
|
|
|
for FN in $(find /lib/kbd/keymaps -type f -name $INCL\*); do
|
|
|
|
findkeymap $FN
|
|
|
|
done
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# vim:ts=8:sw=4:sts=4:et
|