]>
Commit | Line | Data |
---|---|---|
04b56f3a JK |
1 | #!/bin/bash |
2 | # | |
3 | # functions used by mkinitrd and other tools. | |
4 | # | |
5 | # Copyright 2005-2008 Red Hat, Inc. All rights reserved. | |
6 | # | |
7 | # This program is free software; you can redistribute it and/or modify | |
8 | # it under the terms of the GNU General Public License as published by | |
9 | # the Free Software Foundation; either version 2 of the License, or | |
10 | # (at your option) any later version. | |
11 | # | |
12 | # This program is distributed in the hope that it will be useful, | |
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | # GNU General Public License for more details. | |
16 | # | |
17 | # You should have received a copy of the GNU General Public License | |
0f9c78c1 | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
04b56f3a JK |
19 | # |
20 | # Authors: | |
21 | # Peter Jones <pjones@redhat.com> | |
22 | # Jeremy Katz <katzj@redhat.com> | |
23 | # Jakub Jelinek <jakub@redhat.com> | |
04b56f3a JK |
24 | |
25 | IF_RTLD="" | |
26 | IF_dynamic="" | |
36b24d7c | 27 | |
3198f171 | 28 | # Generic substring function. If $2 is in $1, return 0. |
f04dc5f3 VL |
29 | strstr() { [[ ! ${1#*$2*} = $1 ]]; } |
30 | ||
6fac4691 HH |
31 | dwarning() { |
32 | echo "W: $@" >&2 | |
33 | } | |
34 | ||
35 | dinfo() { | |
84ffb877 | 36 | [[ $beverbose ]] && echo "I: $@" >&2 |
6fac4691 HH |
37 | } |
38 | ||
39 | derror() { | |
40 | echo "E: $@" >&2 | |
41 | } | |
42 | ||
36b24d7c VL |
43 | # $1 = file to copy to ramdisk |
44 | # $2 (optional) Name for the file on the ramdisk | |
45 | # Location of the image dir is assumed to be $initdir | |
3198f171 | 46 | # We never overwrite the target if it exists. |
36b24d7c | 47 | inst_simple() { |
54b44196 VL |
48 | local src target |
49 | [[ -f $1 ]] || return 1 | |
50 | src=$1 target="${initdir}${2:-$1}" | |
36b24d7c | 51 | [[ -f $target ]] && return 0 |
36b24d7c | 52 | mkdir -p "${target%/*}" |
6fac4691 | 53 | dinfo "Installing $src" |
36b24d7c VL |
54 | cp -fL "$src" "$target" |
55 | } | |
56 | ||
3198f171 VL |
57 | # Same as above, but specialzed to handle dynamic libraries. |
58 | # It handles making symlinks according to how the original library | |
59 | # is referenced. | |
36b24d7c VL |
60 | inst_library() { |
61 | local src=$1 dest=${2:-$1} | |
62 | [[ -f $initdir$dest ]] && return 0 | |
63 | if [[ -L $src ]]; then | |
9f88fcd9 | 64 | reallib="$(readlink -f "$src")" |
36b24d7c | 65 | lib=${src##*/} |
9f88fcd9 | 66 | inst_simple "$reallib" "$reallib" |
7bcacaaa | 67 | mkdir -p ${initdir}${dest%/*} |
36b24d7c VL |
68 | (cd "${initdir}${dest%/*}" && ln -s "$reallib" "$lib") |
69 | else | |
70 | inst_simple "$src" "$dest" | |
71 | fi | |
72 | } | |
3198f171 VL |
73 | |
74 | # find a binary. If we were not passed the full path directly, | |
75 | # search in the usual places to find the binary. | |
6b25d71a VL |
76 | find_binary() { |
77 | local binpath="/bin /sbin /usr/bin /usr/sbin" p | |
78 | [[ -x $1 ]] && { echo $1; return 0; } | |
3359c8da | 79 | for p in $binpath; do |
6b25d71a | 80 | [[ -x $p/$1 ]] && { echo "$p/$1"; return 0; } |
3359c8da VL |
81 | done |
82 | return 1 | |
83 | } | |
36b24d7c | 84 | |
3198f171 VL |
85 | # Same as above, but specialized to install binary executables. |
86 | # Install binary executable, and all shared library dependencies, if any. | |
36b24d7c | 87 | inst_binary() { |
54b44196 | 88 | local bin target |
6b25d71a | 89 | bin=$(find_binary "$1") || return 1 |
3198f171 | 90 | target=${2:-$bin} |
36b24d7c | 91 | local LDSO NAME IO FILE ADDR I1 n f TLIBDIR |
8c1faa35 | 92 | [[ -f $initdir$target ]] && return 0 |
8667f2b7 | 93 | # I love bash! |
5c862533 | 94 | ldd $bin 2>/dev/null | while read line; do |
f04dc5f3 | 95 | [[ $line = 'not a dynamic executable' ]] && return 1 |
59e3c455 | 96 | [[ $line =~ not\ found ]] &&{ |
6fac4691 HH |
97 | derror "Missing a shared library required by $bin." |
98 | derror "Run \"ldd $bin\" to find out what it is." | |
99 | derror "dracut cannot create an initrd." | |
36b24d7c | 100 | exit 1 |
f04dc5f3 | 101 | } |
59e3c455 | 102 | [[ $line =~ ([^ ]*/lib[^/]*/[^ ]*\.so[^ ]*) ]] || continue |
f04dc5f3 VL |
103 | FILE=${BASH_REMATCH[1]} |
104 | [[ -f ${initdir}$FILE ]] && continue | |
8667f2b7 | 105 | # see if we are loading an optimized version of a shared lib. |
59e3c455 | 106 | [[ $FILE =~ ^(/lib[^/]*).* ]] && { |
8667f2b7 VL |
107 | TLIBDIR=${BASH_REMATCH[1]} |
108 | BASE="${FILE##*/}" | |
109 | # prefer nosegneg libs, then unoptimized ones. | |
110 | for f in "$TLIBDIR/i686/nosegneg" "$TLIBDIR"; do | |
111 | [[ -f $f/$BASE ]] || continue | |
112 | FILE="$f/$BASE" | |
113 | break | |
114 | done | |
36b24d7c | 115 | inst_library "$FILE" "$TLIBDIR/$BASE" |
8667f2b7 | 116 | IF_dynamic="yes" |
36b24d7c | 117 | continue |
8667f2b7 | 118 | } |
36b24d7c | 119 | inst_library "$FILE" |
5c862533 | 120 | done |
3198f171 | 121 | inst_simple "$bin" "$target" |
36b24d7c | 122 | } |
04b56f3a | 123 | |
36b24d7c VL |
124 | # same as above, except for shell scripts. |
125 | # If your shell script does not start with shebang, it is not a shell script. | |
126 | inst_script() { | |
54b44196 | 127 | [[ -f $1 ]] || return 1 |
c7b2624f VL |
128 | local line |
129 | read -r -n 80 line <"$1" | |
00531568 AT |
130 | # If debug is set, clean unprintable chars to prevent messing up the term |
131 | [[ $debug ]] && line=$(echo -n "$line" | tr -c -d '[:print:][:space:]') | |
59e3c455 | 132 | [[ $line =~ (#! *)(/[^ ]+).* ]] || return 1 |
c7b2624f | 133 | inst "${BASH_REMATCH[2]}" && inst_simple "$@" |
04b56f3a JK |
134 | } |
135 | ||
36b24d7c VL |
136 | # same as above, but specialized for symlinks |
137 | inst_symlink() { | |
138 | local src=$1 target=$initdir${2:-$1} realsrc | |
139 | [[ -L $1 ]] || return 1 | |
140 | [[ -L $target ]] && return 0 | |
9f88fcd9 | 141 | realsrc=$(readlink -f "$src") |
36b24d7c VL |
142 | [[ $realsrc = ${realsrc##*/} ]] && realsrc="${src%/*}/$realsrc" |
143 | inst "$realsrc" && ln -s "$realsrc" "$target" | |
144 | } | |
145 | ||
3198f171 | 146 | # find a rule in the usual places. |
09805e02 VL |
147 | find_rule() { |
148 | for r in . /lib/udev/rules.d /etc/udev/rules.d $dsrc/rules.d; do | |
149 | [[ -f $r/$1 ]] && { echo "$r/$1"; return 0; } | |
150 | done | |
151 | return 1 | |
152 | } | |
153 | ||
f04dc5f3 VL |
154 | # udev rules always get installed in the same place, so |
155 | # create a function to install them to make life simpler. | |
156 | inst_rules() { | |
8faaa8f0 VL |
157 | local target="/etc/udev/rules.d" |
158 | mkdir -p "$initdir/lib/udev/rules.d" "$initdir$target" | |
f04dc5f3 | 159 | for rule in "$@"; do |
09805e02 | 160 | rule=$(find_rule $rule) && \ |
496d08bb | 161 | inst_simple "$rule" "$target/${rule##*/}" |
f04dc5f3 VL |
162 | done |
163 | } | |
164 | ||
36b24d7c VL |
165 | # general purpose installation function |
166 | # Same args as above. | |
6b24de99 | 167 | inst() { |
34fffd88 | 168 | if (($# != 1 && $# != 2 )); then |
6fac4691 | 169 | derror "inst only takes 1 or 2 arguments" |
74534e19 | 170 | exit 1 |
59dc3736 | 171 | fi |
8c1faa35 | 172 | for x in inst_symlink inst_script inst_binary inst_simple; do |
34fffd88 | 173 | $x "$@" && return 0 |
36b24d7c VL |
174 | done |
175 | return 1 | |
04b56f3a JK |
176 | } |
177 | ||
53f95456 VL |
178 | # install function specialized for hooks |
179 | # $1 = type of hook, $2 = hook priority (lower runs first), $3 = hook | |
180 | # All hooks should be POSIX/SuS compliant, they will be sourced by init. | |
181 | inst_hook() { | |
182 | [[ -f $3 ]] || { | |
6fac4691 HH |
183 | derror "Cannot install a hook ($3) that does not exist." |
184 | derror "Aborting initrd creation." | |
53f95456 VL |
185 | exit 1 |
186 | } | |
187 | strstr "$hookdirs" "$1" || { | |
6fac4691 | 188 | derror "No such hook type $1. Aborting initrd creation." |
53f95456 VL |
189 | exit 1 |
190 | } | |
191 | inst_simple "$3" "/${1}/${2}${3##*/}" | |
192 | } | |
193 | ||
f4fff04e VL |
194 | dracut_install() { |
195 | while (($# > 0)); do | |
1e5527e3 HH |
196 | if inst "$1" ; then |
197 | shift | |
198 | continue | |
199 | fi | |
6fac4691 | 200 | derror "Failed to install $1"; exit 1 |
f4fff04e VL |
201 | done |
202 | } | |
203 | ||
47507b21 | 204 | # install modules, and handle installing all their dependencies as well. |
6fa0c3d6 VL |
205 | instmods() { |
206 | local mod mpargs modpath modname cmd | |
5686cd41 | 207 | local srcmods="/lib/modules/$kernel/" |
6fa0c3d6 VL |
208 | while (($# > 0)); do |
209 | mod=${1%.ko} | |
210 | case $mod in | |
992acaa9 | 211 | =*) # This introduces 2 incompatible meanings for =* arguments |
74534e19 | 212 | # to instmods. We need to decide which one to keep. |
86c9fa48 | 213 | if [ "$mod" = "=ata" -a -f $srcmods/modules.block ] ; then |
8d385248 | 214 | instmods $mpargs $(egrep 'ata|ahci' "${srcmods}/modules.block") |
86c9fa48 | 215 | elif [ -f $srcmods/modules.${mod#=} ]; then |
8d385248 | 216 | instmods $mpargs $(cat ${srcmods}/modules.${mod#=} ) |
20122a83 | 217 | else |
8d385248 | 218 | instmods $mpargs $(find "$srcmods" -path "*/${mod#=}/*") |
20122a83 HH |
219 | fi |
220 | ;; | |
6fa0c3d6 | 221 | --*) mpargs+=" $mod";; |
cfee8a70 | 222 | *) mod=${mod##*/} |
3198f171 | 223 | [[ -f $initdir/$1 ]] && { shift; continue; } |
992acaa9 VL |
224 | modprobe $mpargs --ignore-install --set-version $kernel \ |
225 | --show-depends $mod 2>/dev/null | \ | |
226 | while read cmd modpath options; do | |
6fa0c3d6 VL |
227 | [[ $cmd = insmod ]] || continue |
228 | modname=${modpath##*/} | |
229 | modname=${modname%.ko} | |
230 | [[ ${mod/-/_} != ${modname/-/_} ]] && { | |
231 | instmods $mpargs $modname | |
232 | continue | |
233 | } | |
ca7d88da | 234 | inst_simple "$modpath" |
6fa0c3d6 VL |
235 | done |
236 | ;; | |
237 | esac | |
238 | shift | |
04b56f3a | 239 | done |
6fa0c3d6 | 240 | for fw in $(/sbin/modinfo -F firmware $mod 2>/dev/null); do |
04b56f3a | 241 | if [ -f /lib/firmware/$fw ]; then |
6fa0c3d6 | 242 | inst_simple "/lib/firmware/$fw" |
6fac4691 HH |
243 | else |
244 | dwarning "Possible missing firmware /lib/firmware/${fw} for module $(basename ${mod} .ko)" | |
04b56f3a JK |
245 | fi |
246 | done | |
6fa0c3d6 | 247 | } |
04b56f3a | 248 | |
04b56f3a | 249 | # vim:ts=8:sw=4:sts=4:et |