You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

182 lines
5.3 KiB

#!/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=""
# $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
echo "Installing $src to $target"
mkdir -p "${target%/*}"
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
}
# 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
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
exit 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
inst_library "$FILE" "$TLIBDIR/$BASE"
IF_dynamic="yes"
continue
}
inst_library "$FILE"
done < <(LD_TRACE_PRELINKING=1 LD_WARN= LD_TRACE_LOADED_OBJECTS=1 \
$LDSO $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"
}
# general purpose installation function
# Same args as above.
# Just tries to install as a binary, a shell script, then a simple data file.
inst() {
if (($# != 1 && $# != 2)); then
echo "usage: inst <file> <root> [<destination file>]"
return 1
fi
local src=$1 dest=${2:-$1}
for x in inst_symlink inst_binary inst_script inst_simple; do
$x "$src" "$dest" && return 0
done
return 1
}
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; 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
}
findkeymap () {
local MAP=$1
[[ ! -f $MAP ]] && \
MAP=$(find /lib/kbd/keymaps -type f -name $MAP -o -name $MAP.\* | head -n1)
[[ " $KEYMAPS " = *" $MAP "* ]] && return
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