Line 0
Link Here
|
|
|
1 |
# Functions imported from Dracut to help locate, unsymlink, strip, and install |
2 |
# executables and the libraries they require to run. |
3 |
# Dracut is licensed under the terms of GPL-2. |
4 |
# |
5 |
### Original Dracut copyright message: |
6 |
### |
7 |
### Copyright 2005-2009 Red Hat, Inc. All rights reserved. |
8 |
### |
9 |
### This program is free software; you can redistribute it and/or modify |
10 |
### it under the terms of the GNU General Public License as published by |
11 |
### the Free Software Foundation; either version 2 of the License, or |
12 |
### (at your option) any later version. |
13 |
### |
14 |
### This program is distributed in the hope that it will be useful, |
15 |
### but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 |
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 |
### GNU General Public License for more details. |
18 |
### |
19 |
### You should have received a copy of the GNU General Public License |
20 |
### along with this program. If not, see <http://www.gnu.org/licenses/>. |
21 |
|
22 |
ddebug() { |
23 |
print_info 4 "$1" |
24 |
} |
25 |
|
26 |
# Install a directory, keeping symlinks as on the original system. |
27 |
# Example: if /lib64 points to /lib on the host, "inst_dir /lib/file" |
28 |
# will create ${initdir}/lib64, ${initdir}/lib64/file, |
29 |
# and a symlink ${initdir}/lib -> lib64. |
30 |
inst_dir() { |
31 |
local dir="$1" |
32 |
[[ -e ${initdir}$dir ]] && return 0 |
33 |
|
34 |
# iterate over parent directories |
35 |
local file="" |
36 |
local IFS="/" |
37 |
for part in $dir; do |
38 |
[[ $part ]] || continue |
39 |
file="$file/$part" |
40 |
[[ -e ${initdir}$file ]] && continue |
41 |
|
42 |
if [[ -L $file ]]; then |
43 |
# create link as the original |
44 |
local target=$(readlink "$file") |
45 |
ln -sfn "$target" "${initdir}$file" || return 1 |
46 |
# resolve relative path and recursively install destination |
47 |
[[ $target == ${target#/} ]] && target="$(dirname "$file")/$target" |
48 |
inst_dir "$target" |
49 |
else |
50 |
# create directory |
51 |
mkdir -m 0755 -p "${initdir}$file" || return 1 |
52 |
fi |
53 |
done |
54 |
} |
55 |
|
56 |
# $1 = file to copy to ramdisk |
57 |
# $2 (optional) Name for the file on the ramdisk |
58 |
# Location of the image dir is assumed to be $initdir |
59 |
# We never overwrite the target if it exists. |
60 |
inst_simple() { |
61 |
local src target |
62 |
[[ -f $1 ]] || return 1 |
63 |
src=$1 target="${2:-$1}" |
64 |
if ! [[ -d ${initdir}$target ]]; then |
65 |
[[ -e ${initdir}$target ]] && return 0 |
66 |
inst_dir "${target%/*}" |
67 |
fi |
68 |
# install checksum files also |
69 |
if [[ -e "${src%/*}/.${src##*/}.hmac" ]]; then |
70 |
instd "${src%/*}/.${src##*/}.hmac" "${target%/*}/.${target##*/}.hmac" |
71 |
fi |
72 |
ddebug "Installing $src to ${initdir}$target" |
73 |
cp -pfL "$src" "${initdir}$target" |
74 |
} |
75 |
|
76 |
# find symlinks linked to given library file |
77 |
# $1 = library file |
78 |
# Function searches for symlinks by stripping version numbers appended to |
79 |
# library filename, checks if it points to the same target and finally |
80 |
# prints the list of symlinks to stdout. |
81 |
# |
82 |
# Example: |
83 |
# rev_lib_symlinks libfoo.so.8.1 |
84 |
# output: libfoo.so.8 libfoo.so |
85 |
# (Only if libfoo.so.8 and libfoo.so exists on host system.) |
86 |
rev_lib_symlinks() { |
87 |
[[ ! $1 ]] && return 0 |
88 |
|
89 |
local fn="$1" orig="$(readlink -f "$1")" links='' |
90 |
|
91 |
[[ ${fn} =~ .*\.so\..* ]] || return 1 |
92 |
|
93 |
until [[ ${fn##*.} == so ]]; do |
94 |
fn="${fn%.*}" |
95 |
[[ -L ${fn} && $(readlink -f "${fn}") == ${orig} ]] && links+=" ${fn}" |
96 |
done |
97 |
|
98 |
echo "${links}" |
99 |
} |
100 |
|
101 |
# Same as above, but specialized to handle dynamic libraries. |
102 |
# It handles making symlinks according to how the original library |
103 |
# is referenced. |
104 |
inst_library() { |
105 |
local src=$1 dest=${2:-$1} lib reallib symlink |
106 |
[[ -e $initdir$dest ]] && return 0 |
107 |
if [[ -L $src ]]; then |
108 |
# install checksum files also |
109 |
if [[ -e "${src%/*}/.${src##*/}.hmac" ]]; then |
110 |
instd "${src%/*}/.${src##*/}.hmac" "${dest%/*}/.${dest##*/}.hmac" |
111 |
fi |
112 |
reallib=$(readlink -f "$src") |
113 |
lib=${src##*/} |
114 |
inst_simple "$reallib" "$reallib" |
115 |
inst_dir "${dest%/*}" |
116 |
(cd "${initdir}${dest%/*}" && ln -s "$reallib" "$lib") |
117 |
else |
118 |
inst_simple "$src" "$dest" |
119 |
fi |
120 |
|
121 |
# Create additional symlinks. See rev_symlinks description. |
122 |
for symlink in $(rev_lib_symlinks $src) $(rev_lib_symlinks $reallib); do |
123 |
[[ ! -e $initdir$symlink ]] && { |
124 |
ddebug "Creating extra symlink: $symlink" |
125 |
inst_symlink $symlink |
126 |
} |
127 |
done |
128 |
} |
129 |
|
130 |
# find a binary. If we were not passed the full path directly, |
131 |
# search in the usual places to find the binary. |
132 |
find_binary() { |
133 |
local binpath="/bin /sbin /usr/bin /usr/sbin" p |
134 |
if [[ -z ${1##/*} ]]; then |
135 |
if [[ -x $1 ]] || ldd $1 &>/dev/null; then |
136 |
echo $1 |
137 |
return 0 |
138 |
fi |
139 |
fi |
140 |
for p in $binpath; do |
141 |
[[ -x $p/$1 ]] && { echo "$p/$1"; return 0; } |
142 |
done |
143 |
return 1 |
144 |
} |
145 |
|
146 |
# Same as above, but specialized to install binary executables. |
147 |
# Install binary executable, and all shared library dependencies, if any. |
148 |
inst_binary() { |
149 |
local bin target |
150 |
bin=$(find_binary "$1") || return 1 |
151 |
target=${2:-$bin} |
152 |
inst_symlink $bin $target && return 0 |
153 |
local LDSO NAME IO FILE ADDR I1 n f TLIBDIR |
154 |
[[ -e $initdir$target ]] && return 0 |
155 |
# I love bash! |
156 |
LC_ALL=C ldd $bin 2>/dev/null | while read line; do |
157 |
[[ $line = 'not a dynamic executable' ]] && return 1 |
158 |
if [[ $line =~ not\ found ]]; then |
159 |
dfatal "Missing a shared library required by $bin." |
160 |
dfatal "Run \"ldd $bin\" to find out what it is." |
161 |
dfatal "genkernel cannot create an initramfs." |
162 |
exit 1 |
163 |
fi |
164 |
so_regex='([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*)' |
165 |
[[ $line =~ $so_regex ]] || continue |
166 |
FILE=${BASH_REMATCH[1]} |
167 |
[[ -e ${initdir}$FILE ]] && continue |
168 |
# see if we are loading an optimized version of a shared lib. |
169 |
lib_regex='^(/lib[^/]*).*' |
170 |
if [[ $FILE =~ $lib_regex ]]; then |
171 |
TLIBDIR=${BASH_REMATCH[1]} |
172 |
BASE=${FILE##*/} |
173 |
# prefer nosegneg libs, then unoptimized ones. |
174 |
for f in "$TLIBDIR/i686/nosegneg" "$TLIBDIR"; do |
175 |
[[ -e $f/$BASE ]] || continue |
176 |
FILE=$f/$BASE |
177 |
break |
178 |
done |
179 |
inst_library "$FILE" "$TLIBDIR/$BASE" |
180 |
IF_dynamic=yes |
181 |
continue |
182 |
fi |
183 |
inst_library "$FILE" |
184 |
done |
185 |
inst_simple "$bin" "$target" |
186 |
} |
187 |
|
188 |
# same as above, but specialized for symlinks |
189 |
inst_symlink() { |
190 |
local src=$1 target=$initdir${2:-$1} realsrc |
191 |
[[ -L $1 ]] || return 1 |
192 |
[[ -L $target ]] && return 0 |
193 |
realsrc=$(readlink -f "$src") |
194 |
[[ $realsrc = ${realsrc##*/} ]] && realsrc=${src%/*}/$realsrc |
195 |
instd "$realsrc" && mkdir -m 0755 -p "${target%/*}" && \ |
196 |
ln -s "$realsrc" "$target" |
197 |
} |
198 |
|
199 |
# general purpose installation function |
200 |
# Same args as above. |
201 |
instd() { |
202 |
case $# in |
203 |
1) ;; |
204 |
2) [[ ! $initdir && -d $2 ]] && export initdir=$2 |
205 |
[[ $initdir = $2 ]] && set $1;; |
206 |
3) [[ -z $initdir ]] && export initdir=$2 |
207 |
set $1 $3;; |
208 |
*) dfatal "inst only takes 1 or 2 or 3 arguments" |
209 |
exit 1;; |
210 |
esac |
211 |
#inst_script |
212 |
for x in inst_symlink inst_binary inst_simple; do |
213 |
$x "$@" && return 0 |
214 |
done |
215 |
return 1 |
216 |
} |