]>
Commit | Line | Data |
---|---|---|
8ce58f1f | 1 | #!/bin/sh |
cc02093d HH |
2 | # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- |
3 | # ex: ts=8 sw=4 sts=4 et filetype=sh | |
c98bcec8 HH |
4 | |
5 | # returns OK if $1 contains $2 | |
6 | strstr() { | |
cc02093d | 7 | [ "${1#*$2*}" != "$1" ] |
c98bcec8 HH |
8 | } |
9 | ||
ccb0ab73 AŻ |
10 | # returns OK if $1 contains $2 at the beginning |
11 | str_starts() { | |
12 | [ "${1#$2*}" != "$1" ] | |
13 | } | |
14 | ||
15 | # replaces all occurrences of 'search' in 'str' with 'replacement' | |
16 | # | |
17 | # str_replace str search replacement | |
18 | # | |
19 | # example: | |
20 | # str_replace ' one two three ' ' ' '_' | |
21 | str_replace() { | |
22 | local in="$1"; local s="$2"; local r="$3" | |
23 | local out='' | |
24 | ||
25 | while strstr "${in}" "$s"; do | |
26 | chop="${in%%$s*}" | |
27 | out="${out}${chop# }$r" | |
28 | in="${in#*$s}" | |
29 | done | |
30 | echo "${out}${in}" | |
31 | } | |
32 | ||
fa7ada31 HH |
33 | _getcmdline() { |
34 | local _line | |
35 | unset _line | |
c1a37d92 | 36 | if [ -z "$CMDLINE" ]; then |
2dfdcbf4 | 37 | if [ -e /etc/cmdline ]; then |
fa7ada31 HH |
38 | while read _line; do |
39 | CMDLINE_ETC="$CMDLINE_ETC $_line"; | |
2dfdcbf4 HH |
40 | done </etc/cmdline; |
41 | fi | |
cc02093d HH |
42 | read CMDLINE </proc/cmdline; |
43 | CMDLINE="$CMDLINE $CMDLINE_ETC" | |
c1a37d92 | 44 | fi |
fa7ada31 HH |
45 | } |
46 | ||
47 | _dogetarg() { | |
48 | local _o _val | |
49 | unset _val | |
50 | unset _o | |
51 | _getcmdline | |
52 | ||
53 | for _o in $CMDLINE; do | |
54 | if [ "$_o" = "$1" ]; then | |
3b403b32 | 55 | return 0; |
3a4d0c9c | 56 | fi |
fa7ada31 | 57 | [ "${_o%%=*}" = "${1%=}" ] && _val=${_o#*=}; |
df44688f | 58 | done |
fa7ada31 | 59 | if [ -n "$_val" ]; then |
3b403b32 | 60 | echo $_val; |
cc02093d | 61 | return 0; |
3a4d0c9c | 62 | fi |
fa7ada31 HH |
63 | return 1; |
64 | } | |
65 | ||
66 | getarg() { | |
67 | set +x | |
68 | while [ $# -gt 0 ]; do | |
69 | case $1 in | |
70 | -y) if _dogetarg $2; then | |
71 | echo 1 | |
9e7a3bf2 | 72 | [ "$RD_DEBUG" = "yes" ] && set -x |
fa7ada31 HH |
73 | return 0 |
74 | fi | |
75 | shift 2;; | |
76 | -n) if _dogetarg $2; then | |
77 | echo 0; | |
9e7a3bf2 | 78 | [ "$RD_DEBUG" = "yes" ] && set -x |
fa7ada31 HH |
79 | return 1 |
80 | fi | |
81 | shift 2;; | |
82 | *) if _dogetarg $1; then | |
9e7a3bf2 | 83 | [ "$RD_DEBUG" = "yes" ] && set -x |
fa7ada31 HH |
84 | return 0; |
85 | fi | |
86 | shift;; | |
87 | esac | |
88 | done | |
3b403b32 | 89 | [ "$RD_DEBUG" = "yes" ] && set -x |
df44688f DD |
90 | return 1 |
91 | } | |
ae5bc1fd | 92 | |
fa7ada31 HH |
93 | getargbool() { |
94 | local _b | |
95 | unset _b | |
96 | local _default | |
97 | _default=$1; shift | |
98 | _b=$(getarg "$@") | |
99 | [ $? -ne 0 -a -z "$_b" ] && _b=$_default | |
100 | if [ -n "$_b" ]; then | |
4ad45344 | 101 | [ $_b = "0" ] && return 1 |
fa7ada31 | 102 | [ $_b = "no" ] && return 1 |
c1a37d92 | 103 | fi |
fa7ada31 HH |
104 | return 0 |
105 | } | |
106 | ||
107 | _dogetargs() { | |
3b403b32 | 108 | set +x |
fa7ada31 HH |
109 | local _o _found |
110 | unset _o | |
111 | unset _found | |
112 | _getcmdline | |
113 | ||
114 | for _o in $CMDLINE; do | |
115 | if [ "$_o" = "$1" ]; then | |
cc02093d HH |
116 | return 0; |
117 | fi | |
fa7ada31 | 118 | if [ "${_o%%=*}" = "${1%=}" ]; then |
3b403b32 | 119 | echo -n "${_o#*=} "; |
fa7ada31 | 120 | _found=1; |
cc02093d | 121 | fi |
da1c03c8 | 122 | done |
fa7ada31 HH |
123 | [ -n "$_found" ] && return 0; |
124 | return 1; | |
125 | } | |
126 | ||
127 | getargs() { | |
128 | local _val | |
129 | unset _val | |
130 | set +x | |
131 | while [ $# -gt 0 ]; do | |
132 | _val="$_val $(_dogetargs $1)" | |
133 | shift | |
134 | done | |
135 | if [ -n "$_val" ]; then | |
136 | echo -n $_val | |
3b403b32 | 137 | [ "$RD_DEBUG" = "yes" ] && set -x |
fa7ada31 | 138 | return 0 |
3a4d0c9c | 139 | fi |
3b403b32 | 140 | [ "$RD_DEBUG" = "yes" ] && set -x |
4bb570c9 | 141 | return 1; |
da1c03c8 HH |
142 | } |
143 | ||
fa7ada31 | 144 | |
2926b5b3 AŻ |
145 | # Prints value of given option. If option is a flag and it's present, |
146 | # it just returns 0. Otherwise 1 is returned. | |
147 | # $1 = options separated by commas | |
148 | # $2 = option we are interested in | |
3b403b32 | 149 | # |
2926b5b3 AŻ |
150 | # Example: |
151 | # $1 = cipher=aes-cbc-essiv:sha256,hash=sha256,verify | |
152 | # $2 = hash | |
153 | # Output: | |
154 | # sha256 | |
155 | getoptcomma() { | |
156 | local line=",$1,"; local opt="$2"; local tmp | |
157 | ||
158 | case "${line}" in | |
159 | *,${opt}=*,*) | |
160 | tmp="${line#*,${opt}=}" | |
161 | echo "${tmp%%,*}" | |
162 | return 0 | |
cc02093d HH |
163 | ;; |
164 | *,${opt},*) return 0;; | |
2926b5b3 | 165 | esac |
2926b5b3 AŻ |
166 | return 1 |
167 | } | |
168 | ||
ccb0ab73 AŻ |
169 | # Splits given string 'str' with separator 'sep' into variables 'var1', 'var2', |
170 | # 'varN'. If number of fields is less than number of variables, remaining are | |
171 | # not set. If number of fields is greater than number of variables, the last | |
172 | # variable takes remaining fields. In short - it acts similary to 'read'. | |
173 | # | |
174 | # splitsep sep str var1 var2 varN | |
175 | # | |
176 | # example: | |
177 | # splitsep ':' 'foo:bar:baz' v1 v2 | |
178 | # in result: | |
179 | # v1='foo', v2='bar:baz' | |
180 | # | |
181 | # TODO: ':' inside fields. | |
182 | splitsep() { | |
183 | local sep="$1"; local str="$2"; shift 2 | |
184 | local tmp | |
185 | ||
186 | while [ -n "$str" -a -n "$*" ]; do | |
7a8a33b6 | 187 | tmp="${str%%$sep*}" |
ccb0ab73 AŻ |
188 | eval "$1=${tmp}" |
189 | str="${str#$tmp}" | |
7a8a33b6 | 190 | str="${str#$sep}" |
ccb0ab73 AŻ |
191 | shift |
192 | done | |
193 | ||
194 | return 0 | |
195 | } | |
196 | ||
4bb570c9 | 197 | setdebug() { |
9e7a3bf2 | 198 | if [ -z "$RD_DEBUG" ]; then |
4bb570c9 | 199 | if [ -e /proc/cmdline ]; then |
9e7a3bf2 | 200 | RD_DEBUG=no |
fa7ada31 | 201 | if getargbool 0 rd.debug -y rdinitdebug -y rdnetdebug; then |
3b403b32 | 202 | RD_DEBUG=yes |
0d837ebf HH |
203 | [ -n "$BASH" ] && \ |
204 | export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): '; | |
205 | fi | |
4bb570c9 | 206 | fi |
9e7a3bf2 | 207 | export RD_DEBUG |
4bb570c9 | 208 | fi |
3b403b32 | 209 | [ "$RD_DEBUG" = "yes" ] && set -x |
4bb570c9 HH |
210 | } |
211 | ||
c98bcec8 | 212 | setdebug |
4bb570c9 | 213 | |
ae5bc1fd DD |
214 | source_all() { |
215 | local f | |
216 | [ "$1" ] && [ -d "/$1" ] || return | |
54a73cbb | 217 | for f in "/$1"/*.sh; do [ -e "$f" ] && . "$f"; done |
ae5bc1fd | 218 | } |
51031303 | 219 | |
0b53ca70 HH |
220 | hookdir=/lib/dracut/hooks |
221 | export hookdir | |
222 | ||
223 | source_hook() { | |
224 | source_all "/lib/dracut/hooks/$1" | |
225 | } | |
226 | ||
8238850c HH |
227 | check_finished() { |
228 | local f | |
0b53ca70 | 229 | for f in $hookdir/initqueue/finished/*.sh; do { [ -e "$f" ] && ( . "$f" ) ; } || return 1 ; done |
8238850c HH |
230 | return 0 |
231 | } | |
232 | ||
0375106c HH |
233 | source_conf() { |
234 | local f | |
235 | [ "$1" ] && [ -d "/$1" ] || return | |
54a73cbb | 236 | for f in "/$1"/*.conf; do [ -e "$f" ] && . "$f"; done |
0375106c HH |
237 | } |
238 | ||
311a2769 | 239 | die() { |
449adc61 | 240 | { |
79471f36 HH |
241 | echo "<24>dracut: FATAL: $@"; |
242 | echo "<24>dracut: Refusing to continue"; | |
449adc61 HH |
243 | } > /dev/kmsg |
244 | ||
3b403b32 | 245 | { |
535ad9d1 HH |
246 | echo "warn dracut: FATAL: \"$@\""; |
247 | echo "warn dracut: Refusing to continue"; | |
248 | echo "exit 1" | |
0b53ca70 | 249 | } >> $hookdir/emergency/01-die.sh |
535ad9d1 | 250 | |
03f405bc | 251 | > /run/initramfs/.die |
311a2769 PS |
252 | exit 1 |
253 | } | |
254 | ||
695de849 HH |
255 | check_quiet() { |
256 | if [ -z "$DRACUT_QUIET" ]; then | |
cc02093d | 257 | DRACUT_QUIET="yes" |
fa7ada31 | 258 | getargbool 0 rd.info -y rdinfo && DRACUT_QUIET="no" |
cc02093d | 259 | getarg quiet || DRACUT_QUIET="yes" |
695de849 HH |
260 | fi |
261 | } | |
262 | ||
9f10836d | 263 | warn() { |
695de849 | 264 | check_quiet |
79471f36 | 265 | echo "<28>dracut Warning: $@" > /dev/kmsg |
695de849 | 266 | [ "$DRACUT_QUIET" != "yes" ] && \ |
cc02093d | 267 | echo "dracut Warning: $@" >&2 |
449adc61 HH |
268 | } |
269 | ||
270 | info() { | |
695de849 | 271 | check_quiet |
79471f36 | 272 | echo "<30>dracut: $@" > /dev/kmsg |
c0dc4c5d | 273 | [ "$DRACUT_QUIET" != "yes" ] && \ |
3b403b32 | 274 | echo "dracut: $@" |
449adc61 HH |
275 | } |
276 | ||
277 | vinfo() { | |
3b403b32 | 278 | while read line; do |
449adc61 HH |
279 | info $line; |
280 | done | |
9f10836d PS |
281 | } |
282 | ||
51031303 DD |
283 | check_occurances() { |
284 | # Count the number of times the character $ch occurs in $str | |
285 | # Return 0 if the count matches the expected number, 1 otherwise | |
286 | local str="$1" | |
287 | local ch="$2" | |
288 | local expected="$3" | |
289 | local count=0 | |
290 | ||
291 | while [ "${str#*$ch}" != "${str}" ]; do | |
cc02093d HH |
292 | str="${str#*$ch}" |
293 | count=$(( $count + 1 )) | |
51031303 DD |
294 | done |
295 | ||
296 | [ $count -eq $expected ] | |
297 | } | |
07b2fbb1 PS |
298 | |
299 | incol2() { | |
300 | local dummy check; | |
301 | local file="$1"; | |
302 | local str="$2"; | |
303 | ||
a2cb4dbc HH |
304 | [ -z "$file" ] && return 1; |
305 | [ -z "$str" ] && return 1; | |
07b2fbb1 PS |
306 | |
307 | while read dummy check restofline; do | |
cc02093d | 308 | [ "$check" = "$str" ] && return 0 |
07b2fbb1 PS |
309 | done < $file |
310 | return 1 | |
311 | } | |
5c6a593f HH |
312 | |
313 | udevsettle() { | |
8ef0be56 HH |
314 | [ -z "$UDEVVERSION" ] && UDEVVERSION=$(udevadm --version) |
315 | ||
5c6a593f | 316 | if [ $UDEVVERSION -ge 143 ]; then |
0b53ca70 | 317 | udevadm settle --exit-if-exists=$hookdir/initqueue/work $settle_exit_if_exists |
5c6a593f HH |
318 | else |
319 | udevadm settle --timeout=30 | |
320 | fi | |
321 | } | |
273b197d | 322 | |
1dd5bc3f HH |
323 | udevproperty() { |
324 | [ -z "$UDEVVERSION" ] && UDEVVERSION=$(udevadm --version) | |
325 | ||
326 | if [ $UDEVVERSION -ge 143 ]; then | |
cc02093d | 327 | for i in "$@"; do udevadm control --property=$i; done |
1dd5bc3f | 328 | else |
cc02093d | 329 | for i in "$@"; do udevadm control --env=$i; done |
1dd5bc3f HH |
330 | fi |
331 | } | |
332 | ||
6822764f HH |
333 | ismounted() { |
334 | while read a m a; do | |
335 | [ "$m" = "$1" ] && return 0 | |
336 | done < /proc/mounts | |
337 | return 1 | |
338 | } | |
339 | ||
bf87d252 HH |
340 | wait_for_if_up() { |
341 | local cnt=0 | |
3b403b32 | 342 | while [ $cnt -lt 20 ]; do |
cc02093d HH |
343 | li=$(ip link show $1) |
344 | [ -z "${li##*state UP*}" ] && return 0 | |
345 | sleep 0.1 | |
346 | cnt=$(($cnt+1)) | |
3b403b32 | 347 | done |
bf87d252 HH |
348 | return 1 |
349 | } | |
c98bcec8 | 350 | |
3b403b32 | 351 | # root=nfs:[<server-ip>:]<root-dir>[:<nfs-options>] |
c98bcec8 HH |
352 | # root=nfs4:[<server-ip>:]<root-dir>[:<nfs-options>] |
353 | nfsroot_to_var() { | |
354 | # strip nfs[4]: | |
355 | local arg="$@:" | |
356 | nfs="${arg%%:*}" | |
357 | arg="${arg##$nfs:}" | |
c98bcec8 HH |
358 | |
359 | # check if we have a server | |
360 | if strstr "$arg" ':/*' ; then | |
cc02093d HH |
361 | server="${arg%%:/*}" |
362 | arg="/${arg##*:/}" | |
c98bcec8 HH |
363 | fi |
364 | ||
365 | path="${arg%%:*}" | |
366 | ||
367 | # rest are options | |
368 | options="${arg##$path}" | |
369 | # strip leading ":" | |
370 | options="${options##:}" | |
371 | # strip ":" | |
372 | options="${options%%:}" | |
3b403b32 | 373 | |
c98bcec8 HH |
374 | # Does it really start with '/'? |
375 | [ -n "${path%%/*}" ] && path="error"; | |
3b403b32 | 376 | |
c98bcec8 HH |
377 | #Fix kernel legacy style separating path and options with ',' |
378 | if [ "$path" != "${path#*,}" ] ; then | |
cc02093d HH |
379 | options=${path#*,} |
380 | path=${path%%,*} | |
c98bcec8 HH |
381 | fi |
382 | } | |
383 | ||
384 | ip_to_var() { | |
385 | local v=${1}: | |
386 | local i | |
3b403b32 | 387 | set -- |
c98bcec8 | 388 | while [ -n "$v" ]; do |
cc02093d HH |
389 | if [ "${v#\[*:*:*\]:}" != "$v" ]; then |
390 | # handle IPv6 address | |
391 | i="${v%%\]:*}" | |
392 | i="${i##\[}" | |
393 | set -- "$@" "$i" | |
394 | v=${v#\[$i\]:} | |
3b403b32 | 395 | else |
cc02093d HH |
396 | set -- "$@" "${v%%:*}" |
397 | v=${v#*:} | |
398 | fi | |
c98bcec8 HH |
399 | done |
400 | ||
401 | unset ip srv gw mask hostname dev autoconf | |
402 | case $# in | |
cc02093d HH |
403 | 0) autoconf="error" ;; |
404 | 1) autoconf=$1 ;; | |
405 | 2) dev=$1; autoconf=$2 ;; | |
406 | *) ip=$1; srv=$2; gw=$3; mask=$4; hostname=$5; dev=$6; autoconf=$7 ;; | |
c98bcec8 HH |
407 | esac |
408 | } | |
409 | ||
ccb0ab73 AŻ |
410 | # Create udev rule match for a device with its device name, or the udev property |
411 | # ID_FS_UUID or ID_FS_LABEL | |
412 | # | |
413 | # example: | |
414 | # udevmatch LABEL=boot | |
415 | # prints: | |
416 | # ENV{ID_FS_LABEL}="boot" | |
417 | # | |
418 | # TOOD: symlinks | |
419 | udevmatch() { | |
420 | case "$1" in | |
421 | UUID=????????-????-????-????-????????????|LABEL=*) | |
422 | printf 'ENV{ID_FS_%s}=="%s"' "${1%%=*}" "${1#*=}" | |
423 | ;; | |
424 | UUID=*) | |
425 | printf 'ENV{ID_FS_UUID}=="%s*"' "${1#*=}" | |
426 | ;; | |
427 | /dev/?*) printf 'KERNEL=="%s"' "${1#/dev/}" ;; | |
428 | *) return 255 ;; | |
429 | esac | |
430 | } | |
431 | ||
432 | # Prints unique path for potential file inside specified directory. It consists | |
433 | # of specified directory, prefix and number at the end which is incremented | |
434 | # until non-existing file is found. | |
435 | # | |
436 | # funiq dir prefix | |
437 | # | |
438 | # example: | |
439 | # # ls /mnt | |
440 | # cdrom0 cdrom1 | |
441 | # | |
442 | # # funiq /mnt cdrom | |
443 | # /mnt/cdrom2 | |
444 | funiq() { | |
445 | local dir="$1"; local prefix="$2" | |
446 | local i=0 | |
447 | ||
448 | [ -d "${dir}" ] || return 1 | |
449 | ||
450 | while [ -e "${dir}/${prefix}$i" ]; do | |
451 | i=$(($i+1)) || return 1 | |
452 | done | |
453 | ||
454 | echo "${dir}/${prefix}$i" | |
455 | } | |
456 | ||
457 | # Creates unique directory and prints its path. It's using funiq to generate | |
458 | # path. | |
459 | # | |
460 | # mkuniqdir subdir new_dir_name | |
461 | mkuniqdir() { | |
462 | local dir="$1"; local prefix="$2" | |
463 | local retdir; local retdir_new | |
464 | ||
d125a470 | 465 | [ -d "${dir}" ] || mkdir -m 0755 -p "${dir}" || return 1 |
ccb0ab73 AŻ |
466 | |
467 | retdir=$(funiq "${dir}" "${prefix}") || return 1 | |
d125a470 | 468 | until mkdir -m 0755 "${retdir}" 2>/dev/null; do |
ccb0ab73 AŻ |
469 | retdir_new=$(funiq "${dir}" "${prefix}") || return 1 |
470 | [ "$retdir_new" = "$retdir" ] && return 1 | |
471 | retdir="$retdir_new" | |
472 | done | |
473 | ||
474 | echo "${retdir}" | |
475 | } | |
476 | ||
477 | # Evaluates command for UUIDs either given as arguments for this function or all | |
2926b5b3 | 478 | # listed in /dev/disk/by-uuid. UUIDs doesn't have to be fully specified. If |
ccb0ab73 AŻ |
479 | # beginning is given it is expanded to all matching UUIDs. To pass full UUID to |
480 | # your command use '$___' as a place holder. Remember to escape '$'! | |
481 | # | |
482 | # foreach_uuid_until [ -p prefix ] command UUIDs | |
2926b5b3 | 483 | # |
ccb0ab73 AŻ |
484 | # prefix - string to put just before $___ |
485 | # command - command to be evaluated | |
486 | # UUIDs - list of UUIDs separated by space | |
2926b5b3 AŻ |
487 | # |
488 | # The function returns after *first successful evaluation* of the given command | |
489 | # with status 0. If evaluation fails for every UUID function returns with | |
490 | # status 1. | |
491 | # | |
492 | # Example: | |
ccb0ab73 | 493 | # foreach_uuid_until "mount -U \$___ /mnt; echo OK; umount /mnt" \ |
2926b5b3 AŻ |
494 | # "01234 f512 a235567f-12a3-c123-a1b1-01234567abcb" |
495 | foreach_uuid_until() ( | |
496 | cd /dev/disk/by-uuid | |
497 | ||
ccb0ab73 | 498 | [ "$1" = -p ] && local prefix="$2" && shift 2 |
2926b5b3 | 499 | local cmd="$1"; shift; local uuids_list="$*" |
ccb0ab73 | 500 | local uuid; local full_uuid; local ___ |
2926b5b3 AŻ |
501 | |
502 | [ -n "${cmd}" ] || return 1 | |
503 | ||
504 | for uuid in ${uuids_list:-*}; do | |
505 | for full_uuid in ${uuid}*; do | |
506 | [ -e "${full_uuid}" ] || continue | |
ccb0ab73 | 507 | ___="${prefix}${full_uuid}" |
2926b5b3 AŻ |
508 | eval ${cmd} && return 0 |
509 | done | |
510 | done | |
511 | ||
512 | return 1 | |
513 | ) |