dracut/dracut-functions
Seewer Philippe 9b88534374 Fix find_binary always succeeding
find_binary inside dracut-functions always succeeds. Independent of
whether the file actually exists or not.

This patch fixes this.

And since we're using the function not only to find binaries at little
enhancement there shouldn't be that bad either.

--
dracut-functions |   21 ++++++++++++++++-----
  1 files changed, 16 insertions(+), 5 deletions(-)
2009-03-04 17:05:58 +01:00

213 lines
5.9 KiB
Bash
Executable File

#!/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=""
strstr() { [[ ! ${1#*$2*} = $1 ]]; }
# $1 = file to copy to ramdisk
# $2 (optional) Name for the file on the ramdisk
# Location of the image dir is assumed to be $initdir
inst_simple() {
local src=$1 target="${initdir}${2:-$1}"
[[ -f $target ]] && return 0
mkdir -p "${target%/*}"
echo "Installing $src" >&2
cp -fL "$src" "$target"
}
inst_library() {
local src=$1 dest=${2:-$1}
[[ -f $initdir$dest ]] && return 0
if [[ -L $src ]]; then
reallib="$(readlink "$src")"
lib=${src##*/}
realsrc="${src%/*}/$reallib"
realdest="${dest%/*}/$reallib"
inst_simple "$realsrc" "$realdest"
(cd "${initdir}${dest%/*}" && ln -s "$reallib" "$lib")
else
inst_simple "$src" "$dest"
fi
}
find_file() {
local binpath="/bin /sbin /usr/bin /usr/sbin" p
#Full path or not?
if [[ ${1##*/} != $1 ]] ; then
if [[ -e $1 ]] ; then
echo $1;
return 0;
fi
return 1;
fi
#Search in path
for p in $binpath; do
[[ -x $p/$1 ]] && { echo "$p/$1"; return 0; }
[[ -e $p/$1 ]] && { echo "$p/$1"; return 0; }
done
return 1
}
# Same as above.
# If the file is a binary executable, install all its
# shared library dependencies, if any.
inst_binary() {
local bin="$1" target="${2:-$1}"
local LDSO NAME IO FILE ADDR I1 n f TLIBDIR
[[ -f $initdir$target ]] && return 0
# I love bash!
while read line; do
[[ $line = 'not a dynamic executable' ]] && return 1
[[ $line =~ 'not found' ]] &&{
echo "Missing a shared library required by $bin." >&2
echo "Run \"ldd $bin\" to find out what it is." >&2
echo "dracut cannot create an initrd." >&2
exit 1
}
[[ $line =~ '([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*)' ]] || continue
FILE=${BASH_REMATCH[1]}
[[ -f ${initdir}$FILE ]] && continue
# 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
inst_library "$FILE" "$TLIBDIR/$BASE"
IF_dynamic="yes"
continue
}
inst_library "$FILE"
done < <(ldd $bin 2>/dev/null)
inst_simple "$bin" "$target"
}
# same as above, except for shell scripts.
# If your shell script does not start with shebang, it is not a shell script.
inst_script() {
local src=$1 target=${2:-$1} line
read -r -n 80 line <"$src"
[[ $line =~ '(#! *)(/[^ ]+).*' ]] || return 1
inst "${BASH_REMATCH[2]}" && inst_simple "$src" "$target"
}
# same as above, but specialized for symlinks
inst_symlink() {
local src=$1 target=$initdir${2:-$1} realsrc
[[ -L $1 ]] || return 1
[[ -L $target ]] && return 0
realsrc=$(readlink "$src")
[[ $realsrc = ${realsrc##*/} ]] && realsrc="${src%/*}/$realsrc"
inst "$realsrc" && ln -s "$realsrc" "$target"
}
# udev rules always get installed in the same place, so
# create a function to install them to make life simpler.
inst_rules() {
for rule in "$@"; do
inst_simple "$rule" "/lib/udev/rules.d/${rule##*/}"
done
}
# general purpose installation function
# Same args as above.
inst() {
if (($# != 1 && $# != 2)); then
echo "usage: inst <file> <root> [<destination file>]"
return 1
fi
local src=$(find_file "$1") || {
echo "Cannot find requested file $1. Exiting."
exit 1
}
local dest=${2:-$src}
for x in inst_symlink inst_script inst_binary inst_simple; do
$x "$src" "$dest" && return 0
done
return 1
}
# install function specialized for hooks
# $1 = type of hook, $2 = hook priority (lower runs first), $3 = hook
# All hooks should be POSIX/SuS compliant, they will be sourced by init.
inst_hook() {
[[ -f $3 ]] || {
echo "Cannot install a hook ($3) that does not exist." >&2
echo "Aborting initrd creation." >&2
exit 1
}
strstr "$hookdirs" "$1" || {
echo "No such hook type $1. Aborting initrd creation." >&2
exit 1
}
inst_simple "$3" "/${1}/${2}${3##*/}"
}
dracut_install() {
while (($# > 0)); do
inst "$1" && shift
done
}
modcat="/lib/modules/$kernel/modules"
instmods() {
local mod mpargs modpath modname cmd
while (($# > 0)); do
mod=${1%.ko}
case $mod in
=ata) instmods $mpargs $(cat "${modcat}.block" |egrep 'ata|ahci');;
=*) instmods $mpargs $(cat "${modcat}.${mod#=}");;
--*) mpargs+=" $mod";;
*) modprobe $mpargs --set-version $kernel --show-depends $mod \
2>/dev/null |while read cmd modpath options; do
[[ $cmd = insmod ]] || continue
modname=${modpath##*/}
modname=${modname%.ko}
[[ ${mod/-/_} != ${modname/-/_} ]] && {
instmods $mpargs $modname
continue
}
inst_simple "$modpath" "/lib/modules/$kernel/$modname.ko"
done
;;
esac
shift
done
for fw in $(/sbin/modinfo -F firmware $mod 2>/dev/null); do
if [ -f /lib/firmware/$fw ]; then
inst_simple "/lib/firmware/$fw"
fi
done
}
# vim:ts=8:sw=4:sts=4:et