]> git.ipfire.org Git - thirdparty/dracut.git/blame - dracut-functions.sh
TEST-20-NFS: remove stale pid file
[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() {
226 local i _tmp _dev
227
228 _dev=$(get_maj_min "$1")
229 [ -z "$_dev" ] && return
230
324ea606
HH
231 for i in \
232 /dev/mapper/* \
3411ad66 233 /dev/disk/${persistent_policy:-by-uuid}/* \
324ea606
HH
234 /dev/disk/by-uuid/* \
235 /dev/disk/by-label/* \
236 /dev/disk/by-partuuid/* \
237 /dev/disk/by-partlabel/* \
238 /dev/disk/by-id/* \
239 /dev/disk/by-path/* \
240 ; do
2b9d8f65 241 [[ -e "$i" ]] || continue
1743473b 242 [[ $i == /dev/mapper/control ]] && continue
69f7ed96
HH
243 [[ $i == /dev/mapper/mpath* ]] && continue
244 _tmp=$(get_maj_min "$i")
245 if [ "$_tmp" = "$_dev" ]; then
246 printf -- "%s" "$i"
247 return
248 fi
249 done
9efb74a3 250 printf -- "%s" "$1"
69f7ed96
HH
251}
252
c82a1133
HH
253expand_persistent_dev() {
254 local _dev=$1
255
256 case "$_dev" in
257 LABEL=*)
258 _dev="/dev/disk/by-label/${_dev#LABEL=}"
259 ;;
260 UUID=*)
261 _dev="${_dev#UUID=}"
93b02f50 262 _dev="${_dev,,}"
c82a1133
HH
263 _dev="/dev/disk/by-uuid/${_dev}"
264 ;;
265 PARTUUID=*)
266 _dev="${_dev#PARTUUID=}"
93b02f50 267 _dev="${_dev,,}"
c82a1133
HH
268 _dev="/dev/disk/by-partuuid/${_dev}"
269 ;;
270 PARTLABEL=*)
271 _dev="/dev/disk/by-partlabel/${_dev#PARTLABEL=}"
272 ;;
273 esac
274 printf "%s" "$_dev"
275}
276
324ea606 277shorten_persistent_dev() {
c82a1133
HH
278 local _dev="$1"
279 case "$_dev" in
324ea606 280 /dev/disk/by-uuid/*)
c82a1133 281 printf "%s" "UUID=${_dev##*/}";;
324ea606 282 /dev/disk/by-label/*)
c82a1133 283 printf "%s" "LABEL=${_dev##*/}";;
324ea606 284 /dev/disk/by-partuuid/*)
c82a1133 285 printf "%s" "PARTUUID=${_dev##*/}";;
324ea606 286 /dev/disk/by-partlabel/*)
c82a1133 287 printf "%s" "PARTLABEL=${_dev##*/}";;
324ea606 288 *)
c82a1133 289 printf "%s" "$_dev";;
324ea606
HH
290 esac
291}
292
7e2bca48
HH
293# find_block_device <mountpoint>
294# Prints the major and minor number of the block device
295# for a given mountpoint.
296# Unless $use_fstab is set to "yes" the functions
297# uses /proc/self/mountinfo as the primary source of the
298# information and only falls back to /etc/fstab, if the mountpoint
299# is not found there.
300# Example:
301# $ find_block_device /usr
302# 8:4
f76ef3aa 303find_block_device() {
9918afd2 304 local _dev _majmin _find_mpt
c8d685c9 305 _find_mpt="$1"
0b706743 306 if [[ $use_fstab != yes ]]; then
9d36d4fb 307 [[ -d $_find_mpt/. ]]
dba20559 308 findmnt -e -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" | { \
6d58fa27 309 while read _majmin _dev || [ -n "$_dev" ]; do
dba20559
HH
310 if [[ -b $_dev ]]; then
311 if ! [[ $_majmin ]] || [[ $_majmin == 0:* ]]; then
312 _majmin=$(get_maj_min $_dev)
313 fi
314 if [[ $_majmin ]]; then
466a5998 315 printf "%s\n" "$_majmin"
dba20559 316 else
466a5998 317 printf "%s\n" "$_dev"
dba20559
HH
318 fi
319 return 0
320 fi
321 if [[ $_dev = *:* ]]; then
466a5998 322 printf "%s\n" "$_dev"
dba20559
HH
323 return 0
324 fi
325 done; return 1; } && return 0
326 fi
327 # fall back to /etc/fstab
328
329 findmnt -e --fstab -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" | { \
6d58fa27 330 while read _majmin _dev || [ -n "$_dev" ]; do
dba20559
HH
331 if ! [[ $_dev ]]; then
332 _dev="$_majmin"
333 unset _majmin
334 fi
9d36d4fb 335 if [[ -b $_dev ]]; then
dba20559 336 [[ $_majmin ]] || _majmin=$(get_maj_min $_dev)
9d36d4fb 337 if [[ $_majmin ]]; then
466a5998 338 printf "%s\n" "$_majmin"
9d36d4fb 339 else
466a5998 340 printf "%s\n" "$_dev"
9d36d4fb
HH
341 fi
342 return 0
343 fi
344 if [[ $_dev = *:* ]]; then
466a5998 345 printf "%s\n" "$_dev"
9d36d4fb 346 return 0
cc02093d 347 fi
dba20559 348 done; return 1; } && return 0
0b706743
349
350 return 1
17829e94
VL
351}
352
9d36d4fb
HH
353# find_mp_fstype <mountpoint>
354# Echo the filesystem type for a given mountpoint.
7e2bca48
HH
355# /proc/self/mountinfo is taken as the primary source of information
356# and /etc/fstab is used as a fallback.
357# No newline is appended!
358# Example:
9d36d4fb 359# $ find_mp_fstype /;echo
7e2bca48 360# ext4
9d36d4fb
HH
361find_mp_fstype() {
362 local _fs
7ae5d9d1 363
9d36d4fb 364 if [[ $use_fstab != yes ]]; then
dba20559 365 findmnt -e -v -n -o 'FSTYPE' --target "$1" | { \
6d58fa27 366 while read _fs || [ -n "$_fs" ]; do
dba20559
HH
367 [[ $_fs ]] || continue
368 [[ $_fs = "autofs" ]] && continue
466a5998 369 printf "%s" "$_fs"
dba20559
HH
370 return 0
371 done; return 1; } && return 0
372 fi
373
374 findmnt --fstab -e -v -n -o 'FSTYPE' --target "$1" | { \
6d58fa27 375 while read _fs || [ -n "$_fs" ]; do
9d36d4fb
HH
376 [[ $_fs ]] || continue
377 [[ $_fs = "autofs" ]] && continue
466a5998 378 printf "%s" "$_fs"
9d36d4fb 379 return 0
dba20559 380 done; return 1; } && return 0
7ae5d9d1
HH
381
382 return 1
383}
384
9d36d4fb
HH
385# find_dev_fstype <device>
386# Echo the filesystem type for a given device.
81672479
HH
387# /proc/self/mountinfo is taken as the primary source of information
388# and /etc/fstab is used as a fallback.
389# No newline is appended!
390# Example:
9d36d4fb 391# $ find_dev_fstype /dev/sda2;echo
81672479 392# ext4
9d36d4fb 393find_dev_fstype() {
5e601454 394 local _find_dev _fs
9d36d4fb 395 _find_dev="$1"
a4f7b504
HH
396 if ! [[ "$_find_dev" = /dev* ]]; then
397 [[ -b "/dev/block/$_find_dev" ]] && _find_dev="/dev/block/$_find_dev"
398 fi
5e601454
HH
399
400 if [[ $use_fstab != yes ]]; then
dba20559 401 findmnt -e -v -n -o 'FSTYPE' --source "$_find_dev" | { \
6d58fa27 402 while read _fs || [ -n "$_fs" ]; do
dba20559
HH
403 [[ $_fs ]] || continue
404 [[ $_fs = "autofs" ]] && continue
466a5998 405 printf "%s" "$_fs"
dba20559
HH
406 return 0
407 done; return 1; } && return 0
408 fi
409
410 findmnt --fstab -e -v -n -o 'FSTYPE' --source "$_find_dev" | { \
6d58fa27 411 while read _fs || [ -n "$_fs" ]; do
5e601454
HH
412 [[ $_fs ]] || continue
413 [[ $_fs = "autofs" ]] && continue
466a5998 414 printf "%s" "$_fs"
5e601454 415 return 0
dba20559 416 done; return 1; } && return 0
5e601454
HH
417
418 return 1
97af51db 419}
5e601454 420
bbc9bfe1
HH
421# find_mp_fsopts <mountpoint>
422# Echo the filesystem options for a given mountpoint.
423# /proc/self/mountinfo is taken as the primary source of information
424# and /etc/fstab is used as a fallback.
425# No newline is appended!
426# Example:
427# $ find_mp_fsopts /;echo
428# rw,relatime,discard,data=ordered
429find_mp_fsopts() {
430 if [[ $use_fstab != yes ]]; then
431 findmnt -e -v -n -o 'OPTIONS' --target "$1" 2>/dev/null && return 0
432 fi
433
434 findmnt --fstab -e -v -n -o 'OPTIONS' --target "$1"
435}
436
97af51db
HH
437# find_dev_fsopts <device>
438# Echo the filesystem options for a given device.
439# /proc/self/mountinfo is taken as the primary source of information
440# and /etc/fstab is used as a fallback.
441# Example:
442# $ find_dev_fsopts /dev/sda2
443# rw,relatime,discard,data=ordered
444find_dev_fsopts() {
445 local _find_dev _opts
446 _find_dev="$1"
447 if ! [[ "$_find_dev" = /dev* ]]; then
448 [[ -b "/dev/block/$_find_dev" ]] && _find_dev="/dev/block/$_find_dev"
449 fi
450
451 if [[ $use_fstab != yes ]]; then
452 findmnt -e -v -n -o 'OPTIONS' --source "$_find_dev" 2>/dev/null && return 0
453 fi
454
455 findmnt --fstab -e -v -n -o 'OPTIONS' --source "$_find_dev"
81672479
HH
456}
457
97af51db 458
7ae5d9d1 459# finds the major:minor of the block device backing the root filesystem.
f76ef3aa
VL
460find_root_block_device() { find_block_device /; }
461
7e2bca48 462# for_each_host_dev_fs <func>
d351541e 463# Execute "<func> <dev> <filesystem>" for every "<dev> <fs>" pair found
7e2bca48 464# in ${host_fs_types[@]}
480d772f
HH
465for_each_host_dev_fs()
466{
467 local _func="$1"
d0096de7 468 local _dev
2efa546f 469 local _ret=1
fd191a7b 470
3721635b 471 [[ "${#host_fs_types[@]}" ]] || return 0
fd191a7b 472
d351541e
HH
473 for _dev in "${!host_fs_types[@]}"; do
474 $_func "$_dev" "${host_fs_types[$_dev]}" && _ret=0
480d772f 475 done
2efa546f 476 return $_ret
480d772f
HH
477}
478
fd191a7b
HH
479host_fs_all()
480{
466a5998 481 printf "%s\n" "${host_fs_types[@]}"
fd191a7b
HH
482}
483
17829e94
VL
484# Walk all the slave relationships for a given block device.
485# Stop when our helper function returns success
486# $1 = function to call on every found block device
487# $2 = block device in major:minor format
0b706743 488check_block_and_slaves() {
29b10e65 489 local _x
17829e94 490 [[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
96c6f6f3 491 if ! lvm_internal_dev $2; then "$1" $2 && return; fi
533d7dc4 492 check_vol_slaves "$@" && return 0
3478b314 493 if [[ -f /sys/dev/block/$2/../dev ]]; then
dba20559 494 check_block_and_slaves $1 $(<"/sys/dev/block/$2/../dev") && return 0
a3afcf2a 495 fi
17829e94 496 [[ -d /sys/dev/block/$2/slaves ]] || return 1
29b10e65 497 for _x in /sys/dev/block/$2/slaves/*/dev; do
d82e0d7d 498 [[ -f $_x ]] || continue
dba20559 499 check_block_and_slaves $1 $(<"$_x") && return 0
17829e94
VL
500 done
501 return 1
502}
503
83e0dc7a
DY
504check_block_and_slaves_all() {
505 local _x _ret=1
506 [[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
96c6f6f3 507 if ! lvm_internal_dev $2 && "$1" $2; then
dba20559 508 _ret=0
83e0dc7a
DY
509 fi
510 check_vol_slaves "$@" && return 0
511 if [[ -f /sys/dev/block/$2/../dev ]]; then
dba20559 512 check_block_and_slaves_all $1 $(<"/sys/dev/block/$2/../dev") && _ret=0
83e0dc7a
DY
513 fi
514 [[ -d /sys/dev/block/$2/slaves ]] || return 1
515 for _x in /sys/dev/block/$2/slaves/*/dev; do
516 [[ -f $_x ]] || continue
dba20559 517 check_block_and_slaves_all $1 $(<"$_x") && _ret=0
83e0dc7a
DY
518 done
519 return $_ret
520}
521# for_each_host_dev_and_slaves <func>
522# Execute "<func> <dev>" for every "<dev>" found
523# in ${host_devs[@]} and their slaves
524for_each_host_dev_and_slaves_all()
525{
526 local _func="$1"
527 local _dev
528 local _ret=1
fd191a7b
HH
529
530 [[ "${host_devs[@]}" ]] || return 0
531
3721635b 532 for _dev in "${host_devs[@]}"; do
83e0dc7a 533 [[ -b "$_dev" ]] || continue
83e0dc7a 534 if check_block_and_slaves_all $_func $(get_maj_min $_dev); then
dba20559 535 _ret=0
83e0dc7a
DY
536 fi
537 done
538 return $_ret
539}
540
541for_each_host_dev_and_slaves()
542{
543 local _func="$1"
544 local _dev
fd191a7b
HH
545
546 [[ "${host_devs[@]}" ]] || return 0
547
3721635b 548 for _dev in "${host_devs[@]}"; do
83e0dc7a 549 [[ -b "$_dev" ]] || continue
a999414e 550 check_block_and_slaves $_func $(get_maj_min $_dev) && return 0
83e0dc7a
DY
551 done
552 return 1
553}
554
533d7dc4
HH
555# ugly workaround for the lvm design
556# There is no volume group device,
557# so, there are no slave devices for volume groups.
558# Logical volumes only have the slave devices they really live on,
559# but you cannot create the logical volume without the volume group.
95bde758 560# And the volume group might be bigger than the devices the LV needs.
533d7dc4 561check_vol_slaves() {
3244bf59 562 local _lv _vg _pv _dm
0b706743 563 for i in /dev/mapper/*; do
1743473b 564 [[ $i == /dev/mapper/control ]] && continue
c4e48eae 565 _lv=$(get_maj_min $i)
3244bf59
HR
566 _dm=/sys/dev/block/$_lv/dm
567 [[ -f $_dm/uuid && $(<$_dm/uuid) =~ LVM-* ]] || continue
29b10e65
HH
568 if [[ $_lv = $2 ]]; then
569 _vg=$(lvm lvs --noheadings -o vg_name $i 2>/dev/null)
cc02093d 570 # strip space
2fd8588d 571 _vg="${_vg//[[:space:]]/}"
29b10e65
HH
572 if [[ $_vg ]]; then
573 for _pv in $(lvm vgs --noheadings -o pv_name "$_vg" 2>/dev/null)
0b706743 574 do
c4e48eae 575 check_block_and_slaves $1 $(get_maj_min $_pv) && return 0
cc02093d
HH
576 done
577 fi
578 fi
533d7dc4
HH
579 done
580 return 1
581}
582
8aa99268
HH
583# fs_get_option <filesystem options> <search for option>
584# search for a specific option in a bunch of filesystem options
585# and return the value
586fs_get_option() {
587 local _fsopts=$1
588 local _option=$2
589 local OLDIFS="$IFS"
590 IFS=,
591 set -- $_fsopts
592 IFS="$OLDIFS"
593 while [ $# -gt 0 ]; do
594 case $1 in
595 $_option=*)
596 echo ${1#${_option}=}
597 break
598 esac
599 shift
600 done
601}
602
8e3f6537
HH
603check_kernel_config()
604{
605 local _config_opt="$1"
606 local _config_file
607 [[ -f /boot/config-$kernel ]] \
608 && _config_file="/boot/config-$kernel"
609 [[ -f /lib/modules/$kernel/config ]] \
610 && _config_file="/lib/modules/$kernel/config"
611
612 # no kernel config file, so return true
613 [[ $_config_file ]] || return 0
614
615 grep -q -F "${_config_opt}=" "$_config_file" && return 0
616 return 1
617}
618
619
5f2c30d9
KRW
620# get_cpu_vendor
621# Only two values are returned: AMD or Intel
622get_cpu_vendor ()
623{
624 if grep -qE AMD /proc/cpuinfo; then
625 printf "AMD"
626 fi
627 if grep -qE Intel /proc/cpuinfo; then
628 printf "Intel"
629 fi
630}
631
632# get_host_ucode
633# Get the hosts' ucode file based on the /proc/cpuinfo
634get_ucode_file ()
635{
636 local family=`grep -E "cpu family" /proc/cpuinfo | head -1 | sed s/.*:\ //`
637 local model=`grep -E "model" /proc/cpuinfo |grep -v name | head -1 | sed s/.*:\ //`
638 local stepping=`grep -E "stepping" /proc/cpuinfo | head -1 | sed s/.*:\ //`
639
640 if [[ "$(get_cpu_vendor)" == "AMD" ]]; then
641 # If family greater or equal than 0x15
642 if [[ $family -ge 21 ]]; then
643 printf "microcode_amd_fam15h.bin"
644 else
645 printf "microcode_amd.bin"
646 fi
647 fi
648 if [[ "$(get_cpu_vendor)" == "Intel" ]]; then
649 # The /proc/cpuinfo are in decimal.
650 printf "%02x-%02x-%02x" ${family} ${model} ${stepping}
651 fi
652}
96c6f6f3
MC
653
654# Not every device in /dev/mapper should be examined.
655# If it is an LVM device, touch only devices which have /dev/VG/LV symlink.
656lvm_internal_dev() {
657 local dev_dm_dir=/sys/dev/block/$1/dm
658 [[ ! -f $dev_dm_dir/uuid || $(<$dev_dm_dir/uuid) != LVM-* ]] && return 1 # Not an LVM device
659 local DM_VG_NAME DM_LV_NAME DM_LV_LAYER
660 eval $(dmsetup splitname --nameprefixes --noheadings --rows "$(<$dev_dm_dir/name)" 2>/dev/null)
661 [[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] || return 0 # Better skip this!
662 [[ ${DM_LV_LAYER} ]] || [[ ! -L /dev/${DM_VG_NAME}/${DM_LV_NAME} ]]
663}
664
1cadc26f
HH
665btrfs_devs() {
666 local _mp="$1"
667 btrfs device usage "$_mp" \
668 | while read _dev _rest; do
669 str_starts "$_dev" "/" || continue
670 _dev=${_dev%,}
671 printf -- "%s\n" "$_dev"
672 done
673}