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