]>
Commit | Line | Data |
---|---|---|
8ce58f1f | 1 | #!/bin/sh |
c98bcec8 | 2 | |
62cb52f4 HH |
3 | export DRACUT_SYSTEMD |
4 | export NEWROOT | |
56903458 HH |
5 | if [ -n "$NEWROOT" ]; then |
6 | [ -d $NEWROOT ] || mkdir -p -m 0755 $NEWROOT | |
7 | fi | |
8 | ||
99d4fd6b HH |
9 | if ! [ -d /run/initramfs ]; then |
10 | mkdir -p -m 0755 /run/initramfs/log | |
11 | ln -sfn /run/initramfs/log /var/log | |
12 | fi | |
13 | ||
56903458 HH |
14 | [ -d /run/lock ] || mkdir -p -m 0755 /run/lock |
15 | [ -d /run/log ] || mkdir -p -m 0755 /run/log | |
62cb52f4 | 16 | |
c32908ce HH |
17 | debug_off() { |
18 | set +x | |
19 | } | |
20 | ||
21 | debug_on() { | |
22 | [ "$RD_DEBUG" = "yes" ] && set -x | |
23 | } | |
24 | ||
2c19a5fa | 25 | # returns OK if $1 contains literal string $2 (and isn't empty) |
c98bcec8 | 26 | strstr() { |
2c19a5fa | 27 | [ "${1##*"$2"*}" != "$1" ] |
c98bcec8 HH |
28 | } |
29 | ||
2c19a5fa CF |
30 | # returns OK if $1 matches (completely) glob pattern $2 |
31 | # An empty $1 will not be considered matched, even if $2 is * which technically | |
32 | # matches; as it would match anything, it's not an interesting case. | |
33 | strglob() { | |
34 | [ -n "$1" -a -z "${1##$2}" ] | |
35 | } | |
36 | ||
37 | # returns OK if $1 contains (anywhere) a match of glob pattern $2 | |
38 | # An empty $1 will not be considered matched, even if $2 is * which technically | |
39 | # matches; as it would match anything, it's not an interesting case. | |
40 | strglobin() { | |
41 | [ -n "$1" -a -z "${1##*$2*}" ] | |
42 | } | |
43 | ||
44 | # returns OK if $1 contains literal string $2 at the beginning, and isn't empty | |
ccb0ab73 | 45 | str_starts() { |
2c19a5fa | 46 | [ "${1#"$2"*}" != "$1" ] |
ccb0ab73 AŻ |
47 | } |
48 | ||
2c19a5fa | 49 | # returns OK if $1 contains literal string $2 at the end, and isn't empty |
d8f0e320 | 50 | str_ends() { |
2c19a5fa | 51 | [ "${1%*"$2"}" != "$1" ] |
d8f0e320 WW |
52 | } |
53 | ||
df478eee HH |
54 | if [ -z "$DRACUT_SYSTEMD" ]; then |
55 | ||
56 | warn() { | |
57 | check_quiet | |
58 | echo "<28>dracut Warning: $*" > /dev/kmsg | |
f41720c3 | 59 | echo "dracut Warning: $*" >&2 |
df478eee HH |
60 | } |
61 | ||
62 | info() { | |
63 | check_quiet | |
64 | echo "<30>dracut: $*" > /dev/kmsg | |
65 | [ "$DRACUT_QUIET" != "yes" ] && \ | |
f41720c3 | 66 | echo "dracut: $*" >&2 |
df478eee HH |
67 | } |
68 | ||
69 | else | |
70 | ||
71 | warn() { | |
f41720c3 | 72 | echo "Warning: $*" >&2 |
df478eee HH |
73 | } |
74 | ||
75 | info() { | |
f41720c3 | 76 | echo "$*" |
df478eee HH |
77 | } |
78 | ||
79 | fi | |
80 | ||
81 | vwarn() { | |
6d58fa27 | 82 | while read line || [ -n "$line" ]; do |
df478eee HH |
83 | warn $line; |
84 | done | |
85 | } | |
86 | ||
87 | vinfo() { | |
6d58fa27 | 88 | while read line || [ -n "$line" ]; do |
df478eee HH |
89 | info $line; |
90 | done | |
91 | } | |
92 | ||
ccb0ab73 AŻ |
93 | # replaces all occurrences of 'search' in 'str' with 'replacement' |
94 | # | |
95 | # str_replace str search replacement | |
96 | # | |
97 | # example: | |
98 | # str_replace ' one two three ' ' ' '_' | |
99 | str_replace() { | |
100 | local in="$1"; local s="$2"; local r="$3" | |
101 | local out='' | |
102 | ||
103 | while strstr "${in}" "$s"; do | |
2c19a5fa | 104 | chop="${in%%"$s"*}" |
cb288154 | 105 | out="${out}${chop}$r" |
2c19a5fa | 106 | in="${in#*"$s"}" |
ccb0ab73 AŻ |
107 | done |
108 | echo "${out}${in}" | |
109 | } | |
110 | ||
551c2dd7 HH |
111 | killall_proc_mountpoint() { |
112 | local _pid | |
113 | local _t | |
114 | for _pid in /proc/*; do | |
115 | _pid=${_pid##/proc/} | |
116 | case $_pid in | |
117 | *[!0-9]*) continue;; | |
118 | esac | |
b093aa2d HH |
119 | [ -e "/proc/$_pid/exe" ] || continue |
120 | [ -e "/proc/$_pid/root" ] || continue | |
3605b485 | 121 | strstr "$(ls -l -- "/proc/$_pid" "/proc/$_pid/fd" 2>/dev/null)" "$1" && kill -9 "$_pid" |
551c2dd7 HH |
122 | done |
123 | } | |
124 | ||
8d3d72a6 | 125 | getcmdline() { |
fa7ada31 | 126 | local _line |
c2801d09 | 127 | local _i |
8d3d72a6 HH |
128 | local CMDLINE_ETC_D |
129 | local CMDLINE_ETC | |
9f087854 | 130 | local CMDLINE_PROC |
fa7ada31 | 131 | unset _line |
b2fab575 WC |
132 | |
133 | if [ -e /etc/cmdline ]; then | |
6d58fa27 | 134 | while read -r _line || [ -n "$_line" ]; do |
b2fab575 WC |
135 | CMDLINE_ETC="$CMDLINE_ETC $_line"; |
136 | done </etc/cmdline; | |
137 | fi | |
138 | for _i in /etc/cmdline.d/*.conf; do | |
139 | [ -e "$_i" ] || continue | |
9f087854 | 140 | while read -r _line || [ -n "$_line" ]; do |
b2fab575 WC |
141 | CMDLINE_ETC_D="$CMDLINE_ETC_D $_line"; |
142 | done <"$_i"; | |
143 | done | |
144 | if [ -e /proc/cmdline ]; then | |
9f087854 HH |
145 | while read -r _line || [ -n "$_line" ]; do |
146 | CMDLINE_PROC="$CMDLINE_PROC $_line" | |
147 | done </proc/cmdline; | |
148 | CMDLINE="$CMDLINE_ETC_D $CMDLINE_ETC $CMDLINE_PROC" | |
c1a37d92 | 149 | fi |
8d3d72a6 | 150 | printf "%s" "$CMDLINE" |
fa7ada31 HH |
151 | } |
152 | ||
153 | _dogetarg() { | |
9e7f4955 | 154 | local _o _val _doecho |
fa7ada31 HH |
155 | unset _val |
156 | unset _o | |
9e7f4955 | 157 | unset _doecho |
8d3d72a6 | 158 | CMDLINE=$(getcmdline) |
fa7ada31 HH |
159 | |
160 | for _o in $CMDLINE; do | |
b1b67842 | 161 | if [ "${_o%%=*}" = "${1%%=*}" ]; then |
9e7f4955 HH |
162 | if [ -n "${1#*=}" -a "${1#*=*}" != "${1}" ]; then |
163 | # if $1 has a "=<value>", we want the exact match | |
164 | if [ "$_o" = "$1" ]; then | |
165 | _val="1"; | |
166 | unset _doecho | |
167 | fi | |
168 | continue | |
169 | fi | |
170 | ||
171 | if [ "${_o#*=}" = "$_o" ]; then | |
172 | # if cmdline argument has no "=<value>", we assume "=1" | |
173 | _val="1"; | |
174 | unset _doecho | |
175 | continue | |
176 | fi | |
177 | ||
b093aa2d | 178 | _val="${_o#*=}" |
9e7f4955 | 179 | _doecho=1 |
3a4d0c9c | 180 | fi |
df44688f | 181 | done |
fa7ada31 | 182 | if [ -n "$_val" ]; then |
d765a3e7 | 183 | [ "x$_doecho" != "x" ] && echo "$_val"; |
cc02093d | 184 | return 0; |
3a4d0c9c | 185 | fi |
fa7ada31 HH |
186 | return 1; |
187 | } | |
188 | ||
189 | getarg() { | |
c32908ce | 190 | debug_off |
68e7661c | 191 | local _deprecated _newoption |
fa7ada31 HH |
192 | while [ $# -gt 0 ]; do |
193 | case $1 in | |
68e7661c | 194 | -d) _deprecated=1; shift;; |
9e7f4955 | 195 | -y) if _dogetarg $2 >/dev/null; then |
68e7661c | 196 | if [ "$_deprecated" = "1" ]; then |
8ea8d6de | 197 | [ -n "$_newoption" ] && warn "Kernel command line option '$2' is deprecated, use '$_newoption' instead." || warn "Option '$2' is deprecated." |
68e7661c | 198 | fi |
fa7ada31 | 199 | echo 1 |
c32908ce | 200 | debug_on |
fa7ada31 HH |
201 | return 0 |
202 | fi | |
68e7661c | 203 | _deprecated=0 |
fa7ada31 | 204 | shift 2;; |
9e7f4955 | 205 | -n) if _dogetarg $2 >/dev/null; then |
fa7ada31 | 206 | echo 0; |
68e7661c | 207 | if [ "$_deprecated" = "1" ]; then |
8ea8d6de | 208 | [ -n "$_newoption" ] && warn "Kernel command line option '$2' is deprecated, use '$_newoption=0' instead." || warn "Option '$2' is deprecated." |
68e7661c | 209 | fi |
c32908ce | 210 | debug_on |
fa7ada31 HH |
211 | return 1 |
212 | fi | |
68e7661c | 213 | _deprecated=0 |
fa7ada31 | 214 | shift 2;; |
68e7661c | 215 | *) if [ -z "$_newoption" ]; then |
b093aa2d | 216 | _newoption="$1" |
68e7661c HH |
217 | fi |
218 | if _dogetarg $1; then | |
219 | if [ "$_deprecated" = "1" ]; then | |
8ea8d6de | 220 | [ -n "$_newoption" ] && warn "Kernel command line option '$1' is deprecated, use '$_newoption' instead." || warn "Option '$1' is deprecated." |
68e7661c | 221 | fi |
c32908ce | 222 | debug_on |
fa7ada31 HH |
223 | return 0; |
224 | fi | |
68e7661c | 225 | _deprecated=0 |
fa7ada31 HH |
226 | shift;; |
227 | esac | |
228 | done | |
c32908ce | 229 | debug_on |
df44688f DD |
230 | return 1 |
231 | } | |
ae5bc1fd | 232 | |
7e2285a4 WW |
233 | # getargbool <defaultval> <args...> |
234 | # False if "getarg <args...>" returns "0", "no", or "off". | |
235 | # True if getarg returns any other non-empty string. | |
236 | # If not found, assumes <defaultval> - usually 0 for false, 1 for true. | |
237 | # example: getargbool 0 rd.info | |
238 | # true: rd.info, rd.info=1, rd.info=xxx | |
239 | # false: rd.info=0, rd.info=off, rd.info not present (default val is 0) | |
fa7ada31 HH |
240 | getargbool() { |
241 | local _b | |
242 | unset _b | |
243 | local _default | |
b093aa2d | 244 | _default="$1"; shift |
fa7ada31 | 245 | _b=$(getarg "$@") |
b093aa2d | 246 | [ $? -ne 0 -a -z "$_b" ] && _b="$_default" |
fa7ada31 | 247 | if [ -n "$_b" ]; then |
4ad45344 | 248 | [ $_b = "0" ] && return 1 |
fa7ada31 | 249 | [ $_b = "no" ] && return 1 |
1cc57eda | 250 | [ $_b = "off" ] && return 1 |
c1a37d92 | 251 | fi |
fa7ada31 HH |
252 | return 0 |
253 | } | |
254 | ||
a08ea34a DY |
255 | isdigit() { |
256 | case "$1" in | |
257 | *[!0-9]*|"") return 1;; | |
258 | esac | |
259 | ||
260 | return 0 | |
261 | } | |
262 | ||
263 | # getargnum <defaultval> <minval> <maxval> <arg> | |
264 | # Will echo the arg if it's in range [minval - maxval]. | |
265 | # If it's not set or it's not valid, will set it <defaultval>. | |
266 | # Note all values are required to be >= 0 here. | |
267 | # <defaultval> should be with [minval -maxval]. | |
268 | getargnum() { | |
269 | local _b | |
270 | unset _b | |
271 | local _default _min _max | |
b093aa2d HH |
272 | _default="$1"; shift |
273 | _min="$1"; shift | |
274 | _max="$1"; shift | |
a08ea34a DY |
275 | _b=$(getarg "$1") |
276 | [ $? -ne 0 -a -z "$_b" ] && _b=$_default | |
277 | if [ -n "$_b" ]; then | |
278 | isdigit "$_b" && _b=$(($_b)) && \ | |
b093aa2d | 279 | [ $_b -ge $_min ] && [ $_b -le $_max ] && echo $_b && return |
a08ea34a DY |
280 | fi |
281 | echo $_default | |
282 | } | |
283 | ||
fa7ada31 | 284 | _dogetargs() { |
c32908ce | 285 | debug_off |
a9fa6d26 | 286 | local _o _found _key |
fa7ada31 HH |
287 | unset _o |
288 | unset _found | |
8d3d72a6 | 289 | CMDLINE=$(getcmdline) |
b093aa2d | 290 | _key="$1" |
a9fa6d26 | 291 | set -- |
fa7ada31 | 292 | for _o in $CMDLINE; do |
a9fa6d26 HH |
293 | if [ "$_o" = "$_key" ]; then |
294 | _found=1; | |
295 | elif [ "${_o%%=*}" = "${_key%=}" ]; then | |
296 | [ -n "${_o%%=*}" ] && set -- "$@" "${_o#*=}"; | |
fa7ada31 | 297 | _found=1; |
cc02093d | 298 | fi |
da1c03c8 | 299 | done |
a9fa6d26 | 300 | if [ -n "$_found" ]; then |
5899f2f5 | 301 | [ $# -gt 0 ] && printf '%s' "$*" |
a9fa6d26 HH |
302 | return 0 |
303 | fi | |
fa7ada31 HH |
304 | return 1; |
305 | } | |
306 | ||
307 | getargs() { | |
c32908ce | 308 | debug_off |
68e7661c | 309 | local _val _i _args _gfound _deprecated |
a9fa6d26 HH |
310 | unset _val |
311 | unset _gfound | |
68e7661c | 312 | _newoption="$1" |
a9fa6d26 HH |
313 | _args="$@" |
314 | set -- | |
315 | for _i in $_args; do | |
e51e7978 | 316 | if [ "$_i" = "-d" ]; then |
68e7661c HH |
317 | _deprecated=1 |
318 | continue | |
319 | fi | |
a9fa6d26 | 320 | _val="$(_dogetargs $_i)" |
68e7661c HH |
321 | if [ $? -eq 0 ]; then |
322 | if [ "$_deprecated" = "1" ]; then | |
323 | [ -n "$_newoption" ] && warn "Option '$_i' is deprecated, use '$_newoption' instead." || warn "Option $_i is deprecated!" | |
324 | fi | |
325 | _gfound=1 | |
326 | fi | |
a9fa6d26 | 327 | [ -n "$_val" ] && set -- "$@" "$_val" |
68e7661c | 328 | _deprecated=0 |
fa7ada31 | 329 | done |
a9fa6d26 HH |
330 | if [ -n "$_gfound" ]; then |
331 | if [ $# -gt 0 ]; then | |
5899f2f5 | 332 | printf '%s' "$*" |
a9fa6d26 | 333 | fi |
c32908ce | 334 | debug_on |
fa7ada31 | 335 | return 0 |
3a4d0c9c | 336 | fi |
c32908ce | 337 | debug_on |
4bb570c9 | 338 | return 1; |
da1c03c8 HH |
339 | } |
340 | ||
fa7ada31 | 341 | |
2926b5b3 AŻ |
342 | # Prints value of given option. If option is a flag and it's present, |
343 | # it just returns 0. Otherwise 1 is returned. | |
344 | # $1 = options separated by commas | |
345 | # $2 = option we are interested in | |
3b403b32 | 346 | # |
2926b5b3 AŻ |
347 | # Example: |
348 | # $1 = cipher=aes-cbc-essiv:sha256,hash=sha256,verify | |
349 | # $2 = hash | |
350 | # Output: | |
351 | # sha256 | |
352 | getoptcomma() { | |
353 | local line=",$1,"; local opt="$2"; local tmp | |
354 | ||
355 | case "${line}" in | |
356 | *,${opt}=*,*) | |
357 | tmp="${line#*,${opt}=}" | |
358 | echo "${tmp%%,*}" | |
359 | return 0 | |
cc02093d HH |
360 | ;; |
361 | *,${opt},*) return 0;; | |
2926b5b3 | 362 | esac |
2926b5b3 AŻ |
363 | return 1 |
364 | } | |
365 | ||
ccb0ab73 AŻ |
366 | # Splits given string 'str' with separator 'sep' into variables 'var1', 'var2', |
367 | # 'varN'. If number of fields is less than number of variables, remaining are | |
368 | # not set. If number of fields is greater than number of variables, the last | |
369 | # variable takes remaining fields. In short - it acts similary to 'read'. | |
370 | # | |
371 | # splitsep sep str var1 var2 varN | |
372 | # | |
373 | # example: | |
374 | # splitsep ':' 'foo:bar:baz' v1 v2 | |
375 | # in result: | |
376 | # v1='foo', v2='bar:baz' | |
377 | # | |
378 | # TODO: ':' inside fields. | |
379 | splitsep() { | |
c32908ce | 380 | debug_off |
ccb0ab73 AŻ |
381 | local sep="$1"; local str="$2"; shift 2 |
382 | local tmp | |
383 | ||
f7cadaa8 | 384 | while [ -n "$str" -a "$#" -gt 1 ]; do |
7a8a33b6 | 385 | tmp="${str%%$sep*}" |
32b2fb8a WW |
386 | eval "$1='${tmp}'" |
387 | str="${str#"$tmp"}" | |
7a8a33b6 | 388 | str="${str#$sep}" |
ccb0ab73 AŻ |
389 | shift |
390 | done | |
32b2fb8a | 391 | [ -n "$str" -a -n "$1" ] && eval "$1='$str'" |
c32908ce | 392 | debug_on |
ccb0ab73 AŻ |
393 | return 0 |
394 | } | |
395 | ||
4bb570c9 | 396 | setdebug() { |
ca4108b7 | 397 | [ -f /usr/lib/initrd-release ] || return |
9e7a3bf2 | 398 | if [ -z "$RD_DEBUG" ]; then |
4bb570c9 | 399 | if [ -e /proc/cmdline ]; then |
9e7a3bf2 | 400 | RD_DEBUG=no |
68e7661c | 401 | if getargbool 0 rd.debug -d -y rdinitdebug -d -y rdnetdebug; then |
3b403b32 | 402 | RD_DEBUG=yes |
0d837ebf HH |
403 | [ -n "$BASH" ] && \ |
404 | export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): '; | |
405 | fi | |
4bb570c9 | 406 | fi |
9e7a3bf2 | 407 | export RD_DEBUG |
4bb570c9 | 408 | fi |
c32908ce | 409 | debug_on |
4bb570c9 HH |
410 | } |
411 | ||
c98bcec8 | 412 | setdebug |
4bb570c9 | 413 | |
ae5bc1fd DD |
414 | source_all() { |
415 | local f | |
f8d50f60 HH |
416 | local _dir |
417 | _dir=$1; shift | |
418 | [ "$_dir" ] && [ -d "/$_dir" ] || return | |
419 | for f in "/$_dir"/*.sh; do [ -e "$f" ] && . "$f" "$@"; done | |
ae5bc1fd | 420 | } |
51031303 | 421 | |
0b53ca70 HH |
422 | hookdir=/lib/dracut/hooks |
423 | export hookdir | |
424 | ||
425 | source_hook() { | |
f8d50f60 HH |
426 | local _dir |
427 | _dir=$1; shift | |
428 | source_all "/lib/dracut/hooks/$_dir" "$@" | |
0b53ca70 HH |
429 | } |
430 | ||
8238850c HH |
431 | check_finished() { |
432 | local f | |
b093aa2d | 433 | for f in $hookdir/initqueue/finished/*.sh; do |
b0692d03 HH |
434 | [ "$f" = "$hookdir/initqueue/finished/*.sh" ] && return 0 |
435 | { [ -e "$f" ] && ( . "$f" ) ; } || return 1 | |
436 | done | |
8238850c HH |
437 | return 0 |
438 | } | |
439 | ||
0375106c HH |
440 | source_conf() { |
441 | local f | |
442 | [ "$1" ] && [ -d "/$1" ] || return | |
54a73cbb | 443 | for f in "/$1"/*.conf; do [ -e "$f" ] && . "$f"; done |
0375106c HH |
444 | } |
445 | ||
311a2769 | 446 | die() { |
449adc61 | 447 | { |
84a12fbc | 448 | echo "<24>dracut: FATAL: $*"; |
79471f36 | 449 | echo "<24>dracut: Refusing to continue"; |
449adc61 HH |
450 | } > /dev/kmsg |
451 | ||
3b403b32 | 452 | { |
84a12fbc | 453 | echo "warn dracut: FATAL: \"$*\""; |
535ad9d1 | 454 | echo "warn dracut: Refusing to continue"; |
0b53ca70 | 455 | } >> $hookdir/emergency/01-die.sh |
b093aa2d | 456 | [ -d /run/initramfs ] || mkdir -p -- /run/initramfs |
e2ecc2d8 | 457 | |
03f405bc | 458 | > /run/initramfs/.die |
e2ecc2d8 | 459 | |
4e882b80 HH |
460 | if getargbool 0 "rd.shell"; then |
461 | emergency_shell | |
462 | else | |
463 | source_hook "shutdown-emergency" | |
464 | fi | |
e2ecc2d8 HH |
465 | |
466 | if [ -n "$DRACUT_SYSTEMD" ]; then | |
467 | systemctl --no-block --force halt | |
468 | fi | |
469 | ||
311a2769 PS |
470 | exit 1 |
471 | } | |
472 | ||
695de849 HH |
473 | check_quiet() { |
474 | if [ -z "$DRACUT_QUIET" ]; then | |
cc02093d | 475 | DRACUT_QUIET="yes" |
68e7661c HH |
476 | getargbool 0 rd.info -d -y rdinfo && DRACUT_QUIET="no" |
477 | getargbool 0 rd.debug -d -y rdinitdebug && DRACUT_QUIET="no" | |
cc02093d | 478 | getarg quiet || DRACUT_QUIET="yes" |
cad10a7f HH |
479 | a=$(getarg loglevel=) |
480 | [ -n "$a" ] && [ $a -ge 28 ] && DRACUT_QUIET="yes" | |
481 | export DRACUT_QUIET | |
695de849 HH |
482 | fi |
483 | } | |
484 | ||
9f10836d | 485 | |
51031303 DD |
486 | check_occurances() { |
487 | # Count the number of times the character $ch occurs in $str | |
488 | # Return 0 if the count matches the expected number, 1 otherwise | |
489 | local str="$1" | |
490 | local ch="$2" | |
491 | local expected="$3" | |
492 | local count=0 | |
493 | ||
494 | while [ "${str#*$ch}" != "${str}" ]; do | |
cc02093d HH |
495 | str="${str#*$ch}" |
496 | count=$(( $count + 1 )) | |
51031303 DD |
497 | done |
498 | ||
499 | [ $count -eq $expected ] | |
500 | } | |
07b2fbb1 PS |
501 | |
502 | incol2() { | |
c32908ce | 503 | debug_off |
07b2fbb1 PS |
504 | local dummy check; |
505 | local file="$1"; | |
506 | local str="$2"; | |
507 | ||
a2cb4dbc HH |
508 | [ -z "$file" ] && return 1; |
509 | [ -z "$str" ] && return 1; | |
07b2fbb1 | 510 | |
6d58fa27 | 511 | while read dummy check restofline || [ -n "$check" ]; do |
c32908ce HH |
512 | if [ "$check" = "$str" ]; then |
513 | debug_on | |
514 | return 0 | |
515 | fi | |
07b2fbb1 | 516 | done < $file |
c32908ce | 517 | debug_on |
07b2fbb1 PS |
518 | return 1 |
519 | } | |
5c6a593f HH |
520 | |
521 | udevsettle() { | |
fe98cfee | 522 | [ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version) |
8ef0be56 | 523 | |
5c6a593f | 524 | if [ $UDEVVERSION -ge 143 ]; then |
0b53ca70 | 525 | udevadm settle --exit-if-exists=$hookdir/initqueue/work $settle_exit_if_exists |
5c6a593f HH |
526 | else |
527 | udevadm settle --timeout=30 | |
528 | fi | |
529 | } | |
273b197d | 530 | |
1dd5bc3f | 531 | udevproperty() { |
fe98cfee | 532 | [ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version) |
1dd5bc3f HH |
533 | |
534 | if [ $UDEVVERSION -ge 143 ]; then | |
cc02093d | 535 | for i in "$@"; do udevadm control --property=$i; done |
1dd5bc3f | 536 | else |
cc02093d | 537 | for i in "$@"; do udevadm control --env=$i; done |
1dd5bc3f HH |
538 | fi |
539 | } | |
540 | ||
42116050 HH |
541 | find_mount() { |
542 | local dev mnt etc wanted_dev | |
543 | wanted_dev="$(readlink -e -q $1)" | |
6d58fa27 | 544 | while read dev mnt etc || [ -n "$dev" ]; do |
42116050 HH |
545 | [ "$dev" = "$wanted_dev" ] && echo "$dev" && return 0 |
546 | done < /proc/mounts | |
547 | return 1 | |
548 | } | |
549 | ||
27790828 HH |
550 | # usage: ismounted <mountpoint> |
551 | # usage: ismounted /dev/<device> | |
42116050 HH |
552 | if command -v findmnt >/dev/null; then |
553 | ismounted() { | |
554 | findmnt "$1" > /dev/null 2>&1 | |
555 | } | |
556 | else | |
557 | ismounted() { | |
558 | if [ -b "$1" ]; then | |
559 | find_mount "$1" > /dev/null && return 0 | |
560 | return 1 | |
561 | fi | |
562 | ||
6d58fa27 | 563 | while read a m a || [ -n "$m" ]; do |
42116050 HH |
564 | [ "$m" = "$1" ] && return 0 |
565 | done < /proc/mounts | |
566 | return 1 | |
567 | } | |
568 | fi | |
a5f01bbf | 569 | |
3b403b32 | 570 | # root=nfs:[<server-ip>:]<root-dir>[:<nfs-options>] |
c98bcec8 HH |
571 | # root=nfs4:[<server-ip>:]<root-dir>[:<nfs-options>] |
572 | nfsroot_to_var() { | |
573 | # strip nfs[4]: | |
574 | local arg="$@:" | |
575 | nfs="${arg%%:*}" | |
576 | arg="${arg##$nfs:}" | |
c98bcec8 HH |
577 | |
578 | # check if we have a server | |
2c19a5fa | 579 | if strstr "$arg" ':/' ; then |
cc02093d HH |
580 | server="${arg%%:/*}" |
581 | arg="/${arg##*:/}" | |
c98bcec8 HH |
582 | fi |
583 | ||
584 | path="${arg%%:*}" | |
585 | ||
586 | # rest are options | |
587 | options="${arg##$path}" | |
588 | # strip leading ":" | |
589 | options="${options##:}" | |
590 | # strip ":" | |
591 | options="${options%%:}" | |
3b403b32 | 592 | |
c98bcec8 HH |
593 | # Does it really start with '/'? |
594 | [ -n "${path%%/*}" ] && path="error"; | |
3b403b32 | 595 | |
c98bcec8 HH |
596 | #Fix kernel legacy style separating path and options with ',' |
597 | if [ "$path" != "${path#*,}" ] ; then | |
cc02093d HH |
598 | options=${path#*,} |
599 | path=${path%%,*} | |
c98bcec8 HH |
600 | fi |
601 | } | |
602 | ||
ccb0ab73 AŻ |
603 | # Create udev rule match for a device with its device name, or the udev property |
604 | # ID_FS_UUID or ID_FS_LABEL | |
605 | # | |
606 | # example: | |
607 | # udevmatch LABEL=boot | |
608 | # prints: | |
609 | # ENV{ID_FS_LABEL}="boot" | |
610 | # | |
611 | # TOOD: symlinks | |
612 | udevmatch() { | |
613 | case "$1" in | |
1e057b35 | 614 | UUID=????????-????-????-????-????????????|LABEL=*|PARTLABEL=*|PARTUUID=????????-????-????-????-????????????) |
ccb0ab73 AŻ |
615 | printf 'ENV{ID_FS_%s}=="%s"' "${1%%=*}" "${1#*=}" |
616 | ;; | |
617 | UUID=*) | |
618 | printf 'ENV{ID_FS_UUID}=="%s*"' "${1#*=}" | |
619 | ;; | |
1e057b35 HH |
620 | PARTUUID=*) |
621 | printf 'ENV{ID_FS_PARTUUID}=="%s*"' "${1#*=}" | |
622 | ;; | |
b093aa2d | 623 | /dev/?*) printf -- 'KERNEL=="%s"' "${1#/dev/}" ;; |
ccb0ab73 AŻ |
624 | *) return 255 ;; |
625 | esac | |
626 | } | |
627 | ||
628 | # Prints unique path for potential file inside specified directory. It consists | |
629 | # of specified directory, prefix and number at the end which is incremented | |
630 | # until non-existing file is found. | |
631 | # | |
632 | # funiq dir prefix | |
633 | # | |
634 | # example: | |
635 | # # ls /mnt | |
636 | # cdrom0 cdrom1 | |
637 | # | |
638 | # # funiq /mnt cdrom | |
639 | # /mnt/cdrom2 | |
640 | funiq() { | |
641 | local dir="$1"; local prefix="$2" | |
642 | local i=0 | |
643 | ||
644 | [ -d "${dir}" ] || return 1 | |
645 | ||
646 | while [ -e "${dir}/${prefix}$i" ]; do | |
647 | i=$(($i+1)) || return 1 | |
648 | done | |
649 | ||
650 | echo "${dir}/${prefix}$i" | |
651 | } | |
652 | ||
653 | # Creates unique directory and prints its path. It's using funiq to generate | |
654 | # path. | |
655 | # | |
656 | # mkuniqdir subdir new_dir_name | |
657 | mkuniqdir() { | |
658 | local dir="$1"; local prefix="$2" | |
659 | local retdir; local retdir_new | |
660 | ||
d125a470 | 661 | [ -d "${dir}" ] || mkdir -m 0755 -p "${dir}" || return 1 |
ccb0ab73 AŻ |
662 | |
663 | retdir=$(funiq "${dir}" "${prefix}") || return 1 | |
d125a470 | 664 | until mkdir -m 0755 "${retdir}" 2>/dev/null; do |
ccb0ab73 AŻ |
665 | retdir_new=$(funiq "${dir}" "${prefix}") || return 1 |
666 | [ "$retdir_new" = "$retdir" ] && return 1 | |
667 | retdir="$retdir_new" | |
668 | done | |
669 | ||
670 | echo "${retdir}" | |
671 | } | |
672 | ||
31cfc9aa WW |
673 | # Copy the contents of SRC into DEST, merging the contents of existing |
674 | # directories (kinda like rsync, or cpio -p). | |
675 | # Creates DEST if it doesn't exist. Overwrites files with the same names. | |
676 | # | |
677 | # copytree SRC DEST | |
678 | copytree() { | |
679 | local src="$1" dest="$2" | |
680 | mkdir -p "$dest"; dest=$(readlink -e -q "$dest") | |
681 | ( cd "$src"; cp -af . -t "$dest" ) | |
682 | } | |
683 | ||
ccb0ab73 | 684 | # Evaluates command for UUIDs either given as arguments for this function or all |
2926b5b3 | 685 | # listed in /dev/disk/by-uuid. UUIDs doesn't have to be fully specified. If |
ccb0ab73 AŻ |
686 | # beginning is given it is expanded to all matching UUIDs. To pass full UUID to |
687 | # your command use '$___' as a place holder. Remember to escape '$'! | |
688 | # | |
689 | # foreach_uuid_until [ -p prefix ] command UUIDs | |
2926b5b3 | 690 | # |
ccb0ab73 AŻ |
691 | # prefix - string to put just before $___ |
692 | # command - command to be evaluated | |
693 | # UUIDs - list of UUIDs separated by space | |
2926b5b3 AŻ |
694 | # |
695 | # The function returns after *first successful evaluation* of the given command | |
696 | # with status 0. If evaluation fails for every UUID function returns with | |
697 | # status 1. | |
698 | # | |
699 | # Example: | |
ccb0ab73 | 700 | # foreach_uuid_until "mount -U \$___ /mnt; echo OK; umount /mnt" \ |
2926b5b3 AŻ |
701 | # "01234 f512 a235567f-12a3-c123-a1b1-01234567abcb" |
702 | foreach_uuid_until() ( | |
703 | cd /dev/disk/by-uuid | |
704 | ||
ccb0ab73 | 705 | [ "$1" = -p ] && local prefix="$2" && shift 2 |
2926b5b3 | 706 | local cmd="$1"; shift; local uuids_list="$*" |
ccb0ab73 | 707 | local uuid; local full_uuid; local ___ |
2926b5b3 AŻ |
708 | |
709 | [ -n "${cmd}" ] || return 1 | |
710 | ||
711 | for uuid in ${uuids_list:-*}; do | |
712 | for full_uuid in ${uuid}*; do | |
713 | [ -e "${full_uuid}" ] || continue | |
ccb0ab73 | 714 | ___="${prefix}${full_uuid}" |
2926b5b3 AŻ |
715 | eval ${cmd} && return 0 |
716 | done | |
717 | done | |
718 | ||
719 | return 1 | |
720 | ) | |
f8342dd5 | 721 | |
1939a4f9 HH |
722 | # Get kernel name for given device. Device may be the name too (then the same |
723 | # is returned), a symlink (full path), UUID (prefixed with "UUID=") or label | |
724 | # (prefixed with "LABEL="). If just a beginning of the UUID is specified or | |
725 | # even an empty, function prints all device names which UUIDs match - every in | |
726 | # single line. | |
727 | # | |
728 | # NOTICE: The name starts with "/dev/". | |
729 | # | |
730 | # Example: | |
731 | # devnames UUID=123 | |
732 | # May print: | |
733 | # /dev/dm-1 | |
734 | # /dev/sdb1 | |
735 | # /dev/sdf3 | |
736 | devnames() { | |
737 | local dev="$1"; local d; local names | |
738 | ||
739 | case "$dev" in | |
740 | UUID=*) | |
741 | dev="$(foreach_uuid_until '! blkid -U $___' "${dev#UUID=}")" \ | |
742 | && return 255 | |
743 | [ -z "$dev" ] && return 255 | |
744 | ;; | |
745 | LABEL=*) dev="$(blkid -L "${dev#LABEL=}")" || return 255 ;; | |
746 | /dev/?*) ;; | |
747 | *) return 255 ;; | |
748 | esac | |
749 | ||
750 | for d in $dev; do | |
751 | names="$names | |
752 | $(readlink -e -q "$d")" || return 255 | |
753 | done | |
754 | ||
755 | echo "${names# | |
756 | }" | |
757 | } | |
758 | ||
759 | ||
f8342dd5 | 760 | usable_root() { |
7e59d550 HH |
761 | local _i |
762 | ||
763 | [ -d "$1" ] || return 1 | |
764 | ||
765 | for _i in "$1"/usr/lib*/ld-*.so "$1"/lib*/ld-*.so; do | |
766 | [ -e "$_i" ] && return 0 | |
f8342dd5 | 767 | done |
7e59d550 HH |
768 | |
769 | for _i in proc sys dev; do | |
770 | [ -e "$1"/$_i ] || return 1 | |
771 | done | |
772 | ||
f8342dd5 MS |
773 | return 0 |
774 | } | |
b0692d03 | 775 | |
bb61d657 HH |
776 | inst_hook() { |
777 | local _hookname _unique _name _job _exe | |
778 | while [ $# -gt 0 ]; do | |
779 | case "$1" in | |
780 | --hook) | |
781 | _hookname="/$2";shift;; | |
782 | --unique) | |
783 | _unique="yes";; | |
784 | --name) | |
785 | _name="$2";shift;; | |
786 | *) | |
787 | break;; | |
788 | esac | |
789 | shift | |
790 | done | |
791 | ||
792 | if [ -z "$_unique" ]; then | |
793 | _job="${_name}$$" | |
794 | else | |
795 | _job="${_name:-$1}" | |
796 | _job=${_job##*/} | |
797 | fi | |
798 | ||
799 | _exe=$1 | |
800 | shift | |
801 | ||
802 | [ -x "$_exe" ] || _exe=$(command -v $_exe) | |
803 | ||
804 | if [ -n "$onetime" ]; then | |
805 | { | |
32bd2fbb | 806 | echo '[ -e "$_job" ] && rm -f -- "$_job"' |
bb61d657 HH |
807 | echo "$_exe $@" |
808 | } > "/tmp/$$-${_job}.sh" | |
809 | else | |
810 | echo "$_exe $@" > "/tmp/$$-${_job}.sh" | |
811 | fi | |
812 | ||
813 | mv -f "/tmp/$$-${_job}.sh" "$hookdir/${_hookname}/${_job}.sh" | |
814 | } | |
815 | ||
816 | # inst_mount_hook <mountpoint> <prio> <name> <script> | |
817 | # | |
818 | # Install a mount hook with priority <prio>, | |
819 | # which executes <script> as soon as <mountpoint> is mounted. | |
820 | inst_mount_hook() { | |
821 | local _prio="$2" _jobname="$3" _script="$4" | |
822 | local _hookname="mount-$(str_replace "$1" '/' '\\x2f')" | |
823 | [ -d "$hookdir/${_hookname}" ] || mkdir -p "$hookdir/${_hookname}" | |
824 | inst_hook --hook "$_hookname" --unique --name "${_prio}-${_jobname}" "$_script" | |
825 | } | |
826 | ||
827 | # add_mount_point <dev> <mountpoint> <filesystem> <fsopts> | |
828 | # | |
829 | # Mount <dev> on <mountpoint> with <filesystem> and <fsopts> | |
830 | # and call any mount hooks, as soon, as it is mounted | |
831 | add_mount_point() { | |
832 | local _dev="$1" _mp="$2" _fs="$3" _fsopts="$4" | |
833 | local _hookname="mount-$(str_replace "$2" '/' '\\x2f')" | |
834 | local _devname="dev-$(str_replace "$1" '/' '\\x2f')" | |
835 | echo "$_dev $_mp $_fs $_fsopts 0 0" >> /etc/fstab | |
836 | ||
837 | exec 7>/etc/udev/rules.d/99-mount-${_devname}.rules | |
838 | echo 'SUBSYSTEM!="block", GOTO="mount_end"' >&7 | |
839 | echo 'ACTION!="add|change", GOTO="mount_end"' >&7 | |
840 | if [ -n "$_dev" ]; then | |
841 | udevmatch "$_dev" >&7 || { | |
842 | warn "add_mount_point dev=$_dev incorrect!" | |
843 | continue | |
844 | } | |
845 | printf ', ' >&7 | |
846 | fi | |
847 | ||
848 | { | |
849 | printf -- 'RUN+="%s --unique --onetime ' $(command -v initqueue) | |
850 | printf -- '--name mount-%%k ' | |
851 | printf -- '%s %s"\n' "$(command -v mount_hook)" "${_mp}" | |
852 | } >&7 | |
853 | echo 'LABEL="mount_end"' >&7 | |
854 | exec 7>&- | |
855 | } | |
856 | ||
857 | # wait_for_mount <mountpoint> | |
858 | # | |
859 | # Installs a initqueue-finished script, | |
860 | # which will cause the main loop only to exit, | |
861 | # if <mountpoint> is mounted. | |
b0692d03 HH |
862 | wait_for_mount() |
863 | { | |
864 | local _name | |
865 | _name="$(str_replace "$1" '/' '\\x2f')" | |
866 | printf '. /lib/dracut-lib.sh\nismounted "%s"\n' $1 \ | |
867 | >> "$hookdir/initqueue/finished/ismounted-${_name}.sh" | |
868 | { | |
869 | printf 'ismounted "%s" || ' $1 | |
870 | printf 'warn "\"%s\" is not mounted"\n' $1 | |
871 | } >> "$hookdir/emergency/90-${_name}.sh" | |
872 | } | |
873 | ||
e3eec4b8 TB |
874 | # get a systemd-compatible unit name from a path |
875 | # (mimicks unit_name_from_path_instance()) | |
c4b572b5 HH |
876 | dev_unit_name() |
877 | { | |
e3eec4b8 TB |
878 | local dev="$1" |
879 | ||
85752f0f | 880 | if command -v systemd-escape >/dev/null; then |
c41df7e1 | 881 | systemd-escape -p -- "$dev" |
85752f0f HH |
882 | return |
883 | fi | |
884 | ||
e3eec4b8 TB |
885 | if [ "$dev" = "/" -o -z "$dev" ]; then |
886 | printf -- "-" | |
887 | exit 0 | |
888 | fi | |
889 | ||
890 | dev="${1%%/}" | |
891 | dev="${dev##/}" | |
892 | dev="$(str_replace "$dev" '\' '\x5c')" | |
893 | dev="$(str_replace "$dev" '-' '\x2d')" | |
13efce5d AT |
894 | if [ "${dev##.}" != "$dev" ]; then |
895 | dev="\x2e${dev##.}" | |
896 | fi | |
e3eec4b8 TB |
897 | dev="$(str_replace "$dev" '/' '-')" |
898 | ||
899 | printf -- "%s" "$dev" | |
c4b572b5 HH |
900 | } |
901 | ||
4d9d767d N |
902 | # set_systemd_timeout_for_dev <dev> |
903 | # Set 'rd.timeout' as the systemd timeout for <dev> | |
904 | ||
905 | set_systemd_timeout_for_dev() | |
b0692d03 HH |
906 | { |
907 | local _name | |
ac5bff2b HH |
908 | local _needreload |
909 | local _noreload | |
56663e7e | 910 | local _timeout |
ac5bff2b HH |
911 | |
912 | if [ "$1" = "-n" ]; then | |
913 | _noreload=1 | |
914 | shift | |
915 | fi | |
916 | ||
56663e7e HR |
917 | _timeout=$(getarg rd.timeout) |
918 | _timeout=${_timeout:-0} | |
919 | ||
44d26d92 | 920 | if [ -n "$DRACUT_SYSTEMD" ]; then |
c4b572b5 | 921 | _name=$(dev_unit_name "$1") |
b92896ec HH |
922 | if ! [ -L ${PREFIX}/etc/systemd/system/initrd.target.wants/${_name}.device ]; then |
923 | [ -d ${PREFIX}/etc/systemd/system/initrd.target.wants ] || mkdir -p ${PREFIX}/etc/systemd/system/initrd.target.wants | |
924 | ln -s ../${_name}.device ${PREFIX}/etc/systemd/system/initrd.target.wants/${_name}.device | |
5a575820 | 925 | type mark_hostonly >/dev/null 2>&1 && mark_hostonly /etc/systemd/system/initrd.target.wants/${_name}.device |
ac5bff2b | 926 | _needreload=1 |
44d26d92 | 927 | fi |
6db8c5a5 | 928 | |
ac5bff2b HH |
929 | if ! [ -f ${PREFIX}/etc/systemd/system/${_name}.device.d/timeout.conf ]; then |
930 | mkdir -p ${PREFIX}/etc/systemd/system/${_name}.device.d | |
931 | { | |
932 | echo "[Unit]" | |
56663e7e | 933 | echo "JobTimeoutSec=$_timeout" |
ac5bff2b | 934 | } > ${PREFIX}/etc/systemd/system/${_name}.device.d/timeout.conf |
5a575820 | 935 | type mark_hostonly >/dev/null 2>&1 && mark_hostonly /etc/systemd/system/${_name}.device.d/timeout.conf |
ac5bff2b HH |
936 | _needreload=1 |
937 | fi | |
938 | ||
939 | if [ -z "$PREFIX" ] && [ "$_needreload" = 1 ] && [ -z "$_noreload" ]; then | |
940 | /sbin/initqueue --onetime --unique --name daemon-reload systemctl daemon-reload | |
941 | fi | |
44d26d92 | 942 | fi |
b0692d03 | 943 | } |
4d9d767d N |
944 | # wait_for_dev <dev> |
945 | # | |
946 | # Installs a initqueue-finished script, | |
947 | # which will cause the main loop only to exit, | |
948 | # if the device <dev> is recognized by the system. | |
949 | wait_for_dev() | |
950 | { | |
951 | local _name | |
952 | local _noreload | |
953 | ||
954 | if [ "$1" = "-n" ]; then | |
955 | _noreload=-n | |
956 | shift | |
957 | fi | |
958 | ||
959 | _name="$(str_replace "$1" '/' '\x2f')" | |
960 | ||
961 | type mark_hostonly >/dev/null 2>&1 && mark_hostonly "$hookdir/initqueue/finished/devexists-${_name}.sh" | |
962 | ||
963 | [ -e "${PREFIX}$hookdir/initqueue/finished/devexists-${_name}.sh" ] && return 0 | |
964 | ||
965 | printf '[ -e "%s" ]\n' $1 \ | |
966 | >> "${PREFIX}$hookdir/initqueue/finished/devexists-${_name}.sh" | |
967 | { | |
968 | printf '[ -e "%s" ] || ' $1 | |
969 | printf 'warn "\"%s\" does not exist"\n' $1 | |
970 | } >> "${PREFIX}$hookdir/emergency/80-${_name}.sh" | |
971 | ||
972 | set_systemd_timeout_for_dev $_noreload $1 | |
973 | } | |
745af916 | 974 | |
f65b874b CG |
975 | cancel_wait_for_dev() |
976 | { | |
977 | local _name | |
7c752ffa | 978 | _name="$(str_replace "$1" '/' '\x2f')" |
32bd2fbb HH |
979 | rm -f -- "$hookdir/initqueue/finished/devexists-${_name}.sh" |
980 | rm -f -- "$hookdir/emergency/80-${_name}.sh" | |
6db8c5a5 HH |
981 | if [ -n "$DRACUT_SYSTEMD" ]; then |
982 | _name=$(dev_unit_name "$1") | |
b92896ec | 983 | rm -f -- ${PREFIX}/etc/systemd/system/initrd.target.wants/${_name}.device |
32bd2fbb | 984 | rm -f -- ${PREFIX}/etc/systemd/system/${_name}.device.d/timeout.conf |
6db8c5a5 HH |
985 | /sbin/initqueue --onetime --unique --name daemon-reload systemctl daemon-reload |
986 | fi | |
f65b874b CG |
987 | } |
988 | ||
745af916 | 989 | killproc() { |
c32908ce | 990 | debug_off |
4d638826 HH |
991 | local _exe="$(command -v $1)" |
992 | local _sig=$2 | |
993 | local _i | |
994 | [ -x "$_exe" ] || return 1 | |
995 | for _i in /proc/[0-9]*; do | |
996 | [ "$_i" = "/proc/1" ] && continue | |
997 | if [ -e "$_i"/_exe ] && [ "$_i/_exe" -ef "$_exe" ] ; then | |
998 | kill $_sig ${_i##*/} | |
745af916 HH |
999 | fi |
1000 | done | |
c32908ce | 1001 | debug_on |
745af916 | 1002 | } |
fb67e4aa HH |
1003 | |
1004 | need_shutdown() { | |
1005 | >/run/initramfs/.need_shutdown | |
1006 | } | |
ffcc64bd | 1007 | |
4d518aec HH |
1008 | wait_for_loginit() |
1009 | { | |
4d518aec HH |
1010 | [ "$RD_DEBUG" = "yes" ] || return |
1011 | [ -e /run/initramfs/loginit.pipe ] || return | |
c32908ce | 1012 | debug_off |
4d518aec HH |
1013 | echo "DRACUT_LOG_END" |
1014 | exec 0<>/dev/console 1<>/dev/console 2<>/dev/console | |
1015 | # wait for loginit | |
1016 | i=0 | |
1017 | while [ $i -lt 10 ]; do | |
1018 | if [ ! -e /run/initramfs/loginit.pipe ]; then | |
1019 | j=$(jobs) | |
1020 | [ -z "$j" ] && break | |
1021 | [ -z "${j##*Running*}" ] || break | |
1022 | fi | |
1023 | sleep 0.1 | |
1024 | i=$(($i+1)) | |
1025 | done | |
1026 | ||
1027 | if [ $i -eq 10 ]; then | |
1028 | kill %1 >/dev/null 2>&1 | |
6d58fa27 | 1029 | kill $(while read line || [ -n "$line" ];do echo $line;done</run/initramfs/loginit.pid) |
4d518aec HH |
1030 | fi |
1031 | ||
478314a9 | 1032 | setdebug |
32bd2fbb | 1033 | rm -f -- /run/initramfs/loginit.pipe /run/initramfs/loginit.pid |
4d518aec HH |
1034 | } |
1035 | ||
45ef8eb7 HH |
1036 | # pidof version for root |
1037 | if ! command -v pidof >/dev/null 2>/dev/null; then | |
1038 | pidof() { | |
ad8638e0 | 1039 | debug_off |
45ef8eb7 HH |
1040 | local _cmd |
1041 | local _exe | |
1042 | local _rl | |
4e58a1ff | 1043 | local _ret=1 |
45ef8eb7 HH |
1044 | local i |
1045 | _cmd="$1" | |
ad8638e0 HH |
1046 | if [ -z "$_cmd" ]; then |
1047 | debug_on | |
1048 | return 1 | |
1049 | fi | |
45ef8eb7 HH |
1050 | _exe=$(type -P "$1") |
1051 | for i in /proc/*/exe; do | |
6cc8f694 | 1052 | [ -e "$i" ] || continue |
45ef8eb7 | 1053 | if [ -n "$_exe" ]; then |
abdf191b | 1054 | [ "$i" -ef "$_exe" ] || continue |
45ef8eb7 HH |
1055 | else |
1056 | _rl=$(readlink -f "$i"); | |
1057 | [ "${_rl%/$_cmd}" != "$_rl" ] || continue | |
1058 | fi | |
1059 | i=${i%/exe} | |
1060 | echo ${i##/proc/} | |
4e58a1ff | 1061 | _ret=0 |
45ef8eb7 | 1062 | done |
ad8638e0 | 1063 | debug_on |
4e58a1ff | 1064 | return $_ret |
45ef8eb7 HH |
1065 | } |
1066 | fi | |
1067 | ||
126732bc DY |
1068 | _emergency_shell() |
1069 | { | |
1070 | local _name="$1" | |
7dd7ff0f | 1071 | if [ -n "$DRACUT_SYSTEMD" ]; then |
126732bc | 1072 | > /.console_lock |
b6f2e058 | 1073 | echo "PS1=\"$_name:\\\${PWD}# \"" >/etc/profile |
2242cd92 | 1074 | systemctl start dracut-emergency.service |
32bd2fbb HH |
1075 | rm -f -- /etc/profile |
1076 | rm -f -- /.console_lock | |
126732bc | 1077 | else |
64d144ae HH |
1078 | debug_off |
1079 | echo | |
c33488fe HH |
1080 | /sbin/rdsosreport |
1081 | echo 'You might want to save "/run/initramfs/rdsosreport.txt" to a USB stick or /boot' | |
64d144ae HH |
1082 | echo 'after mounting them and attach it to a bug report.' |
1083 | if ! RD_DEBUG= getargbool 0 rd.debug -d -y rdinitdebug -d -y rdnetdebug; then | |
1084 | echo | |
1085 | echo 'To get more debug information in the report,' | |
1086 | echo 'reboot with "rd.debug" added to the kernel command line.' | |
1087 | fi | |
1088 | echo | |
1089 | echo 'Dropping to debug shell.' | |
126732bc DY |
1090 | echo |
1091 | export PS1="$_name:\${PWD}# " | |
1092 | [ -e /.profile ] || >/.profile | |
1093 | ||
64d144ae | 1094 | _ctty="$(RD_DEBUG= getarg rd.ctty=)" && _ctty="/dev/${_ctty##*/}" |
126732bc DY |
1095 | if [ -z "$_ctty" ]; then |
1096 | _ctty=console | |
1097 | while [ -f /sys/class/tty/$_ctty/active ]; do | |
1098 | _ctty=$(cat /sys/class/tty/$_ctty/active) | |
1099 | _ctty=${_ctty##* } # last one in the list | |
1100 | done | |
1101 | _ctty=/dev/$_ctty | |
1102 | fi | |
1103 | [ -c "$_ctty" ] || _ctty=/dev/tty1 | |
3bff70ef | 1104 | case "$(/usr/bin/setsid --help 2>&1)" in *--ctty*) CTTY="--ctty";; esac |
a6c718ce | 1105 | setsid $CTTY /bin/sh -i -l 0<>$_ctty 1<>$_ctty 2<>$_ctty |
126732bc DY |
1106 | fi |
1107 | } | |
1108 | ||
ffcc64bd WW |
1109 | emergency_shell() |
1110 | { | |
1111 | local _ctty | |
1112 | set +e | |
bd3bf2ce | 1113 | local _rdshell_name="dracut" action="Boot" hook="emergency" |
ffcc64bd WW |
1114 | if [ "$1" = "-n" ]; then |
1115 | _rdshell_name=$2 | |
1116 | shift 2 | |
bd3bf2ce WW |
1117 | elif [ "$1" = "--shutdown" ]; then |
1118 | _rdshell_name=$2; action="Shutdown"; hook="shutdown-emergency" | |
ca2c6936 HH |
1119 | if type plymouth >/dev/null 2>&1; then |
1120 | plymouth --hide-splash | |
5b683008 HH |
1121 | elif [ -x /oldroot/bin/plymouth ]; then |
1122 | /oldroot/bin/plymouth --hide-splash | |
1123 | fi | |
bd3bf2ce | 1124 | shift 2 |
ffcc64bd | 1125 | fi |
1e570bf8 | 1126 | |
ffcc64bd | 1127 | echo ; echo |
84a12fbc | 1128 | warn "$*" |
bd3bf2ce | 1129 | source_hook "$hook" |
ffcc64bd | 1130 | echo |
1e570bf8 | 1131 | |
68e7661c | 1132 | if getargbool 1 rd.shell -d -y rdshell || getarg rd.break -d rdbreak; then |
126732bc | 1133 | _emergency_shell $_rdshell_name |
ffcc64bd | 1134 | else |
64d144ae | 1135 | warn "$action has failed. To debug this issue add \"rd.shell rd.debug\" to the kernel command line." |
ffcc64bd WW |
1136 | # cause a kernel panic |
1137 | exit 1 | |
1138 | fi | |
e2ecc2d8 HH |
1139 | |
1140 | if [ -e /run/initramfs/.die ]; then | |
1141 | if [ -n "$DRACUT_SYSTEMD" ]; then | |
1142 | systemctl --no-block --force halt | |
1143 | fi | |
1144 | exit 1 | |
1145 | fi | |
ffcc64bd | 1146 | } |
476eb1b3 HH |
1147 | |
1148 | # Retain the values of these variables but ensure that they are unexported | |
1149 | # This is a POSIX-compliant equivalent of bash's "export -n" | |
1150 | export_n() | |
1151 | { | |
1152 | local var | |
1153 | local val | |
1154 | for var in "$@"; do | |
1155 | eval val=\$$var | |
1156 | unset $var | |
1157 | [ -n "$val" ] && eval $var=\"$val\" | |
1158 | done | |
1159 | } | |
5767201e AŻ |
1160 | |
1161 | # returns OK if list1 contains all elements of list2, i.e. checks if list2 is a | |
1162 | # sublist of list1. An order and a duplication doesn't matter. | |
1163 | # | |
1164 | # $1 = separator | |
1165 | # $2 = list1 | |
1166 | # $3 = list2 | |
1167 | # $4 = ignore values, separated by $1 | |
1168 | listlist() { | |
1169 | local _sep="$1" | |
1170 | local _list="${_sep}${2}${_sep}" | |
1171 | local _sublist="$3" | |
1172 | [ -n "$4" ] && local _iglist="${_sep}${4}${_sep}" | |
1173 | local IFS="$_sep" | |
1174 | local _v | |
1175 | ||
1176 | [ "$_list" = "$_sublist" ] && return 0 | |
1177 | ||
1178 | for _v in $_sublist; do | |
1179 | if [ -n "$_v" ] && ! ( [ -n "$_iglist" ] && strstr "$_iglist" "$_v" ) | |
1180 | then | |
1181 | strstr "$_list" "$_v" || return 1 | |
1182 | fi | |
1183 | done | |
1184 | ||
1185 | return 0 | |
1186 | } | |
1187 | ||
1188 | # returns OK if both lists contain the same values. An order and a duplication | |
1189 | # doesn't matter. | |
6db8c5a5 | 1190 | # |
5767201e AŻ |
1191 | # $1 = separator |
1192 | # $2 = list1 | |
1193 | # $3 = list2 | |
1194 | # $4 = ignore values, separated by $1 | |
1195 | are_lists_eq() { | |
1196 | listlist "$1" "$2" "$3" "$4" && listlist "$1" "$3" "$2" "$4" | |
1197 | } | |
7bd8f233 DY |
1198 | |
1199 | setmemdebug() { | |
1200 | if [ -z "$DEBUG_MEM_LEVEL" ]; then | |
1201 | export DEBUG_MEM_LEVEL=$(getargnum 0 0 3 rd.memdebug) | |
1202 | fi | |
1203 | } | |
1204 | ||
1205 | setmemdebug | |
1206 | ||
1207 | # parameters: msg [trace_level:trace]... | |
1208 | make_trace_mem() | |
1209 | { | |
1210 | local msg | |
1211 | msg="$1" | |
1212 | shift | |
1213 | if [ -n "$DEBUG_MEM_LEVEL" ] && [ "$DEBUG_MEM_LEVEL" -gt 0 ]; then | |
dff9a66c | 1214 | make_trace show_memstats $DEBUG_MEM_LEVEL "[debug_mem]" "$msg" "$@" >&2 |
7bd8f233 DY |
1215 | fi |
1216 | } | |
1217 | ||
1218 | # parameters: func log_level prefix msg [trace_level:trace]... | |
1219 | make_trace() | |
1220 | { | |
1221 | local func log_level prefix msg msg_printed | |
1222 | local trace trace_level trace_in_higher_levels insert_trace | |
1223 | ||
1224 | func=$1 | |
1225 | shift | |
1226 | ||
1227 | log_level=$1 | |
1228 | shift | |
1229 | ||
1230 | prefix=$1 | |
1231 | shift | |
1232 | ||
1233 | msg=$1 | |
1234 | shift | |
1235 | ||
1236 | if [ -z "$log_level" ]; then | |
1237 | return | |
1238 | fi | |
1239 | ||
1240 | msg=$(echo $msg) | |
1241 | ||
1242 | msg_printed=0 | |
1243 | while [ $# -gt 0 ]; do | |
1244 | trace=${1%%:*} | |
1245 | trace_level=${trace%%+} | |
1246 | [ "$trace" != "$trace_level" ] && trace_in_higher_levels="yes" | |
1247 | trace=${1##*:} | |
1248 | ||
1249 | if [ -z "$trace_level" ]; then | |
1250 | trace_level=0 | |
1251 | fi | |
1252 | ||
1253 | insert_trace=0 | |
1254 | if [ -n "$trace_in_higher_levels" ]; then | |
1255 | if [ "$log_level" -ge "$trace_level" ]; then | |
1256 | insert_trace=1 | |
1257 | fi | |
1258 | else | |
1259 | if [ "$log_level" -eq "$trace_level" ]; then | |
1260 | insert_trace=1 | |
1261 | fi | |
1262 | fi | |
1263 | ||
1264 | if [ $insert_trace -eq 1 ]; then | |
1265 | if [ $msg_printed -eq 0 ]; then | |
1266 | echo "$prefix $msg" | |
1267 | msg_printed=1 | |
1268 | fi | |
1269 | $func $trace | |
1270 | fi | |
1271 | shift | |
1272 | done | |
1273 | } | |
1274 | ||
1275 | # parameters: type | |
1276 | show_memstats() | |
1277 | { | |
1278 | case $1 in | |
1279 | shortmem) | |
1280 | cat /proc/meminfo | grep -e "^MemFree" -e "^Cached" -e "^Slab" | |
1281 | ;; | |
1282 | mem) | |
1283 | cat /proc/meminfo | |
1284 | ;; | |
1285 | slab) | |
1286 | cat /proc/slabinfo | |
1287 | ;; | |
1288 | iomem) | |
1289 | cat /proc/iomem | |
1290 | ;; | |
1291 | esac | |
1292 | } | |
5a575820 HH |
1293 | |
1294 | remove_hostonly_files() { | |
87e90d7f | 1295 | rm -fr /etc/cmdline /etc/cmdline.d/*.conf "$hookdir/initqueue/finished" |
5a575820 | 1296 | if [ -f /lib/dracut/hostonly-files ]; then |
6d58fa27 | 1297 | while read line || [ -n "$line" ]; do |
7075a402 | 1298 | [ -e "$line" ] || [ -h "$line" ] || continue |
5a575820 HH |
1299 | rm -f "$line" |
1300 | done < /lib/dracut/hostonly-files | |
1301 | fi | |
1302 | } |