]> git.ipfire.org Git - thirdparty/dracut.git/blame - dracut-functions.sh
test: use hosts randomness, not rngd
[thirdparty/dracut.git] / dracut-functions.sh
CommitLineData
04b56f3a
JK
1#!/bin/bash
2#
33ee031c 3# functions used by dracut and other tools.
04b56f3a 4#
33ee031c 5# Copyright 2005-2009 Red Hat, Inc. All rights reserved.
04b56f3a
JK
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
0f9c78c1 18# along with this program. If not, see <http://www.gnu.org/licenses/>.
04b56f3a 19#
258de828 20export LC_MESSAGES=C
f4031e8a 21
561eb42f
HH
22# is_func <command>
23# Check whether $1 is a function.
24is_func() {
25 [[ "$(type -t "$1")" = "function" ]]
26}
27
eaa924b6 28
8d95b8b3 29# Generic substring function. If $2 is in $1, return 0.
2c19a5fa
CF
30strstr() { [[ $1 = *"$2"* ]]; }
31# Generic glob matching function. If glob pattern $2 matches anywhere in $1, OK
32strglobin() { [[ $1 = *$2* ]]; }
33# Generic glob matching function. If glob pattern $2 matches all of $1, OK
34strglob() { [[ $1 = $2 ]]; }
1cadc26f
HH
35# returns OK if $1 contains literal string $2 at the beginning, and isn't empty
36str_starts() { [ "${1#"$2"*}" != "$1" ]; }
37# returns OK if $1 contains literal string $2 at the end, and isn't empty
38str_ends() { [ "${1%*"$2"}" != "$1" ]; }
8d95b8b3 39
f4031e8a
HH
40# find a binary. If we were not passed the full path directly,
41# search in the usual places to find the binary.
42find_binary() {
a0120420
BZ
43 local _delim
44 local l
45 local p
46 [[ -z ${1##/*} ]] || _delim="/"
47
48 if [[ "$1" == *.so* ]]; then
49 for l in libdirs ; do
50 if { $DRACUT_LDD "$dracutsysrootdir$l$_delim$1" &>/dev/null; }; then
51 printf "%s\n" "$1"
52 return 0
53 fi
54 done
55 if { $DRACUT_LDD "$dracutsysrootdir$_delim$1" &>/dev/null; }; then
b093aa2d 56 printf "%s\n" "$1"
f4031e8a
HH
57 return 0
58 fi
59 fi
a0120420
BZ
60 if [[ "$1" == */* ]]; then
61 if [[ -L $dracutsysrootdir$_delim$1 ]] || [[ -x $dracutsysrootdir$_delim$1 ]]; then
62 printf "%s\n" "$1"
63 return 0
64 fi
65 fi
66 for p in $DRACUT_PATH ; do
67 if [[ -L $dracutsysrootdir$p$_delim$1 ]] || [[ -x $dracutsysrootdir$p$_delim$1 ]]; then
68 printf "%s\n" "$1"
69 return 0
70 fi
71 done
f4031e8a 72
a0120420 73 [[ -n "$dracutsysrootdir" ]] && return 1
b093aa2d 74 type -P "${1##*/}"
f4031e8a
HH
75}
76
4fe1bdd4
HH
77ldconfig_paths()
78{
a0120420 79 $DRACUT_LDCONFIG ${dracutsysrootdir:+-r ${dracutsysrootdir} -f /etc/ld.so.conf} -pN 2>/dev/null | grep -E -v '/(lib|lib64|usr/lib|usr/lib64)/[^/]*$' | sed -n 's,.* => \(.*\)/.*,\1,p' | sort | uniq
4fe1bdd4
HH
80}
81
f06c2b58
HH
82# Version comparision function. Assumes Linux style version scheme.
83# $1 = version a
84# $2 = comparision op (gt, ge, eq, le, lt, ne)
85# $3 = version b
86vercmp() {
87 local _n1=(${1//./ }) _op=$2 _n2=(${3//./ }) _i _res
88
89 for ((_i=0; ; _i++))
90 do
91 if [[ ! ${_n1[_i]}${_n2[_i]} ]]; then _res=0
92 elif ((${_n1[_i]:-0} > ${_n2[_i]:-0})); then _res=1
93 elif ((${_n1[_i]:-0} < ${_n2[_i]:-0})); then _res=2
94 else continue
95 fi
96 break
97 done
98
99 case $_op in
100 gt) ((_res == 1));;
101 ge) ((_res != 2));;
102 eq) ((_res == 0));;
103 le) ((_res != 1));;
104 lt) ((_res == 2));;
105 ne) ((_res != 0));;
106 esac
107}
108
87122afc
109# Create all subdirectories for given path without creating the last element.
110# $1 = path
b093aa2d
HH
111mksubdirs() {
112 [[ -e ${1%/*} ]] || mkdir -m 0755 -p -- "${1%/*}"
113}
87122afc 114
87122afc
115# Function prints global variables in format name=value line by line.
116# $@ = list of global variables' name
117print_vars() {
29b10e65 118 local _var _value
87122afc 119
b093aa2d 120 for _var in "$@"
87122afc 121 do
7a94a432 122 eval printf -v _value "%s" \""\$$_var"\"
b093aa2d 123 [[ ${_value} ]] && printf '%s="%s"\n' "$_var" "$_value"
87122afc
124 done
125}
126
7e2bca48
HH
127# normalize_path <path>
128# Prints the normalized path, where it removes any duplicated
129# and trailing slashes.
130# Example:
131# $ normalize_path ///test/test//
132# /test/test
626d9eba 133normalize_path() {
c44e3cb4
MS
134 shopt -q -s extglob
135 set -- "${1//+(\/)//}"
136 shopt -q -u extglob
466a5998 137 printf "%s\n" "${1%/}"
626d9eba 138}
d4bb4316 139
7e2bca48
HH
140# convert_abs_rel <from> <to>
141# Prints the relative path, when creating a symlink to <to> from <from>.
142# Example:
143# $ convert_abs_rel /usr/bin/test /bin/test-2
144# ../../bin/test-2
145# $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test
d4bb4316 146convert_abs_rel() {
6d2a7942 147 local __current __absolute __abssize __cursize __newpath
c44e3cb4 148 local -i __i __level
d4bb4316 149
c44e3cb4
MS
150 set -- "$(normalize_path "$1")" "$(normalize_path "$2")"
151
c1609dd4 152 # corner case #1 - self looping link
466a5998 153 [[ "$1" == "$2" ]] && { printf "%s\n" "${1##*/}"; return; }
c1609dd4
MS
154
155 # corner case #2 - own dir link
466a5998 156 [[ "${1%/*}" == "$2" ]] && { printf ".\n"; return; }
c1609dd4 157
6d2a7942
HH
158 IFS="/" __current=($1)
159 IFS="/" __absolute=($2)
d4bb4316
HH
160
161 __abssize=${#__absolute[@]}
162 __cursize=${#__current[@]}
163
b093aa2d 164 while [[ "${__absolute[__level]}" == "${__current[__level]}" ]]
d4bb4316
HH
165 do
166 (( __level++ ))
167 if (( __level > __abssize || __level > __cursize ))
168 then
169 break
170 fi
171 done
172
173 for ((__i = __level; __i < __cursize-1; __i++))
174 do
175 if ((__i > __level))
176 then
177 __newpath=$__newpath"/"
178 fi
179 __newpath=$__newpath".."
180 done
181
182 for ((__i = __level; __i < __abssize; __i++))
183 do
184 if [[ -n $__newpath ]]
185 then
186 __newpath=$__newpath"/"
187 fi
188 __newpath=$__newpath${__absolute[__i]}
189 done
190
466a5998 191 printf "%s\n" "$__newpath"
d4bb4316
HH
192}
193
a20d24de 194
7e2bca48 195# get_fs_env <device>
97af51db 196# Get and the ID_FS_TYPE variable from udev for a device.
7e2bca48 197# Example:
97af51db 198# $ get_fs_env /dev/sda2
7e2bca48 199# ext4
9ede1929 200get_fs_env() {
7c179686 201 [[ $1 ]] || return
29b10e65 202 unset ID_FS_TYPE
69f7ed96 203 ID_FS_TYPE=$(blkid -u filesystem -o export -- "$1" \
6d58fa27 204 | while read line || [ -n "$line" ]; do
69f7ed96
HH
205 if [[ "$line" == TYPE\=* ]]; then
206 printf "%s" "${line#TYPE=}";
207 exit 0;
208 fi
209 done)
210 if [[ $ID_FS_TYPE ]]; then
211 printf "%s" "$ID_FS_TYPE"
212 return 0
7c179686 213 fi
a5cde2dd
HH
214 return 1
215}
9ede1929 216
7e2bca48
HH
217# get_maj_min <device>
218# Prints the major and minor of a device node.
219# Example:
220# $ get_maj_min /dev/sda2
221# 8:2
480d772f 222get_maj_min() {
224175d8 223 local _majmin
dba20559
HH
224 _majmin="$(stat -L -c '%t:%T' "$1" 2>/dev/null)"
225 printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))"
480d772f
HH
226}
227
281327f7
HH
228
229# get_devpath_block <device>
230# get the DEVPATH in /sys of a block device
231get_devpath_block() {
8552a327 232 local _majmin _i
281327f7
HH
233 _majmin=$(get_maj_min "$1")
234
235 for _i in /sys/block/*/dev /sys/block/*/*/dev; do
236 [[ -e "$_i" ]] || continue
237 if [[ "$_majmin" == "$(<"$_i")" ]]; then
238 printf "%s" "${_i%/dev}"
239 return 0
240 fi
241 done
242 return 1
243}
244
69f7ed96
HH
245# get a persistent path from a device
246get_persistent_dev() {
b6054b5d 247 local i _tmp _dev _pol
69f7ed96
HH
248
249 _dev=$(get_maj_min "$1")
250 [ -z "$_dev" ] && return
251
b6054b5d
MW
252 if [[ -n "$persistent_policy" ]]; then
253 _pol="/dev/disk/${persistent_policy}/*"
254 else
255 _pol=
256 fi
257
324ea606 258 for i in \
b6054b5d 259 $_pol \
324ea606 260 /dev/mapper/* \
324ea606
HH
261 /dev/disk/by-uuid/* \
262 /dev/disk/by-label/* \
263 /dev/disk/by-partuuid/* \
264 /dev/disk/by-partlabel/* \
265 /dev/disk/by-id/* \
266 /dev/disk/by-path/* \
267 ; do
2b9d8f65 268 [[ -e "$i" ]] || continue
1743473b 269 [[ $i == /dev/mapper/control ]] && continue
69f7ed96
HH
270 [[ $i == /dev/mapper/mpath* ]] && continue
271 _tmp=$(get_maj_min "$i")
272 if [ "$_tmp" = "$_dev" ]; then
273 printf -- "%s" "$i"
274 return
275 fi
276 done
9efb74a3 277 printf -- "%s" "$1"
69f7ed96
HH
278}
279
c82a1133
HH
280expand_persistent_dev() {
281 local _dev=$1
282
283 case "$_dev" in
284 LABEL=*)
285 _dev="/dev/disk/by-label/${_dev#LABEL=}"
286 ;;
287 UUID=*)
288 _dev="${_dev#UUID=}"
93b02f50 289 _dev="${_dev,,}"
c82a1133
HH
290 _dev="/dev/disk/by-uuid/${_dev}"
291 ;;
292 PARTUUID=*)
293 _dev="${_dev#PARTUUID=}"
93b02f50 294 _dev="${_dev,,}"
c82a1133
HH
295 _dev="/dev/disk/by-partuuid/${_dev}"
296 ;;
297 PARTLABEL=*)
298 _dev="/dev/disk/by-partlabel/${_dev#PARTLABEL=}"
299 ;;
300 esac
301 printf "%s" "$_dev"
302}
303
324ea606 304shorten_persistent_dev() {
c82a1133
HH
305 local _dev="$1"
306 case "$_dev" in
324ea606 307 /dev/disk/by-uuid/*)
c82a1133 308 printf "%s" "UUID=${_dev##*/}";;
324ea606 309 /dev/disk/by-label/*)
c82a1133 310 printf "%s" "LABEL=${_dev##*/}";;
324ea606 311 /dev/disk/by-partuuid/*)
c82a1133 312 printf "%s" "PARTUUID=${_dev##*/}";;
324ea606 313 /dev/disk/by-partlabel/*)
c82a1133 314 printf "%s" "PARTLABEL=${_dev##*/}";;
324ea606 315 *)
c82a1133 316 printf "%s" "$_dev";;
324ea606
HH
317 esac
318}
319
7e2bca48
HH
320# find_block_device <mountpoint>
321# Prints the major and minor number of the block device
322# for a given mountpoint.
323# Unless $use_fstab is set to "yes" the functions
324# uses /proc/self/mountinfo as the primary source of the
325# information and only falls back to /etc/fstab, if the mountpoint
326# is not found there.
327# Example:
328# $ find_block_device /usr
329# 8:4
f76ef3aa 330find_block_device() {
9918afd2 331 local _dev _majmin _find_mpt
c8d685c9 332 _find_mpt="$1"
0b706743 333 if [[ $use_fstab != yes ]]; then
9d36d4fb 334 [[ -d $_find_mpt/. ]]
dba20559 335 findmnt -e -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" | { \
6d58fa27 336 while read _majmin _dev || [ -n "$_dev" ]; do
dba20559
HH
337 if [[ -b $_dev ]]; then
338 if ! [[ $_majmin ]] || [[ $_majmin == 0:* ]]; then
339 _majmin=$(get_maj_min $_dev)
340 fi
341 if [[ $_majmin ]]; then
466a5998 342 printf "%s\n" "$_majmin"
dba20559 343 else
466a5998 344 printf "%s\n" "$_dev"
dba20559
HH
345 fi
346 return 0
347 fi
348 if [[ $_dev = *:* ]]; then
466a5998 349 printf "%s\n" "$_dev"
dba20559
HH
350 return 0
351 fi
352 done; return 1; } && return 0
353 fi
354 # fall back to /etc/fstab
355
356 findmnt -e --fstab -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" | { \
6d58fa27 357 while read _majmin _dev || [ -n "$_dev" ]; do
dba20559
HH
358 if ! [[ $_dev ]]; then
359 _dev="$_majmin"
360 unset _majmin
361 fi
9d36d4fb 362 if [[ -b $_dev ]]; then
dba20559 363 [[ $_majmin ]] || _majmin=$(get_maj_min $_dev)
9d36d4fb 364 if [[ $_majmin ]]; then
466a5998 365 printf "%s\n" "$_majmin"
9d36d4fb 366 else
466a5998 367 printf "%s\n" "$_dev"
9d36d4fb
HH
368 fi
369 return 0
370 fi
371 if [[ $_dev = *:* ]]; then
466a5998 372 printf "%s\n" "$_dev"
9d36d4fb 373 return 0
cc02093d 374 fi
dba20559 375 done; return 1; } && return 0
0b706743
376
377 return 1
17829e94
VL
378}
379
9d36d4fb
HH
380# find_mp_fstype <mountpoint>
381# Echo the filesystem type for a given mountpoint.
7e2bca48
HH
382# /proc/self/mountinfo is taken as the primary source of information
383# and /etc/fstab is used as a fallback.
384# No newline is appended!
385# Example:
9d36d4fb 386# $ find_mp_fstype /;echo
7e2bca48 387# ext4
9d36d4fb
HH
388find_mp_fstype() {
389 local _fs
7ae5d9d1 390
9d36d4fb 391 if [[ $use_fstab != yes ]]; then
dba20559 392 findmnt -e -v -n -o 'FSTYPE' --target "$1" | { \
6d58fa27 393 while read _fs || [ -n "$_fs" ]; do
dba20559
HH
394 [[ $_fs ]] || continue
395 [[ $_fs = "autofs" ]] && continue
466a5998 396 printf "%s" "$_fs"
dba20559
HH
397 return 0
398 done; return 1; } && return 0
399 fi
400
401 findmnt --fstab -e -v -n -o 'FSTYPE' --target "$1" | { \
6d58fa27 402 while read _fs || [ -n "$_fs" ]; do
9d36d4fb
HH
403 [[ $_fs ]] || continue
404 [[ $_fs = "autofs" ]] && continue
466a5998 405 printf "%s" "$_fs"
9d36d4fb 406 return 0
dba20559 407 done; return 1; } && return 0
7ae5d9d1
HH
408
409 return 1
410}
411
9d36d4fb
HH
412# find_dev_fstype <device>
413# Echo the filesystem type for a given device.
81672479
HH
414# /proc/self/mountinfo is taken as the primary source of information
415# and /etc/fstab is used as a fallback.
416# No newline is appended!
417# Example:
9d36d4fb 418# $ find_dev_fstype /dev/sda2;echo
81672479 419# ext4
9d36d4fb 420find_dev_fstype() {
5e601454 421 local _find_dev _fs
9d36d4fb 422 _find_dev="$1"
a4f7b504
HH
423 if ! [[ "$_find_dev" = /dev* ]]; then
424 [[ -b "/dev/block/$_find_dev" ]] && _find_dev="/dev/block/$_find_dev"
425 fi
5e601454
HH
426
427 if [[ $use_fstab != yes ]]; then
dba20559 428 findmnt -e -v -n -o 'FSTYPE' --source "$_find_dev" | { \
6d58fa27 429 while read _fs || [ -n "$_fs" ]; do
dba20559
HH
430 [[ $_fs ]] || continue
431 [[ $_fs = "autofs" ]] && continue
466a5998 432 printf "%s" "$_fs"
dba20559
HH
433 return 0
434 done; return 1; } && return 0
435 fi
436
437 findmnt --fstab -e -v -n -o 'FSTYPE' --source "$_find_dev" | { \
6d58fa27 438 while read _fs || [ -n "$_fs" ]; do
5e601454
HH
439 [[ $_fs ]] || continue
440 [[ $_fs = "autofs" ]] && continue
466a5998 441 printf "%s" "$_fs"
5e601454 442 return 0
dba20559 443 done; return 1; } && return 0
5e601454
HH
444
445 return 1
97af51db 446}
5e601454 447
bbc9bfe1
HH
448# find_mp_fsopts <mountpoint>
449# Echo the filesystem options for a given mountpoint.
450# /proc/self/mountinfo is taken as the primary source of information
451# and /etc/fstab is used as a fallback.
452# No newline is appended!
453# Example:
454# $ find_mp_fsopts /;echo
455# rw,relatime,discard,data=ordered
456find_mp_fsopts() {
457 if [[ $use_fstab != yes ]]; then
458 findmnt -e -v -n -o 'OPTIONS' --target "$1" 2>/dev/null && return 0
459 fi
460
461 findmnt --fstab -e -v -n -o 'OPTIONS' --target "$1"
462}
463
97af51db
HH
464# find_dev_fsopts <device>
465# Echo the filesystem options for a given device.
466# /proc/self/mountinfo is taken as the primary source of information
467# and /etc/fstab is used as a fallback.
468# Example:
469# $ find_dev_fsopts /dev/sda2
470# rw,relatime,discard,data=ordered
471find_dev_fsopts() {
472 local _find_dev _opts
473 _find_dev="$1"
474 if ! [[ "$_find_dev" = /dev* ]]; then
475 [[ -b "/dev/block/$_find_dev" ]] && _find_dev="/dev/block/$_find_dev"
476 fi
477
478 if [[ $use_fstab != yes ]]; then
479 findmnt -e -v -n -o 'OPTIONS' --source "$_find_dev" 2>/dev/null && return 0
480 fi
481
482 findmnt --fstab -e -v -n -o 'OPTIONS' --source "$_find_dev"
81672479
HH
483}
484
97af51db 485
7ae5d9d1 486# finds the major:minor of the block device backing the root filesystem.
f76ef3aa
VL
487find_root_block_device() { find_block_device /; }
488
7e2bca48 489# for_each_host_dev_fs <func>
d351541e 490# Execute "<func> <dev> <filesystem>" for every "<dev> <fs>" pair found
7e2bca48 491# in ${host_fs_types[@]}
480d772f
HH
492for_each_host_dev_fs()
493{
494 local _func="$1"
d0096de7 495 local _dev
2efa546f 496 local _ret=1
fd191a7b 497
e6199960
PL
498 [[ "${#host_fs_types[@]}" ]] || return 2
499
fd191a7b 500
d351541e
HH
501 for _dev in "${!host_fs_types[@]}"; do
502 $_func "$_dev" "${host_fs_types[$_dev]}" && _ret=0
480d772f 503 done
2efa546f 504 return $_ret
480d772f
HH
505}
506
fd191a7b
HH
507host_fs_all()
508{
466a5998 509 printf "%s\n" "${host_fs_types[@]}"
fd191a7b
HH
510}
511
17829e94
VL
512# Walk all the slave relationships for a given block device.
513# Stop when our helper function returns success
514# $1 = function to call on every found block device
515# $2 = block device in major:minor format
0b706743 516check_block_and_slaves() {
29b10e65 517 local _x
17829e94 518 [[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
96c6f6f3 519 if ! lvm_internal_dev $2; then "$1" $2 && return; fi
533d7dc4 520 check_vol_slaves "$@" && return 0
e64dafd1 521 if [[ -f /sys/dev/block/$2/../dev ]] && [[ /sys/dev/block/$2/../subsystem -ef /sys/class/block ]]; then
dba20559 522 check_block_and_slaves $1 $(<"/sys/dev/block/$2/../dev") && return 0
a3afcf2a 523 fi
17829e94 524 [[ -d /sys/dev/block/$2/slaves ]] || return 1
e64dafd1
HH
525 for _x in /sys/dev/block/$2/slaves/*; do
526 [[ -f $_x/dev ]] || continue
527 [[ $_x/subsystem -ef /sys/class/block ]] || continue
528 check_block_and_slaves $1 $(<"$_x/dev") && return 0
17829e94
VL
529 done
530 return 1
531}
532
83e0dc7a
DY
533check_block_and_slaves_all() {
534 local _x _ret=1
535 [[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
96c6f6f3 536 if ! lvm_internal_dev $2 && "$1" $2; then
dba20559 537 _ret=0
83e0dc7a 538 fi
c7c8c498 539 check_vol_slaves_all "$@" && return 0
e64dafd1 540 if [[ -f /sys/dev/block/$2/../dev ]] && [[ /sys/dev/block/$2/../subsystem -ef /sys/class/block ]]; then
dba20559 541 check_block_and_slaves_all $1 $(<"/sys/dev/block/$2/../dev") && _ret=0
83e0dc7a
DY
542 fi
543 [[ -d /sys/dev/block/$2/slaves ]] || return 1
e64dafd1
HH
544 for _x in /sys/dev/block/$2/slaves/*; do
545 [[ -f $_x/dev ]] || continue
546 [[ $_x/subsystem -ef /sys/class/block ]] || continue
547 check_block_and_slaves_all $1 $(<"$_x/dev") && _ret=0
83e0dc7a
DY
548 done
549 return $_ret
550}
551# for_each_host_dev_and_slaves <func>
552# Execute "<func> <dev>" for every "<dev>" found
553# in ${host_devs[@]} and their slaves
554for_each_host_dev_and_slaves_all()
555{
556 local _func="$1"
557 local _dev
558 local _ret=1
fd191a7b 559
e6199960 560 [[ "${host_devs[@]}" ]] || return 2
fd191a7b 561
3721635b 562 for _dev in "${host_devs[@]}"; do
83e0dc7a 563 [[ -b "$_dev" ]] || continue
83e0dc7a 564 if check_block_and_slaves_all $_func $(get_maj_min $_dev); then
dba20559 565 _ret=0
83e0dc7a
DY
566 fi
567 done
568 return $_ret
569}
570
571for_each_host_dev_and_slaves()
572{
573 local _func="$1"
574 local _dev
fd191a7b 575
e6199960 576 [[ "${host_devs[@]}" ]] || return 2
fd191a7b 577
3721635b 578 for _dev in "${host_devs[@]}"; do
83e0dc7a 579 [[ -b "$_dev" ]] || continue
a999414e 580 check_block_and_slaves $_func $(get_maj_min $_dev) && return 0
83e0dc7a
DY
581 done
582 return 1
583}
584
533d7dc4
HH
585# ugly workaround for the lvm design
586# There is no volume group device,
587# so, there are no slave devices for volume groups.
588# Logical volumes only have the slave devices they really live on,
589# but you cannot create the logical volume without the volume group.
95bde758 590# And the volume group might be bigger than the devices the LV needs.
533d7dc4 591check_vol_slaves() {
9ed6eb74
HH
592 local _lv _vg _pv _dm _majmin
593 _majmin="$2"
594 _lv="/dev/block/$_majmin"
595 _dm=/sys/dev/block/$_majmin/dm
596 [[ -f $_dm/uuid && $(<$_dm/uuid) =~ LVM-* ]] || return 1
597 _vg=$(dmsetup splitname --noheadings -o vg_name $(<"$_dm/name") )
598 # strip space
599 _vg="${_vg//[[:space:]]/}"
600 if [[ $_vg ]]; then
601 for _pv in $(lvm vgs --noheadings -o pv_name "$_vg" 2>/dev/null)
602 do
603 check_block_and_slaves $1 $(get_maj_min $_pv) && return 0
604 done
605 fi
533d7dc4
HH
606 return 1
607}
608
c7c8c498 609check_vol_slaves_all() {
9ed6eb74
HH
610 local _lv _vg _pv _majmin
611 _majmin="$2"
612 _lv="/dev/block/$_majmin"
613 _dm="/sys/dev/block/$_majmin/dm"
614 [[ -f $_dm/uuid && $(<$_dm/uuid) =~ LVM-* ]] || return 1
615 _vg=$(dmsetup splitname --noheadings -o vg_name $(<"$_dm/name") )
616 # strip space
617 _vg="${_vg//[[:space:]]/}"
618 if [[ $_vg ]]; then
da36b76a 619 # when filter/global_filter is set, lvm may be failed
620 lvm lvs --noheadings -o vg_name $_vg 2>/dev/null 1>/dev/null
621 if [ $? -ne 0 ]; then
622 return 1
623 fi
624
9ed6eb74
HH
625 for _pv in $(lvm vgs --noheadings -o pv_name "$_vg" 2>/dev/null)
626 do
627 check_block_and_slaves_all $1 $(get_maj_min $_pv)
628 done
629 return 0
630 fi
c7c8c498
HH
631 return 1
632}
633
634
635
8aa99268
HH
636# fs_get_option <filesystem options> <search for option>
637# search for a specific option in a bunch of filesystem options
638# and return the value
639fs_get_option() {
640 local _fsopts=$1
641 local _option=$2
642 local OLDIFS="$IFS"
643 IFS=,
644 set -- $_fsopts
645 IFS="$OLDIFS"
646 while [ $# -gt 0 ]; do
647 case $1 in
648 $_option=*)
649 echo ${1#${_option}=}
650 break
651 esac
652 shift
653 done
654}
655
8e3f6537
HH
656check_kernel_config()
657{
658 local _config_opt="$1"
659 local _config_file
a0120420 660 [[ -f $dracutsysrootdir/boot/config-$kernel ]] \
8e3f6537 661 && _config_file="/boot/config-$kernel"
a0120420 662 [[ -f $dracutsysrootdir/lib/modules/$kernel/config ]] \
8e3f6537
HH
663 && _config_file="/lib/modules/$kernel/config"
664
665 # no kernel config file, so return true
666 [[ $_config_file ]] || return 0
667
668 grep -q -F "${_config_opt}=" "$_config_file" && return 0
669 return 1
670}
671
672
5f2c30d9
KRW
673# get_cpu_vendor
674# Only two values are returned: AMD or Intel
675get_cpu_vendor ()
676{
677 if grep -qE AMD /proc/cpuinfo; then
678 printf "AMD"
679 fi
680 if grep -qE Intel /proc/cpuinfo; then
681 printf "Intel"
682 fi
683}
684
685# get_host_ucode
686# Get the hosts' ucode file based on the /proc/cpuinfo
687get_ucode_file ()
688{
689 local family=`grep -E "cpu family" /proc/cpuinfo | head -1 | sed s/.*:\ //`
690 local model=`grep -E "model" /proc/cpuinfo |grep -v name | head -1 | sed s/.*:\ //`
691 local stepping=`grep -E "stepping" /proc/cpuinfo | head -1 | sed s/.*:\ //`
692
693 if [[ "$(get_cpu_vendor)" == "AMD" ]]; then
19453dc8
DM
694 if [[ $family -ge 21 ]]; then
695 printf "microcode_amd_fam%xh.bin" $family
5f2c30d9
KRW
696 else
697 printf "microcode_amd.bin"
698 fi
699 fi
700 if [[ "$(get_cpu_vendor)" == "Intel" ]]; then
701 # The /proc/cpuinfo are in decimal.
702 printf "%02x-%02x-%02x" ${family} ${model} ${stepping}
703 fi
704}
96c6f6f3
MC
705
706# Not every device in /dev/mapper should be examined.
707# If it is an LVM device, touch only devices which have /dev/VG/LV symlink.
708lvm_internal_dev() {
709 local dev_dm_dir=/sys/dev/block/$1/dm
710 [[ ! -f $dev_dm_dir/uuid || $(<$dev_dm_dir/uuid) != LVM-* ]] && return 1 # Not an LVM device
711 local DM_VG_NAME DM_LV_NAME DM_LV_LAYER
712 eval $(dmsetup splitname --nameprefixes --noheadings --rows "$(<$dev_dm_dir/name)" 2>/dev/null)
713 [[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] || return 0 # Better skip this!
714 [[ ${DM_LV_LAYER} ]] || [[ ! -L /dev/${DM_VG_NAME}/${DM_LV_NAME} ]]
715}
716
1cadc26f
HH
717btrfs_devs() {
718 local _mp="$1"
719 btrfs device usage "$_mp" \
720 | while read _dev _rest; do
721 str_starts "$_dev" "/" || continue
722 _dev=${_dev%,}
723 printf -- "%s\n" "$_dev"
724 done
725}