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