2008-12-18 00:57:43 +03:00
#!/bin/bash
#
2009-07-22 14:43:26 +04:00
# functions used by dracut and other tools.
2008-12-18 00:57:43 +03:00
#
2009-07-22 14:43:26 +04:00
# Copyright 2005-2009 Red Hat, Inc. All rights reserved.
2008-12-18 00:57:43 +03:00
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
2009-03-04 19:29:42 +03:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2008-12-18 00:57:43 +03:00
#
2012-07-19 15:35:50 +04:00
export LC_MESSAGES = C
2012-06-30 11:12:35 +04:00
2015-11-13 15:06:01 +03:00
# is_func <command>
# Check whether $1 is a function.
is_func( ) {
2021-02-25 11:43:35 +03:00
[ [ " $( type -t " $1 " ) " = = "function" ] ]
2015-11-13 15:06:01 +03:00
}
2012-06-18 14:52:39 +04:00
# Generic substring function. If $2 is in $1, return 0.
2021-02-25 11:43:35 +03:00
strstr( ) { [ [ $1 = = *" $2 " * ] ] ; }
Specify strstr tightly, add strglob/strglobin.
By convention, strstr should be a literal string match. Previously, it
would match as a glob pattern. Some code used that, so add new
functions strglob and strglobin to do what that code expects, and
specify them tightly too. strglob tests whether the glob pattern
matches the entire string (the name strglob is also used in the yorick
language, and that's what it does there), while strglobin tests whether
the glob pattern matches anywhere in the string.
Also tightens str_starts, str_ends, and str_replace to deal with
literal strings only. In a quick grep I did not find code that depended
on these functions matching globs.
Changes the call sites where strstr was used with glob patterns to use
strglobin or strglob as the intention seemed to be (or, in one case,
strstr with the * removed as it did not affect the result anyway).
2014-04-05 05:11:38 +04:00
# Generic glob matching function. If glob pattern $2 matches anywhere in $1, OK
2021-02-25 11:43:35 +03:00
strglobin( ) { [ [ $1 = = *$2 * ] ] ; }
Specify strstr tightly, add strglob/strglobin.
By convention, strstr should be a literal string match. Previously, it
would match as a glob pattern. Some code used that, so add new
functions strglob and strglobin to do what that code expects, and
specify them tightly too. strglob tests whether the glob pattern
matches the entire string (the name strglob is also used in the yorick
language, and that's what it does there), while strglobin tests whether
the glob pattern matches anywhere in the string.
Also tightens str_starts, str_ends, and str_replace to deal with
literal strings only. In a quick grep I did not find code that depended
on these functions matching globs.
Changes the call sites where strstr was used with glob patterns to use
strglobin or strglob as the intention seemed to be (or, in one case,
strstr with the * removed as it did not affect the result anyway).
2014-04-05 05:11:38 +04:00
# Generic glob matching function. If glob pattern $2 matches all of $1, OK
2021-02-12 15:26:09 +03:00
# shellcheck disable=SC2053
2021-02-25 11:43:35 +03:00
strglob( ) { [ [ $1 = = $2 ] ] ; }
2015-07-09 14:18:13 +03:00
# returns OK if $1 contains literal string $2 at the beginning, and isn't empty
str_starts( ) { [ " ${ 1 # " $2 " * } " != " $1 " ] ; }
# returns OK if $1 contains literal string $2 at the end, and isn't empty
str_ends( ) { [ " ${ 1 %* " $2 " } " != " $1 " ] ; }
2012-06-18 14:52:39 +04:00
2012-06-30 11:12:35 +04:00
# find a binary. If we were not passed the full path directly,
# search in the usual places to find the binary.
find_binary( ) {
Allow running on a cross-compiled rootfs
For the shell scripts, new environment variables were introduced.
dracutsysrootdir is the root directory, file existence checks use it.
DRACUT_LDCONFIG can override ldconfig with a different one that works
on the sysroot with foreign binaries.
DRACUT_LDD can override ldd with a different one that works
with foreign binaries.
DRACUT_TESTBIN can override /bin/sh. A cross-compiled sysroot
may use symlinks that are valid only when running on the target
so a real file must be provided that exist in the sysroot.
DRACUT_INSTALL now supports debugging dracut-install in itself
when run by dracut but without debugging the dracut scripts.
E.g. DRACUT_INSTALL="valgrind dracut-install or
DRACUT_INSTALL="dracut-install --debug".
DRACUT_COMPRESS_BZIP2, DRACUT_COMPRESS_LBZIP2, DRACUT_COMPRESS_LZMA,
DRACUT_COMPRESS_XZ, DRACUT_COMPRESS_GZIP, DRACUT_COMPRESS_PIGZ,
DRACUT_COMPRESS_LZOP, DRACUT_COMPRESS_ZSTD, DRACUT_COMPRESS_LZ4,
DRACUT_COMPRESS_CAT: All of the compression utilities may be
overridden, to support the native binaries in non-standard places.
DRACUT_ARCH overrides "uname -m".
SYSTEMD_VERSION overrides "systemd --version".
The dracut-install utility was overhauled to support sysroot via
a new option -r and fixes for clang-analyze. It supports
cross-compiler-ldd from
https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f
DRACUT_INSTALL_PATH was introduced so dracut-install can work with
a different PATH. In a cross-compiled environment (e.g. Yocto), PATH
points to natively built binaries that are not in the host's /bin,
/usr/bin, etc. dracut-install still needs plain /bin and /usr/bin
that are relative to the cross-compiled sysroot.
The hashmap pool allocate_tile/deallocate_tile code was removed
because clang-analyze showed errors in it. hashmap_copy was removed
because it wasn't used and clang-analyze showed errors in it.
DRACUT_INSTALL_LOG_TARGET and DRACUT_INSTALL_LOG_LEVEL were
introduced so dracut-install can use different settings from
DRACUT_LOG_TARGET and DRACUT_LOG_LEVEL.
Signed-off-by: Böszörményi Zoltán <zboszor@pr.hu>
2019-10-24 12:28:55 +03:00
local _delim
2020-05-25 19:02:05 +03:00
local _path
Allow running on a cross-compiled rootfs
For the shell scripts, new environment variables were introduced.
dracutsysrootdir is the root directory, file existence checks use it.
DRACUT_LDCONFIG can override ldconfig with a different one that works
on the sysroot with foreign binaries.
DRACUT_LDD can override ldd with a different one that works
with foreign binaries.
DRACUT_TESTBIN can override /bin/sh. A cross-compiled sysroot
may use symlinks that are valid only when running on the target
so a real file must be provided that exist in the sysroot.
DRACUT_INSTALL now supports debugging dracut-install in itself
when run by dracut but without debugging the dracut scripts.
E.g. DRACUT_INSTALL="valgrind dracut-install or
DRACUT_INSTALL="dracut-install --debug".
DRACUT_COMPRESS_BZIP2, DRACUT_COMPRESS_LBZIP2, DRACUT_COMPRESS_LZMA,
DRACUT_COMPRESS_XZ, DRACUT_COMPRESS_GZIP, DRACUT_COMPRESS_PIGZ,
DRACUT_COMPRESS_LZOP, DRACUT_COMPRESS_ZSTD, DRACUT_COMPRESS_LZ4,
DRACUT_COMPRESS_CAT: All of the compression utilities may be
overridden, to support the native binaries in non-standard places.
DRACUT_ARCH overrides "uname -m".
SYSTEMD_VERSION overrides "systemd --version".
The dracut-install utility was overhauled to support sysroot via
a new option -r and fixes for clang-analyze. It supports
cross-compiler-ldd from
https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f
DRACUT_INSTALL_PATH was introduced so dracut-install can work with
a different PATH. In a cross-compiled environment (e.g. Yocto), PATH
points to natively built binaries that are not in the host's /bin,
/usr/bin, etc. dracut-install still needs plain /bin and /usr/bin
that are relative to the cross-compiled sysroot.
The hashmap pool allocate_tile/deallocate_tile code was removed
because clang-analyze showed errors in it. hashmap_copy was removed
because it wasn't used and clang-analyze showed errors in it.
DRACUT_INSTALL_LOG_TARGET and DRACUT_INSTALL_LOG_LEVEL were
introduced so dracut-install can use different settings from
DRACUT_LOG_TARGET and DRACUT_LOG_LEVEL.
Signed-off-by: Böszörményi Zoltán <zboszor@pr.hu>
2019-10-24 12:28:55 +03:00
local l
local p
[ [ -z ${ 1 ##/* } ] ] || _delim = "/"
2021-02-25 11:43:35 +03:00
if [ [ $1 = = *.so* ] ] ; then
2021-02-12 15:26:09 +03:00
# shellcheck disable=SC2154
2021-02-25 11:42:54 +03:00
for l in $libdirs ; do
2020-05-25 19:02:05 +03:00
_path = " ${ l } ${ _delim } ${ 1 } "
2021-02-25 11:42:54 +03:00
if { $DRACUT_LDD " ${ dracutsysrootdir } ${ _path } " & > /dev/null; } ; then
2020-05-25 19:02:05 +03:00
printf "%s\n" " ${ _path } "
Allow running on a cross-compiled rootfs
For the shell scripts, new environment variables were introduced.
dracutsysrootdir is the root directory, file existence checks use it.
DRACUT_LDCONFIG can override ldconfig with a different one that works
on the sysroot with foreign binaries.
DRACUT_LDD can override ldd with a different one that works
with foreign binaries.
DRACUT_TESTBIN can override /bin/sh. A cross-compiled sysroot
may use symlinks that are valid only when running on the target
so a real file must be provided that exist in the sysroot.
DRACUT_INSTALL now supports debugging dracut-install in itself
when run by dracut but without debugging the dracut scripts.
E.g. DRACUT_INSTALL="valgrind dracut-install or
DRACUT_INSTALL="dracut-install --debug".
DRACUT_COMPRESS_BZIP2, DRACUT_COMPRESS_LBZIP2, DRACUT_COMPRESS_LZMA,
DRACUT_COMPRESS_XZ, DRACUT_COMPRESS_GZIP, DRACUT_COMPRESS_PIGZ,
DRACUT_COMPRESS_LZOP, DRACUT_COMPRESS_ZSTD, DRACUT_COMPRESS_LZ4,
DRACUT_COMPRESS_CAT: All of the compression utilities may be
overridden, to support the native binaries in non-standard places.
DRACUT_ARCH overrides "uname -m".
SYSTEMD_VERSION overrides "systemd --version".
The dracut-install utility was overhauled to support sysroot via
a new option -r and fixes for clang-analyze. It supports
cross-compiler-ldd from
https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f
DRACUT_INSTALL_PATH was introduced so dracut-install can work with
a different PATH. In a cross-compiled environment (e.g. Yocto), PATH
points to natively built binaries that are not in the host's /bin,
/usr/bin, etc. dracut-install still needs plain /bin and /usr/bin
that are relative to the cross-compiled sysroot.
The hashmap pool allocate_tile/deallocate_tile code was removed
because clang-analyze showed errors in it. hashmap_copy was removed
because it wasn't used and clang-analyze showed errors in it.
DRACUT_INSTALL_LOG_TARGET and DRACUT_INSTALL_LOG_LEVEL were
introduced so dracut-install can use different settings from
DRACUT_LOG_TARGET and DRACUT_LOG_LEVEL.
Signed-off-by: Böszörményi Zoltán <zboszor@pr.hu>
2019-10-24 12:28:55 +03:00
return 0
fi
done
2020-05-25 19:02:05 +03:00
_path = " ${ _delim } ${ 1 } "
2021-02-25 11:42:54 +03:00
if { $DRACUT_LDD " ${ dracutsysrootdir } ${ _path } " & > /dev/null; } ; then
2020-05-25 19:02:05 +03:00
printf "%s\n" " ${ _path } "
2012-06-30 11:12:35 +04:00
return 0
fi
fi
2021-02-25 11:43:35 +03:00
if [ [ $1 = = */* ] ] ; then
2020-05-25 19:02:05 +03:00
_path = " ${ _delim } ${ 1 } "
if [ [ -L ${ dracutsysrootdir } ${ _path } ] ] || [ [ -x ${ dracutsysrootdir } ${ _path } ] ] ; then
printf "%s\n" " ${ _path } "
Allow running on a cross-compiled rootfs
For the shell scripts, new environment variables were introduced.
dracutsysrootdir is the root directory, file existence checks use it.
DRACUT_LDCONFIG can override ldconfig with a different one that works
on the sysroot with foreign binaries.
DRACUT_LDD can override ldd with a different one that works
with foreign binaries.
DRACUT_TESTBIN can override /bin/sh. A cross-compiled sysroot
may use symlinks that are valid only when running on the target
so a real file must be provided that exist in the sysroot.
DRACUT_INSTALL now supports debugging dracut-install in itself
when run by dracut but without debugging the dracut scripts.
E.g. DRACUT_INSTALL="valgrind dracut-install or
DRACUT_INSTALL="dracut-install --debug".
DRACUT_COMPRESS_BZIP2, DRACUT_COMPRESS_LBZIP2, DRACUT_COMPRESS_LZMA,
DRACUT_COMPRESS_XZ, DRACUT_COMPRESS_GZIP, DRACUT_COMPRESS_PIGZ,
DRACUT_COMPRESS_LZOP, DRACUT_COMPRESS_ZSTD, DRACUT_COMPRESS_LZ4,
DRACUT_COMPRESS_CAT: All of the compression utilities may be
overridden, to support the native binaries in non-standard places.
DRACUT_ARCH overrides "uname -m".
SYSTEMD_VERSION overrides "systemd --version".
The dracut-install utility was overhauled to support sysroot via
a new option -r and fixes for clang-analyze. It supports
cross-compiler-ldd from
https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f
DRACUT_INSTALL_PATH was introduced so dracut-install can work with
a different PATH. In a cross-compiled environment (e.g. Yocto), PATH
points to natively built binaries that are not in the host's /bin,
/usr/bin, etc. dracut-install still needs plain /bin and /usr/bin
that are relative to the cross-compiled sysroot.
The hashmap pool allocate_tile/deallocate_tile code was removed
because clang-analyze showed errors in it. hashmap_copy was removed
because it wasn't used and clang-analyze showed errors in it.
DRACUT_INSTALL_LOG_TARGET and DRACUT_INSTALL_LOG_LEVEL were
introduced so dracut-install can use different settings from
DRACUT_LOG_TARGET and DRACUT_LOG_LEVEL.
Signed-off-by: Böszörményi Zoltán <zboszor@pr.hu>
2019-10-24 12:28:55 +03:00
return 0
fi
fi
2021-02-25 11:42:54 +03:00
for p in $DRACUT_PATH ; do
2020-05-25 19:02:05 +03:00
_path = " ${ p } ${ _delim } ${ 1 } "
2021-02-25 11:42:54 +03:00
if [ [ -L ${ dracutsysrootdir } ${ _path } ] ] || [ [ -x ${ dracutsysrootdir } ${ _path } ] ] ; then
2020-05-25 19:02:05 +03:00
printf "%s\n" " ${ _path } "
Allow running on a cross-compiled rootfs
For the shell scripts, new environment variables were introduced.
dracutsysrootdir is the root directory, file existence checks use it.
DRACUT_LDCONFIG can override ldconfig with a different one that works
on the sysroot with foreign binaries.
DRACUT_LDD can override ldd with a different one that works
with foreign binaries.
DRACUT_TESTBIN can override /bin/sh. A cross-compiled sysroot
may use symlinks that are valid only when running on the target
so a real file must be provided that exist in the sysroot.
DRACUT_INSTALL now supports debugging dracut-install in itself
when run by dracut but without debugging the dracut scripts.
E.g. DRACUT_INSTALL="valgrind dracut-install or
DRACUT_INSTALL="dracut-install --debug".
DRACUT_COMPRESS_BZIP2, DRACUT_COMPRESS_LBZIP2, DRACUT_COMPRESS_LZMA,
DRACUT_COMPRESS_XZ, DRACUT_COMPRESS_GZIP, DRACUT_COMPRESS_PIGZ,
DRACUT_COMPRESS_LZOP, DRACUT_COMPRESS_ZSTD, DRACUT_COMPRESS_LZ4,
DRACUT_COMPRESS_CAT: All of the compression utilities may be
overridden, to support the native binaries in non-standard places.
DRACUT_ARCH overrides "uname -m".
SYSTEMD_VERSION overrides "systemd --version".
The dracut-install utility was overhauled to support sysroot via
a new option -r and fixes for clang-analyze. It supports
cross-compiler-ldd from
https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f
DRACUT_INSTALL_PATH was introduced so dracut-install can work with
a different PATH. In a cross-compiled environment (e.g. Yocto), PATH
points to natively built binaries that are not in the host's /bin,
/usr/bin, etc. dracut-install still needs plain /bin and /usr/bin
that are relative to the cross-compiled sysroot.
The hashmap pool allocate_tile/deallocate_tile code was removed
because clang-analyze showed errors in it. hashmap_copy was removed
because it wasn't used and clang-analyze showed errors in it.
DRACUT_INSTALL_LOG_TARGET and DRACUT_INSTALL_LOG_LEVEL were
introduced so dracut-install can use different settings from
DRACUT_LOG_TARGET and DRACUT_LOG_LEVEL.
Signed-off-by: Böszörményi Zoltán <zboszor@pr.hu>
2019-10-24 12:28:55 +03:00
return 0
fi
done
2012-06-30 11:12:35 +04:00
2021-02-25 11:43:35 +03:00
[ [ -n $dracutsysrootdir ] ] && return 1
2013-07-04 14:29:59 +04:00
type -P " ${ 1 ##*/ } "
2012-06-30 11:12:35 +04:00
}
2021-02-25 11:42:54 +03:00
ldconfig_paths( ) {
$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
2013-08-13 22:00:55 +04:00
}
2013-08-14 14:54:33 +04:00
# Version comparision function. Assumes Linux style version scheme.
# $1 = version a
# $2 = comparision op (gt, ge, eq, le, lt, ne)
# $3 = version b
vercmp( ) {
2021-02-12 15:26:09 +03:00
local _n1
2021-03-26 14:30:15 +03:00
read -r -a _n1 <<< " ${ 1 //./ } "
2021-02-12 15:26:09 +03:00
local _op = $2
local _n2
2021-03-26 14:30:15 +03:00
read -r -a _n2 <<< " ${ 3 //./ } "
2021-02-12 15:26:09 +03:00
local _i _res
2013-08-14 14:54:33 +04:00
2021-02-25 11:42:54 +03:00
for ( ( _i = 0; ; _i++) ) ; do
if [ [ ! ${ _n1 [_i] } ${ _n2 [_i] } ] ] ; then
_res = 0
elif ( ( ${ _n1 [_i] :- 0 } > ${ _n2 [_i] :- 0 } ) ) ; then
_res = 1
elif ( ( ${ _n1 [_i] :- 0 } < ${ _n2 [_i] :- 0 } ) ) ; then
_res = 2
else
continue
2013-08-14 14:54:33 +04:00
fi
break
done
case $_op in
2021-02-25 11:42:54 +03:00
gt) ( ( _res = = 1) ) ; ;
ge) ( ( _res != 2) ) ; ;
eq) ( ( _res = = 0) ) ; ;
le) ( ( _res != 1) ) ; ;
lt) ( ( _res = = 2) ) ; ;
ne) ( ( _res != 0) ) ; ;
2013-08-14 14:54:33 +04:00
esac
}
2010-07-01 23:17:37 +04:00
# Create all subdirectories for given path without creating the last element.
# $1 = path
2013-07-04 14:29:59 +04:00
mksubdirs( ) {
2021-02-12 15:26:09 +03:00
# shellcheck disable=SC2174
2013-07-04 14:29:59 +04:00
[ [ -e ${ 1 %/* } ] ] || mkdir -m 0755 -p -- " ${ 1 %/* } "
}
2010-07-01 23:17:37 +04:00
# Function prints global variables in format name=value line by line.
# $@ = list of global variables' name
print_vars( ) {
2011-05-12 13:03:30 +04:00
local _var _value
2010-07-01 23:17:37 +04:00
2021-02-25 11:42:54 +03:00
for _var in " $@ " ; do
2014-05-20 13:27:42 +04:00
eval printf -v _value "%s" \" " \$ $_var " \"
2013-07-04 14:29:59 +04:00
[ [ ${ _value } ] ] && printf '%s="%s"\n' " $_var " " $_value "
2010-07-01 23:17:37 +04:00
done
}
2012-02-16 14:49:19 +04:00
# normalize_path <path>
# Prints the normalized path, where it removes any duplicated
# and trailing slashes.
# Example:
# $ normalize_path ///test/test//
# /test/test
2011-07-25 16:28:55 +04:00
normalize_path( ) {
2021-03-26 14:30:15 +03:00
# shellcheck disable=SC2064
trap " $( shopt -p extglob) " RETURN
2011-10-08 02:20:50 +04:00
shopt -q -s extglob
2021-03-26 14:30:15 +03:00
local p = ${ 1 //+( \/ )// }
printf "%s\n" " ${ p %/ } "
2011-07-25 16:28:55 +04:00
}
2011-07-25 12:25:44 +04:00
2012-02-16 14:49:19 +04:00
# convert_abs_rel <from> <to>
# Prints the relative path, when creating a symlink to <to> from <from>.
# Example:
# $ convert_abs_rel /usr/bin/test /bin/test-2
# ../../bin/test-2
# $ ln -s $(convert_abs_rel /usr/bin/test /bin/test-2) /usr/bin/test
2011-07-25 12:25:44 +04:00
convert_abs_rel( ) {
2012-02-22 16:04:37 +04:00
local __current __absolute __abssize __cursize __newpath
2011-10-08 02:20:50 +04:00
local -i __i __level
2011-07-25 12:25:44 +04:00
2011-10-08 02:20:50 +04:00
set -- " $( normalize_path " $1 " ) " " $( normalize_path " $2 " ) "
2011-10-08 00:23:49 +04:00
# corner case #1 - self looping link
2021-02-25 11:43:35 +03:00
[ [ $1 = = " $2 " ] ] && {
2021-02-25 11:42:54 +03:00
printf "%s\n" " ${ 1 ##*/ } "
return
}
2011-10-08 00:23:49 +04:00
# corner case #2 - own dir link
2021-02-25 11:43:35 +03:00
[ [ ${ 1 %/* } = = " $2 " ] ] && {
2021-02-25 11:42:54 +03:00
printf ".\n"
return
}
2011-10-08 00:23:49 +04:00
2021-03-26 14:30:15 +03:00
IFS = / read -r -a __current <<< " $1 "
IFS = / read -r -a __absolute <<< " $2 "
2011-07-25 12:25:44 +04:00
__abssize = ${# __absolute [@] }
__cursize = ${# __current [@] }
2021-02-25 11:43:35 +03:00
while [ [ ${ __absolute [__level] } = = " ${ __current [__level] } " ] ] ; do
2021-02-25 11:42:54 +03:00
( ( __level++) )
if ( ( __level > __abssize || __level > __cursize) ) ; then
2011-07-25 12:25:44 +04:00
break
fi
done
2021-02-25 11:42:54 +03:00
for ( ( __i = __level; __i < __cursize - 1; __i++) ) ; do
if ( ( __i > __level) ) ; then
2011-07-25 12:25:44 +04:00
__newpath = $__newpath "/"
fi
__newpath = $__newpath ".."
done
2021-02-25 11:42:54 +03:00
for ( ( __i = __level; __i < __abssize; __i++) ) ; do
if [ [ -n $__newpath ] ] ; then
2011-07-25 12:25:44 +04:00
__newpath = $__newpath "/"
fi
__newpath = $__newpath ${ __absolute [__i] }
done
2021-02-12 15:26:09 +03:00
printf -- "%s\n" " $__newpath "
2011-07-25 12:25:44 +04:00
}
2012-02-16 14:49:19 +04:00
# get_fs_env <device>
2013-08-15 13:14:14 +04:00
# Get and the ID_FS_TYPE variable from udev for a device.
2012-02-16 14:49:19 +04:00
# Example:
2013-08-15 13:14:14 +04:00
# $ get_fs_env /dev/sda2
2012-02-16 14:49:19 +04:00
# ext4
2009-08-22 21:04:11 +04:00
get_fs_env( ) {
2010-08-06 15:54:34 +04:00
[ [ $1 ] ] || return
2011-05-12 13:03:30 +04:00
unset ID_FS_TYPE
2013-08-15 12:44:20 +04:00
ID_FS_TYPE = $( blkid -u filesystem -o export -- " $1 " \
2021-03-26 14:30:15 +03:00
| while read -r line || [ -n " $line " ] ; do
if [ [ $line = = "TYPE=" * ] ] ; then
2021-02-25 11:42:54 +03:00
printf "%s" " ${ line #TYPE= } "
exit 0
2013-08-15 12:44:20 +04:00
fi
2021-02-25 11:42:54 +03:00
done )
2013-08-15 12:44:20 +04:00
if [ [ $ID_FS_TYPE ] ] ; then
printf "%s" " $ID_FS_TYPE "
return 0
2010-08-06 15:54:34 +04:00
fi
2012-03-29 16:56:46 +04:00
return 1
}
2009-08-22 21:04:11 +04:00
2012-02-16 14:49:19 +04:00
# get_maj_min <device>
# Prints the major and minor of a device node.
# Example:
# $ get_maj_min /dev/sda2
# 8:2
2011-12-08 13:43:29 +04:00
get_maj_min( ) {
2019-10-17 02:07:37 +03:00
local _majmin
2021-02-25 11:42:54 +03:00
_majmin = " $( stat -L -c '%t:%T' " $1 " 2> /dev/null) "
2013-07-31 13:00:29 +04:00
printf "%s" " $(( 0 x${ _majmin % : * } )) : $(( 0 x${ _majmin #* : } )) "
2011-12-08 13:43:29 +04:00
}
2013-08-26 16:04:56 +04:00
# get_devpath_block <device>
# get the DEVPATH in /sys of a block device
get_devpath_block( ) {
2013-08-27 13:34:39 +04:00
local _majmin _i
2013-08-26 16:04:56 +04:00
_majmin = $( get_maj_min " $1 " )
for _i in /sys/block/*/dev /sys/block/*/*/dev; do
2021-02-25 11:43:35 +03:00
[ [ -e $_i ] ] || continue
if [ [ $_majmin = = " $( < " $_i " ) " ] ] ; then
2013-08-26 16:04:56 +04:00
printf "%s" " ${ _i %/dev } "
return 0
fi
done
return 1
}
2013-08-15 12:44:20 +04:00
# get a persistent path from a device
get_persistent_dev( ) {
2016-10-05 14:54:26 +03:00
local i _tmp _dev _pol
2013-08-15 12:44:20 +04:00
_dev = $( get_maj_min " $1 " )
[ -z " $_dev " ] && return
2021-02-25 11:43:35 +03:00
if [ [ -n $persistent_policy ] ] ; then
2021-02-25 11:42:54 +03:00
_pol = " /dev/disk/ ${ persistent_policy } /* "
2016-10-05 14:54:26 +03:00
else
2021-02-25 11:42:54 +03:00
_pol =
2016-10-05 14:54:26 +03:00
fi
2013-08-16 13:52:07 +04:00
for i in \
2016-10-05 14:54:26 +03:00
$_pol \
2013-08-16 13:52:07 +04:00
/dev/mapper/* \
/dev/disk/by-uuid/* \
/dev/disk/by-label/* \
/dev/disk/by-partuuid/* \
/dev/disk/by-partlabel/* \
/dev/disk/by-id/* \
2021-02-25 11:42:54 +03:00
/dev/disk/by-path/*; do
2021-02-25 11:43:35 +03:00
[ [ -e $i ] ] || continue
2013-08-15 17:52:22 +04:00
[ [ $i = = /dev/mapper/control ] ] && continue
2013-08-15 12:44:20 +04:00
[ [ $i = = /dev/mapper/mpath* ] ] && continue
_tmp = $( get_maj_min " $i " )
if [ " $_tmp " = " $_dev " ] ; then
printf -- "%s" " $i "
return
fi
done
2014-08-15 14:36:04 +04:00
printf -- "%s" " $1 "
2013-08-15 12:44:20 +04:00
}
2013-08-20 18:01:10 +04:00
expand_persistent_dev( ) {
local _dev = $1
case " $_dev " in
LABEL = *)
_dev = " /dev/disk/by-label/ ${ _dev #LABEL= } "
; ;
UUID = *)
_dev = " ${ _dev #UUID= } "
2013-08-22 12:52:49 +04:00
_dev = " ${ _dev ,, } "
2013-08-20 18:01:10 +04:00
_dev = " /dev/disk/by-uuid/ ${ _dev } "
; ;
PARTUUID = *)
_dev = " ${ _dev #PARTUUID= } "
2013-08-22 12:52:49 +04:00
_dev = " ${ _dev ,, } "
2013-08-20 18:01:10 +04:00
_dev = " /dev/disk/by-partuuid/ ${ _dev } "
; ;
PARTLABEL = *)
_dev = " /dev/disk/by-partlabel/ ${ _dev #PARTLABEL= } "
; ;
esac
printf "%s" " $_dev "
}
2013-08-16 13:52:07 +04:00
shorten_persistent_dev( ) {
2013-08-20 18:01:10 +04:00
local _dev = " $1 "
case " $_dev " in
2013-08-16 13:52:07 +04:00
/dev/disk/by-uuid/*)
2021-02-25 11:42:54 +03:00
printf "%s" " UUID= ${ _dev ##*/ } "
; ;
2013-08-16 13:52:07 +04:00
/dev/disk/by-label/*)
2021-02-25 11:42:54 +03:00
printf "%s" " LABEL= ${ _dev ##*/ } "
; ;
2013-08-16 13:52:07 +04:00
/dev/disk/by-partuuid/*)
2021-02-25 11:42:54 +03:00
printf "%s" " PARTUUID= ${ _dev ##*/ } "
; ;
2013-08-16 13:52:07 +04:00
/dev/disk/by-partlabel/*)
2021-02-25 11:42:54 +03:00
printf "%s" " PARTLABEL= ${ _dev ##*/ } "
; ;
2013-08-16 13:52:07 +04:00
*)
2021-02-25 11:42:54 +03:00
printf "%s" " $_dev "
; ;
2013-08-16 13:52:07 +04:00
esac
}
2012-02-16 14:49:19 +04:00
# find_block_device <mountpoint>
# Prints the major and minor number of the block device
# for a given mountpoint.
# Unless $use_fstab is set to "yes" the functions
# uses /proc/self/mountinfo as the primary source of the
# information and only falls back to /etc/fstab, if the mountpoint
# is not found there.
# Example:
# $ find_block_device /usr
# 8:4
2009-08-20 07:20:12 +04:00
find_block_device( ) {
2015-08-24 13:02:10 +03:00
local _dev _majmin _find_mpt
2013-01-23 17:10:15 +04:00
_find_mpt = " $1 "
2021-02-12 15:26:09 +03:00
2011-03-25 17:56:46 +03:00
if [ [ $use_fstab != yes ] ] ; then
2013-04-09 12:47:39 +04:00
[ [ -d $_find_mpt /. ] ]
2021-02-25 11:42:54 +03:00
findmnt -e -v -n -o 'MAJ:MIN,SOURCE' --target " $_find_mpt " | {
2021-03-26 14:30:15 +03:00
while read -r _majmin _dev || [ -n " $_dev " ] ; do
2013-07-31 13:00:29 +04:00
if [ [ -b $_dev ] ] ; then
if ! [ [ $_majmin ] ] || [ [ $_majmin = = 0:* ] ] ; then
2021-03-26 14:30:15 +03:00
_majmin = $( get_maj_min " $_dev " )
2013-07-31 13:00:29 +04:00
fi
if [ [ $_majmin ] ] ; then
2013-08-15 14:22:26 +04:00
printf "%s\n" " $_majmin "
2013-07-31 13:00:29 +04:00
else
2013-08-15 14:22:26 +04:00
printf "%s\n" " $_dev "
2013-07-31 13:00:29 +04:00
fi
return 0
fi
2021-02-25 11:43:35 +03:00
if [ [ $_dev = = *:* ] ] ; then
2013-08-15 14:22:26 +04:00
printf "%s\n" " $_dev "
2013-07-31 13:00:29 +04:00
return 0
fi
2021-02-25 11:42:54 +03:00
done
return 1
} && return 0
2013-07-31 13:00:29 +04:00
fi
# fall back to /etc/fstab
2021-02-25 11:42:54 +03:00
findmnt -e --fstab -v -n -o 'MAJ:MIN,SOURCE' --target " $_find_mpt " | {
2021-03-26 14:30:15 +03:00
while read -r _majmin _dev || [ -n " $_dev " ] ; do
2013-07-31 13:00:29 +04:00
if ! [ [ $_dev ] ] ; then
_dev = " $_majmin "
unset _majmin
fi
2013-04-09 12:47:39 +04:00
if [ [ -b $_dev ] ] ; then
2021-03-26 14:30:15 +03:00
[ [ $_majmin ] ] || _majmin = $( get_maj_min " $_dev " )
2013-04-09 12:47:39 +04:00
if [ [ $_majmin ] ] ; then
2013-08-15 14:22:26 +04:00
printf "%s\n" " $_majmin "
2013-04-09 12:47:39 +04:00
else
2013-08-15 14:22:26 +04:00
printf "%s\n" " $_dev "
2013-04-09 12:47:39 +04:00
fi
return 0
fi
2021-02-25 11:43:35 +03:00
if [ [ $_dev = = *:* ] ] ; then
2013-08-15 14:22:26 +04:00
printf "%s\n" " $_dev "
2013-04-09 12:47:39 +04:00
return 0
2010-09-10 17:23:06 +04:00
fi
2021-02-25 11:42:54 +03:00
done
return 1
} && return 0
2011-03-25 17:56:46 +03:00
return 1
2009-08-16 19:29:21 +04:00
}
2013-04-09 12:47:39 +04:00
# find_mp_fstype <mountpoint>
# Echo the filesystem type for a given mountpoint.
2012-02-16 14:49:19 +04:00
# /proc/self/mountinfo is taken as the primary source of information
# and /etc/fstab is used as a fallback.
# No newline is appended!
# Example:
2013-04-09 12:47:39 +04:00
# $ find_mp_fstype /;echo
2012-02-16 14:49:19 +04:00
# ext4
2013-04-09 12:47:39 +04:00
find_mp_fstype( ) {
local _fs
2011-12-08 13:25:58 +04:00
2013-04-09 12:47:39 +04:00
if [ [ $use_fstab != yes ] ] ; then
2021-02-25 11:42:54 +03:00
findmnt -e -v -n -o 'FSTYPE' --target " $1 " | {
2021-03-26 14:30:15 +03:00
while read -r _fs || [ -n " $_fs " ] ; do
2013-07-31 13:00:29 +04:00
[ [ $_fs ] ] || continue
2021-02-25 11:43:35 +03:00
[ [ $_fs = = "autofs" ] ] && continue
2013-08-15 14:22:26 +04:00
printf "%s" " $_fs "
2013-07-31 13:00:29 +04:00
return 0
2021-02-25 11:42:54 +03:00
done
return 1
} && return 0
2013-07-31 13:00:29 +04:00
fi
2021-02-25 11:42:54 +03:00
findmnt --fstab -e -v -n -o 'FSTYPE' --target " $1 " | {
2021-03-26 14:30:15 +03:00
while read -r _fs || [ -n " $_fs " ] ; do
2013-04-09 12:47:39 +04:00
[ [ $_fs ] ] || continue
2021-02-25 11:43:35 +03:00
[ [ $_fs = = "autofs" ] ] && continue
2013-08-15 14:22:26 +04:00
printf "%s" " $_fs "
2013-04-09 12:47:39 +04:00
return 0
2021-02-25 11:42:54 +03:00
done
return 1
} && return 0
2011-12-08 13:25:58 +04:00
return 1
}
2013-04-09 12:47:39 +04:00
# find_dev_fstype <device>
# Echo the filesystem type for a given device.
2012-07-26 19:00:07 +04:00
# /proc/self/mountinfo is taken as the primary source of information
# and /etc/fstab is used as a fallback.
# No newline is appended!
# Example:
2013-04-09 12:47:39 +04:00
# $ find_dev_fstype /dev/sda2;echo
2012-07-26 19:00:07 +04:00
# ext4
2013-04-09 12:47:39 +04:00
find_dev_fstype( ) {
2013-06-24 14:47:01 +04:00
local _find_dev _fs
2013-04-09 12:47:39 +04:00
_find_dev = " $1 "
2021-02-25 11:43:35 +03:00
if ! [ [ $_find_dev = = /dev* ] ] ; then
2013-08-05 13:25:45 +04:00
[ [ -b " /dev/block/ $_find_dev " ] ] && _find_dev = " /dev/block/ $_find_dev "
fi
2013-06-24 14:47:01 +04:00
if [ [ $use_fstab != yes ] ] ; then
2021-02-25 11:42:54 +03:00
findmnt -e -v -n -o 'FSTYPE' --source " $_find_dev " | {
2021-03-26 14:30:15 +03:00
while read -r _fs || [ -n " $_fs " ] ; do
2013-07-31 13:00:29 +04:00
[ [ $_fs ] ] || continue
2021-02-25 11:43:35 +03:00
[ [ $_fs = = "autofs" ] ] && continue
2013-08-15 14:22:26 +04:00
printf "%s" " $_fs "
2013-07-31 13:00:29 +04:00
return 0
2021-02-25 11:42:54 +03:00
done
return 1
} && return 0
2013-07-31 13:00:29 +04:00
fi
2021-02-25 11:42:54 +03:00
findmnt --fstab -e -v -n -o 'FSTYPE' --source " $_find_dev " | {
2021-03-26 14:30:15 +03:00
while read -r _fs || [ -n " $_fs " ] ; do
2013-06-24 14:47:01 +04:00
[ [ $_fs ] ] || continue
2021-02-25 11:43:35 +03:00
[ [ $_fs = = "autofs" ] ] && continue
2013-08-15 14:22:26 +04:00
printf "%s" " $_fs "
2013-06-24 14:47:01 +04:00
return 0
2021-02-25 11:42:54 +03:00
done
return 1
} && return 0
2013-06-24 14:47:01 +04:00
return 1
2013-08-15 13:14:14 +04:00
}
2013-06-24 14:47:01 +04:00
2013-08-15 14:23:04 +04:00
# find_mp_fsopts <mountpoint>
# Echo the filesystem options for a given mountpoint.
# /proc/self/mountinfo is taken as the primary source of information
# and /etc/fstab is used as a fallback.
# No newline is appended!
# Example:
# $ find_mp_fsopts /;echo
# rw,relatime,discard,data=ordered
find_mp_fsopts( ) {
if [ [ $use_fstab != yes ] ] ; then
2021-02-25 11:42:54 +03:00
findmnt -e -v -n -o 'OPTIONS' --target " $1 " 2> /dev/null && return 0
2013-08-15 14:23:04 +04:00
fi
findmnt --fstab -e -v -n -o 'OPTIONS' --target " $1 "
}
2013-08-15 13:14:14 +04:00
# find_dev_fsopts <device>
# Echo the filesystem options for a given device.
# /proc/self/mountinfo is taken as the primary source of information
# and /etc/fstab is used as a fallback.
2021-02-12 15:26:09 +03:00
# if `use_fstab == yes`, then only `/etc/fstab` is used.
#
2013-08-15 13:14:14 +04:00
# Example:
# $ find_dev_fsopts /dev/sda2
# rw,relatime,discard,data=ordered
find_dev_fsopts( ) {
2021-02-12 15:26:09 +03:00
local _find_dev
2013-08-15 13:14:14 +04:00
_find_dev = " $1 "
2021-02-25 11:43:35 +03:00
if ! [ [ $_find_dev = = /dev* ] ] ; then
2013-08-15 13:14:14 +04:00
[ [ -b " /dev/block/ $_find_dev " ] ] && _find_dev = " /dev/block/ $_find_dev "
fi
if [ [ $use_fstab != yes ] ] ; then
2021-02-25 11:42:54 +03:00
findmnt -e -v -n -o 'OPTIONS' --source " $_find_dev " 2> /dev/null && return 0
2013-08-15 13:14:14 +04:00
fi
findmnt --fstab -e -v -n -o 'OPTIONS' --source " $_find_dev "
2012-07-26 19:00:07 +04:00
}
2011-12-08 13:25:58 +04:00
# finds the major:minor of the block device backing the root filesystem.
2009-08-20 07:20:12 +04:00
find_root_block_device( ) { find_block_device /; }
2012-02-16 14:49:19 +04:00
# for_each_host_dev_fs <func>
2013-03-11 19:32:16 +04:00
# Execute "<func> <dev> <filesystem>" for every "<dev> <fs>" pair found
2012-02-16 14:49:19 +04:00
# in ${host_fs_types[@]}
2021-02-25 11:42:54 +03:00
for_each_host_dev_fs( ) {
2011-12-08 13:43:29 +04:00
local _func = " $1 "
2011-12-20 10:09:59 +04:00
local _dev
2012-02-22 22:06:00 +04:00
local _ret = 1
2013-03-18 11:43:23 +04:00
2017-12-04 12:24:11 +03:00
[ [ " ${# host_fs_types [@] } " ] ] || return 2
2013-03-11 19:32:16 +04:00
for _dev in " ${ !host_fs_types[@] } " ; do
$_func " $_dev " " ${ host_fs_types [ $_dev ] } " && _ret = 0
2011-12-08 13:43:29 +04:00
done
2012-02-22 22:06:00 +04:00
return $_ret
2011-12-08 13:43:29 +04:00
}
2021-02-25 11:42:54 +03:00
host_fs_all( ) {
2013-08-15 14:22:26 +04:00
printf "%s\n" " ${ host_fs_types [@] } "
2013-03-18 11:43:23 +04:00
}
2009-08-16 19:29:21 +04:00
# Walk all the slave relationships for a given block device.
# Stop when our helper function returns success
# $1 = function to call on every found block device
# $2 = block device in major:minor format
2011-03-25 17:56:46 +03:00
check_block_and_slaves( ) {
2011-05-12 13:03:30 +04:00
local _x
2009-08-16 19:29:21 +04:00
[ [ -b /dev/block/$2 ] ] || return 1 # Not a block device? So sorry.
2021-03-26 14:30:15 +03:00
if ! lvm_internal_dev " $2 " ; then " $1 " " $2 " && return ; fi
2009-08-31 16:58:44 +04:00
check_vol_slaves " $@ " && return 0
2018-02-19 11:03:02 +03:00
if [ [ -f /sys/dev/block/$2 /../dev ] ] && [ [ /sys/dev/block/$2 /../subsystem -ef /sys/class/block ] ] ; then
2021-03-26 14:30:15 +03:00
check_block_and_slaves " $1 " " $( < " /sys/dev/block/ $2 /../dev " ) " && return 0
2010-05-19 10:13:12 +04:00
fi
2021-03-26 14:30:15 +03:00
for _x in /sys/dev/block/" $2 " /slaves/*; do
2018-02-19 11:03:02 +03:00
[ [ -f $_x /dev ] ] || continue
[ [ $_x /subsystem -ef /sys/class/block ] ] || continue
2021-03-26 14:30:15 +03:00
check_block_and_slaves " $1 " " $( < " $_x /dev " ) " && return 0
2009-08-16 19:29:21 +04:00
done
return 1
}
2012-08-23 07:02:23 +04:00
check_block_and_slaves_all( ) {
local _x _ret = 1
[ [ -b /dev/block/$2 ] ] || return 1 # Not a block device? So sorry.
2021-03-26 14:30:15 +03:00
if ! lvm_internal_dev " $2 " && " $1 " " $2 " ; then
2013-07-31 13:00:29 +04:00
_ret = 0
2012-08-23 07:02:23 +04:00
fi
2016-08-09 16:26:04 +03:00
check_vol_slaves_all " $@ " && return 0
2018-02-19 11:03:02 +03:00
if [ [ -f /sys/dev/block/$2 /../dev ] ] && [ [ /sys/dev/block/$2 /../subsystem -ef /sys/class/block ] ] ; then
2021-03-26 14:30:15 +03:00
check_block_and_slaves_all " $1 " " $( < " /sys/dev/block/ $2 /../dev " ) " && _ret = 0
2012-08-23 07:02:23 +04:00
fi
2021-03-26 14:30:15 +03:00
for _x in /sys/dev/block/" $2 " /slaves/*; do
2018-02-19 11:03:02 +03:00
[ [ -f $_x /dev ] ] || continue
[ [ $_x /subsystem -ef /sys/class/block ] ] || continue
2021-03-26 14:30:15 +03:00
check_block_and_slaves_all " $1 " " $( < " $_x /dev " ) " && _ret = 0
2012-08-23 07:02:23 +04:00
done
return $_ret
}
# for_each_host_dev_and_slaves <func>
# Execute "<func> <dev>" for every "<dev>" found
# in ${host_devs[@]} and their slaves
2021-02-25 11:42:54 +03:00
for_each_host_dev_and_slaves_all( ) {
2012-08-23 07:02:23 +04:00
local _func = " $1 "
local _dev
local _ret = 1
2013-03-18 11:43:23 +04:00
2021-02-12 15:26:09 +03:00
[ [ " ${ host_devs [*] } " ] ] || return 2
2013-03-18 11:43:23 +04:00
2015-07-09 16:27:44 +03:00
for _dev in " ${ host_devs [@] } " ; do
2021-02-25 11:43:35 +03:00
[ [ -b $_dev ] ] || continue
2021-03-26 14:30:15 +03:00
if check_block_and_slaves_all " $_func " " $( get_maj_min " $_dev " ) " ; then
2013-07-31 13:00:29 +04:00
_ret = 0
2012-08-23 07:02:23 +04:00
fi
done
return $_ret
}
2021-02-25 11:42:54 +03:00
for_each_host_dev_and_slaves( ) {
2012-08-23 07:02:23 +04:00
local _func = " $1 "
local _dev
2013-03-18 11:43:23 +04:00
2021-02-12 15:26:09 +03:00
[ [ " ${ host_devs [*] } " ] ] || return 2
2013-03-18 11:43:23 +04:00
2015-07-09 16:27:44 +03:00
for _dev in " ${ host_devs [@] } " ; do
2021-02-25 11:43:35 +03:00
[ [ -b $_dev ] ] || continue
2021-03-26 14:30:15 +03:00
check_block_and_slaves " $_func " " $( get_maj_min " $_dev " ) " && return 0
2012-08-23 07:02:23 +04:00
done
return 1
}
2009-08-31 16:58:44 +04:00
# ugly workaround for the lvm design
# There is no volume group device,
# so, there are no slave devices for volume groups.
# Logical volumes only have the slave devices they really live on,
# but you cannot create the logical volume without the volume group.
2009-10-29 12:29:58 +03:00
# And the volume group might be bigger than the devices the LV needs.
2009-08-31 16:58:44 +04:00
check_vol_slaves( ) {
2021-03-26 14:30:15 +03:00
local _vg _pv _dm _majmin
2018-01-15 17:44:46 +03:00
_majmin = " $2 "
_dm = /sys/dev/block/$_majmin /dm
2021-03-26 14:30:15 +03:00
[ [ -f $_dm /uuid && $( < " $_dm " /uuid) = ~ LVM-* ] ] || return 1
_vg = $( dmsetup splitname --noheadings -o vg_name " $( < " $_dm /name " ) " )
2018-01-15 17:44:46 +03:00
# strip space
_vg = " ${ _vg //[[ : space : ]]/ } "
if [ [ $_vg ] ] ; then
2021-02-25 11:42:54 +03:00
for _pv in $( lvm vgs --noheadings -o pv_name " $_vg " 2> /dev/null) ; do
2021-03-26 14:30:15 +03:00
check_block_and_slaves " $1 " " $( get_maj_min " $_pv " ) " && return 0
2018-01-15 17:44:46 +03:00
done
fi
2009-08-31 16:58:44 +04:00
return 1
}
2016-08-09 16:26:04 +03:00
check_vol_slaves_all( ) {
2021-03-26 14:30:15 +03:00
local _vg _pv _majmin
2018-01-15 17:44:46 +03:00
_majmin = " $2 "
_dm = " /sys/dev/block/ $_majmin /dm "
2021-03-26 14:30:15 +03:00
[ [ -f $_dm /uuid && $( < " $_dm " /uuid) = ~ LVM-* ] ] || return 1
_vg = $( dmsetup splitname --noheadings -o vg_name " $( < " $_dm /name " ) " )
2018-01-15 17:44:46 +03:00
# strip space
_vg = " ${ _vg //[[ : space : ]]/ } "
if [ [ $_vg ] ] ; then
2019-08-14 15:55:56 +03:00
# when filter/global_filter is set, lvm may be failed
2021-03-26 14:30:15 +03:00
if ! lvm lvs --noheadings -o vg_name " $_vg " 2> /dev/null 1> /dev/null; then
2021-02-25 11:42:54 +03:00
return 1
2019-08-14 15:55:56 +03:00
fi
2021-02-25 11:42:54 +03:00
for _pv in $( lvm vgs --noheadings -o pv_name " $_vg " 2> /dev/null) ; do
2021-03-26 14:30:15 +03:00
check_block_and_slaves_all " $1 " " $( get_maj_min " $_pv " ) "
2018-01-15 17:44:46 +03:00
done
return 0
fi
2016-08-09 16:26:04 +03:00
return 1
}
2012-07-26 19:22:14 +04:00
# fs_get_option <filesystem options> <search for option>
# search for a specific option in a bunch of filesystem options
# and return the value
fs_get_option( ) {
local _fsopts = $1
local _option = $2
local OLDIFS = " $IFS "
IFS = ,
2021-03-26 14:30:15 +03:00
# shellcheck disable=SC2086
2012-07-26 19:22:14 +04:00
set -- $_fsopts
IFS = " $OLDIFS "
while [ $# -gt 0 ] ; do
case $1 in
$_option = *)
2021-03-26 14:30:15 +03:00
echo " ${ 1 # ${ _option } = } "
2012-07-26 19:22:14 +04:00
break
2021-02-25 11:42:54 +03:00
; ;
2012-07-26 19:22:14 +04:00
esac
shift
done
}
2021-02-25 11:42:54 +03:00
check_kernel_config( ) {
2014-08-20 12:13:55 +04:00
local _config_opt = " $1 "
local _config_file
Allow running on a cross-compiled rootfs
For the shell scripts, new environment variables were introduced.
dracutsysrootdir is the root directory, file existence checks use it.
DRACUT_LDCONFIG can override ldconfig with a different one that works
on the sysroot with foreign binaries.
DRACUT_LDD can override ldd with a different one that works
with foreign binaries.
DRACUT_TESTBIN can override /bin/sh. A cross-compiled sysroot
may use symlinks that are valid only when running on the target
so a real file must be provided that exist in the sysroot.
DRACUT_INSTALL now supports debugging dracut-install in itself
when run by dracut but without debugging the dracut scripts.
E.g. DRACUT_INSTALL="valgrind dracut-install or
DRACUT_INSTALL="dracut-install --debug".
DRACUT_COMPRESS_BZIP2, DRACUT_COMPRESS_LBZIP2, DRACUT_COMPRESS_LZMA,
DRACUT_COMPRESS_XZ, DRACUT_COMPRESS_GZIP, DRACUT_COMPRESS_PIGZ,
DRACUT_COMPRESS_LZOP, DRACUT_COMPRESS_ZSTD, DRACUT_COMPRESS_LZ4,
DRACUT_COMPRESS_CAT: All of the compression utilities may be
overridden, to support the native binaries in non-standard places.
DRACUT_ARCH overrides "uname -m".
SYSTEMD_VERSION overrides "systemd --version".
The dracut-install utility was overhauled to support sysroot via
a new option -r and fixes for clang-analyze. It supports
cross-compiler-ldd from
https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f
DRACUT_INSTALL_PATH was introduced so dracut-install can work with
a different PATH. In a cross-compiled environment (e.g. Yocto), PATH
points to natively built binaries that are not in the host's /bin,
/usr/bin, etc. dracut-install still needs plain /bin and /usr/bin
that are relative to the cross-compiled sysroot.
The hashmap pool allocate_tile/deallocate_tile code was removed
because clang-analyze showed errors in it. hashmap_copy was removed
because it wasn't used and clang-analyze showed errors in it.
DRACUT_INSTALL_LOG_TARGET and DRACUT_INSTALL_LOG_LEVEL were
introduced so dracut-install can use different settings from
DRACUT_LOG_TARGET and DRACUT_LOG_LEVEL.
Signed-off-by: Böszörményi Zoltán <zboszor@pr.hu>
2019-10-24 12:28:55 +03:00
[ [ -f $dracutsysrootdir /boot/config-$kernel ] ] \
2014-08-20 12:13:55 +04:00
&& _config_file = " /boot/config- $kernel "
Allow running on a cross-compiled rootfs
For the shell scripts, new environment variables were introduced.
dracutsysrootdir is the root directory, file existence checks use it.
DRACUT_LDCONFIG can override ldconfig with a different one that works
on the sysroot with foreign binaries.
DRACUT_LDD can override ldd with a different one that works
with foreign binaries.
DRACUT_TESTBIN can override /bin/sh. A cross-compiled sysroot
may use symlinks that are valid only when running on the target
so a real file must be provided that exist in the sysroot.
DRACUT_INSTALL now supports debugging dracut-install in itself
when run by dracut but without debugging the dracut scripts.
E.g. DRACUT_INSTALL="valgrind dracut-install or
DRACUT_INSTALL="dracut-install --debug".
DRACUT_COMPRESS_BZIP2, DRACUT_COMPRESS_LBZIP2, DRACUT_COMPRESS_LZMA,
DRACUT_COMPRESS_XZ, DRACUT_COMPRESS_GZIP, DRACUT_COMPRESS_PIGZ,
DRACUT_COMPRESS_LZOP, DRACUT_COMPRESS_ZSTD, DRACUT_COMPRESS_LZ4,
DRACUT_COMPRESS_CAT: All of the compression utilities may be
overridden, to support the native binaries in non-standard places.
DRACUT_ARCH overrides "uname -m".
SYSTEMD_VERSION overrides "systemd --version".
The dracut-install utility was overhauled to support sysroot via
a new option -r and fixes for clang-analyze. It supports
cross-compiler-ldd from
https://gist.github.com/jerome-pouiller/c403786c1394f53f44a3b61214489e6f
DRACUT_INSTALL_PATH was introduced so dracut-install can work with
a different PATH. In a cross-compiled environment (e.g. Yocto), PATH
points to natively built binaries that are not in the host's /bin,
/usr/bin, etc. dracut-install still needs plain /bin and /usr/bin
that are relative to the cross-compiled sysroot.
The hashmap pool allocate_tile/deallocate_tile code was removed
because clang-analyze showed errors in it. hashmap_copy was removed
because it wasn't used and clang-analyze showed errors in it.
DRACUT_INSTALL_LOG_TARGET and DRACUT_INSTALL_LOG_LEVEL were
introduced so dracut-install can use different settings from
DRACUT_LOG_TARGET and DRACUT_LOG_LEVEL.
Signed-off-by: Böszörményi Zoltán <zboszor@pr.hu>
2019-10-24 12:28:55 +03:00
[ [ -f $dracutsysrootdir /lib/modules/$kernel /config ] ] \
2014-08-20 12:13:55 +04:00
&& _config_file = " /lib/modules/ $kernel /config "
# no kernel config file, so return true
[ [ $_config_file ] ] || return 0
2021-01-19 12:39:17 +03:00
grep -q -F " ${ _config_opt } = " " $dracutsysrootdir $_config_file " && return 0
2014-08-20 12:13:55 +04:00
return 1
}
2020-10-20 11:58:01 +03:00
# 0 if the kernel module is either built-in or available
# 1 if the kernel module is not enabled
check_kernel_module( ) {
2021-03-26 14:30:15 +03:00
modprobe -S " $kernel " --dry-run " $1 " & > /dev/null || return 1
2020-10-20 11:58:01 +03:00
}
2014-08-20 12:13:55 +04:00
dracut.sh: Support early microcode loading.
On Wed, Jul 10, 2013 at 10:58:15AM -0400, Konrad Rzeszutek Wilk wrote:
> On Wed, Jul 10, 2013 at 09:37:11AM +0200, Harald Hoyer wrote:
> > On 07/10/2013 02:29 AM, Yu, Fenghua wrote:
> > >> From: Konrad Rzeszutek Wilk [mailto:konrad.wilk@oracle.com]
> > >> Sent: Tuesday, July 09, 2013 12:24 PM
> > >> Implement it per Linux kernel Documentation/x86/early-microcode.txt
> > >> (from v3.11-rc0):
> > [...]
> > > This patch works fine with one microcode blob in binary format. There are situations that the microcode is not delivered in one blob in binary format:
> > >
> > > First, each microcode patch is one file instead all microcode patches are in one big blob. Secondly, old delivered microcode file is in ascii format.
> > >
> > > To handle those formats, additional code needs to convert the formats into one big binary microcode blob. I'm not sure if we should consider the code and if we should put the code in dracut.
> > >
> > > Thanks.
> > >
> > > -Fenghua
> > >
> >
> >
> > $ ls /lib/firmware/amd-ucode
> > microcode_amd.bin microcode_amd_fam15h.bin microcode_amd_solaris.bin
>
> Right, so all of those blobs (for AMD) get stuck in AuthenticAMD.bin.
>
> > $ ls /lib/firmware/intel-ucode
> > 06-03-02 06-06-00 06-07-02 06-08-0a 06-0b-04 06-0f-06 06-16-01 06-1c-02
> > 06-25-02 06-2d-07 0f-01-02 0f-02-09 0f-04-03 0f-04-0a
> > 06-05-00 06-06-05 06-07-03 06-09-05 06-0d-06 06-0f-07 06-17-06 06-1c-0a
> > 06-25-05 06-2f-02 0f-02-04 0f-03-02 0f-04-04 0f-06-02
> > 06-05-01 06-06-0a 06-08-01 06-0a-00 06-0e-08 06-0f-0a 06-17-07 06-1d-01
> > 06-26-01 06-3a-09 0f-02-05 0f-03-03 0f-04-07 0f-06-04
> > 06-05-02 06-06-0d 06-08-03 06-0a-01 06-0e-0c 06-0f-0b 06-17-0a 06-1e-04
> > 06-2a-07 0f-00-07 0f-02-06 0f-03-04 0f-04-08 0f-06-05
> > 06-05-03 06-07-01 06-08-06 06-0b-01 06-0f-02 06-0f-0d 06-1a-04 06-1e-05
> > 06-2d-06 0f-00-0a 0f-02-07 0f-04-01 0f-04-09 0f-06-08
>
> And all of those get catted in GenuineIntel.bin.
>
> >
> > Also, for [[ $hostonly ]], we only want to add the current running CPU microcode.
>
> <nods> Will do that. Are you OK with me adding some of this CPU detection logic
> in dracut-functions.sh?
This is still RFC, as I had not done the --no-compress logic (or tested it).
Please see if this is OK:
>From 5f853d2ececd4cadff648e22cb9c9287a01a9783 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Tue, 9 Jul 2013 13:57:01 -0400
Subject: [PATCH] dracut.sh: Support early microcode loading.
Implement it per Linux kernel Documentation/x86/early-microcode.txt
(from v3.11-rc0):
<start>
Early load microcode
====================
By Fenghua Yu <fenghua.yu@intel.com>
Kernel can update microcode in early phase of boot time. Loading microcode early
can fix CPU issues before they are observed during kernel boot time.
Microcode is stored in an initrd file. The microcode is read from the initrd
file and loaded to CPUs during boot time.
The format of the combined initrd image is microcode in cpio format followed by
the initrd image (maybe compressed). Kernel parses the combined initrd image
during boot time. The microcode file in cpio name space is:
on Intel: kernel/x86/microcode/GenuineIntel.bin
on AMD : kernel/x86/microcode/AuthenticAMD.bin
During BSP boot (before SMP starts), if the kernel finds the microcode file in
the initrd file, it parses the microcode and saves matching microcode in memory.
If matching microcode is found, it will be uploaded in BSP and later on in all
APs.
The cached microcode patch is applied when CPUs resume from a sleep state.
There are two legacy user space interfaces to load microcode, either through
/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file
in sysfs.
In addition to these two legacy methods, the early loading method described
here is the third method with which microcode can be uploaded to a system's
CPUs.
The following example script shows how to generate a new combined initrd file in
/boot/initrd-3.5.0.ucode.img with original microcode microcode.bin and
original initrd image /boot/initrd-3.5.0.img.
mkdir initrd
cd initrd
mkdir -p kernel/x86/microcode
cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin)
find . | cpio -o -H newc >../ucode.cpio
cd ..
cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img
<end>
That is what we do in the patch. Furthermoere there is also
an off-switch: "no-early-microcode" to disable it.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[v1: Support --host-only parameter]
2013-07-13 01:02:54 +04:00
# get_cpu_vendor
# Only two values are returned: AMD or Intel
2021-02-25 11:42:54 +03:00
get_cpu_vendor( ) {
dracut.sh: Support early microcode loading.
On Wed, Jul 10, 2013 at 10:58:15AM -0400, Konrad Rzeszutek Wilk wrote:
> On Wed, Jul 10, 2013 at 09:37:11AM +0200, Harald Hoyer wrote:
> > On 07/10/2013 02:29 AM, Yu, Fenghua wrote:
> > >> From: Konrad Rzeszutek Wilk [mailto:konrad.wilk@oracle.com]
> > >> Sent: Tuesday, July 09, 2013 12:24 PM
> > >> Implement it per Linux kernel Documentation/x86/early-microcode.txt
> > >> (from v3.11-rc0):
> > [...]
> > > This patch works fine with one microcode blob in binary format. There are situations that the microcode is not delivered in one blob in binary format:
> > >
> > > First, each microcode patch is one file instead all microcode patches are in one big blob. Secondly, old delivered microcode file is in ascii format.
> > >
> > > To handle those formats, additional code needs to convert the formats into one big binary microcode blob. I'm not sure if we should consider the code and if we should put the code in dracut.
> > >
> > > Thanks.
> > >
> > > -Fenghua
> > >
> >
> >
> > $ ls /lib/firmware/amd-ucode
> > microcode_amd.bin microcode_amd_fam15h.bin microcode_amd_solaris.bin
>
> Right, so all of those blobs (for AMD) get stuck in AuthenticAMD.bin.
>
> > $ ls /lib/firmware/intel-ucode
> > 06-03-02 06-06-00 06-07-02 06-08-0a 06-0b-04 06-0f-06 06-16-01 06-1c-02
> > 06-25-02 06-2d-07 0f-01-02 0f-02-09 0f-04-03 0f-04-0a
> > 06-05-00 06-06-05 06-07-03 06-09-05 06-0d-06 06-0f-07 06-17-06 06-1c-0a
> > 06-25-05 06-2f-02 0f-02-04 0f-03-02 0f-04-04 0f-06-02
> > 06-05-01 06-06-0a 06-08-01 06-0a-00 06-0e-08 06-0f-0a 06-17-07 06-1d-01
> > 06-26-01 06-3a-09 0f-02-05 0f-03-03 0f-04-07 0f-06-04
> > 06-05-02 06-06-0d 06-08-03 06-0a-01 06-0e-0c 06-0f-0b 06-17-0a 06-1e-04
> > 06-2a-07 0f-00-07 0f-02-06 0f-03-04 0f-04-08 0f-06-05
> > 06-05-03 06-07-01 06-08-06 06-0b-01 06-0f-02 06-0f-0d 06-1a-04 06-1e-05
> > 06-2d-06 0f-00-0a 0f-02-07 0f-04-01 0f-04-09 0f-06-08
>
> And all of those get catted in GenuineIntel.bin.
>
> >
> > Also, for [[ $hostonly ]], we only want to add the current running CPU microcode.
>
> <nods> Will do that. Are you OK with me adding some of this CPU detection logic
> in dracut-functions.sh?
This is still RFC, as I had not done the --no-compress logic (or tested it).
Please see if this is OK:
>From 5f853d2ececd4cadff648e22cb9c9287a01a9783 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Tue, 9 Jul 2013 13:57:01 -0400
Subject: [PATCH] dracut.sh: Support early microcode loading.
Implement it per Linux kernel Documentation/x86/early-microcode.txt
(from v3.11-rc0):
<start>
Early load microcode
====================
By Fenghua Yu <fenghua.yu@intel.com>
Kernel can update microcode in early phase of boot time. Loading microcode early
can fix CPU issues before they are observed during kernel boot time.
Microcode is stored in an initrd file. The microcode is read from the initrd
file and loaded to CPUs during boot time.
The format of the combined initrd image is microcode in cpio format followed by
the initrd image (maybe compressed). Kernel parses the combined initrd image
during boot time. The microcode file in cpio name space is:
on Intel: kernel/x86/microcode/GenuineIntel.bin
on AMD : kernel/x86/microcode/AuthenticAMD.bin
During BSP boot (before SMP starts), if the kernel finds the microcode file in
the initrd file, it parses the microcode and saves matching microcode in memory.
If matching microcode is found, it will be uploaded in BSP and later on in all
APs.
The cached microcode patch is applied when CPUs resume from a sleep state.
There are two legacy user space interfaces to load microcode, either through
/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file
in sysfs.
In addition to these two legacy methods, the early loading method described
here is the third method with which microcode can be uploaded to a system's
CPUs.
The following example script shows how to generate a new combined initrd file in
/boot/initrd-3.5.0.ucode.img with original microcode microcode.bin and
original initrd image /boot/initrd-3.5.0.img.
mkdir initrd
cd initrd
mkdir -p kernel/x86/microcode
cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin)
find . | cpio -o -H newc >../ucode.cpio
cd ..
cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img
<end>
That is what we do in the patch. Furthermoere there is also
an off-switch: "no-early-microcode" to disable it.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[v1: Support --host-only parameter]
2013-07-13 01:02:54 +04:00
if grep -qE AMD /proc/cpuinfo; then
printf "AMD"
fi
if grep -qE Intel /proc/cpuinfo; then
printf "Intel"
fi
}
# get_host_ucode
# Get the hosts' ucode file based on the /proc/cpuinfo
2021-02-25 11:42:54 +03:00
get_ucode_file( ) {
2021-03-26 14:30:15 +03:00
local family
local model
local stepping
family = $( grep -E "cpu family" /proc/cpuinfo | head -1 | sed s/.*:\ //)
model = $( grep -E "model" /proc/cpuinfo | grep -v name | head -1 | sed s/.*:\ //)
stepping = $( grep -E "stepping" /proc/cpuinfo | head -1 | sed s/.*:\ //)
dracut.sh: Support early microcode loading.
On Wed, Jul 10, 2013 at 10:58:15AM -0400, Konrad Rzeszutek Wilk wrote:
> On Wed, Jul 10, 2013 at 09:37:11AM +0200, Harald Hoyer wrote:
> > On 07/10/2013 02:29 AM, Yu, Fenghua wrote:
> > >> From: Konrad Rzeszutek Wilk [mailto:konrad.wilk@oracle.com]
> > >> Sent: Tuesday, July 09, 2013 12:24 PM
> > >> Implement it per Linux kernel Documentation/x86/early-microcode.txt
> > >> (from v3.11-rc0):
> > [...]
> > > This patch works fine with one microcode blob in binary format. There are situations that the microcode is not delivered in one blob in binary format:
> > >
> > > First, each microcode patch is one file instead all microcode patches are in one big blob. Secondly, old delivered microcode file is in ascii format.
> > >
> > > To handle those formats, additional code needs to convert the formats into one big binary microcode blob. I'm not sure if we should consider the code and if we should put the code in dracut.
> > >
> > > Thanks.
> > >
> > > -Fenghua
> > >
> >
> >
> > $ ls /lib/firmware/amd-ucode
> > microcode_amd.bin microcode_amd_fam15h.bin microcode_amd_solaris.bin
>
> Right, so all of those blobs (for AMD) get stuck in AuthenticAMD.bin.
>
> > $ ls /lib/firmware/intel-ucode
> > 06-03-02 06-06-00 06-07-02 06-08-0a 06-0b-04 06-0f-06 06-16-01 06-1c-02
> > 06-25-02 06-2d-07 0f-01-02 0f-02-09 0f-04-03 0f-04-0a
> > 06-05-00 06-06-05 06-07-03 06-09-05 06-0d-06 06-0f-07 06-17-06 06-1c-0a
> > 06-25-05 06-2f-02 0f-02-04 0f-03-02 0f-04-04 0f-06-02
> > 06-05-01 06-06-0a 06-08-01 06-0a-00 06-0e-08 06-0f-0a 06-17-07 06-1d-01
> > 06-26-01 06-3a-09 0f-02-05 0f-03-03 0f-04-07 0f-06-04
> > 06-05-02 06-06-0d 06-08-03 06-0a-01 06-0e-0c 06-0f-0b 06-17-0a 06-1e-04
> > 06-2a-07 0f-00-07 0f-02-06 0f-03-04 0f-04-08 0f-06-05
> > 06-05-03 06-07-01 06-08-06 06-0b-01 06-0f-02 06-0f-0d 06-1a-04 06-1e-05
> > 06-2d-06 0f-00-0a 0f-02-07 0f-04-01 0f-04-09 0f-06-08
>
> And all of those get catted in GenuineIntel.bin.
>
> >
> > Also, for [[ $hostonly ]], we only want to add the current running CPU microcode.
>
> <nods> Will do that. Are you OK with me adding some of this CPU detection logic
> in dracut-functions.sh?
This is still RFC, as I had not done the --no-compress logic (or tested it).
Please see if this is OK:
>From 5f853d2ececd4cadff648e22cb9c9287a01a9783 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Tue, 9 Jul 2013 13:57:01 -0400
Subject: [PATCH] dracut.sh: Support early microcode loading.
Implement it per Linux kernel Documentation/x86/early-microcode.txt
(from v3.11-rc0):
<start>
Early load microcode
====================
By Fenghua Yu <fenghua.yu@intel.com>
Kernel can update microcode in early phase of boot time. Loading microcode early
can fix CPU issues before they are observed during kernel boot time.
Microcode is stored in an initrd file. The microcode is read from the initrd
file and loaded to CPUs during boot time.
The format of the combined initrd image is microcode in cpio format followed by
the initrd image (maybe compressed). Kernel parses the combined initrd image
during boot time. The microcode file in cpio name space is:
on Intel: kernel/x86/microcode/GenuineIntel.bin
on AMD : kernel/x86/microcode/AuthenticAMD.bin
During BSP boot (before SMP starts), if the kernel finds the microcode file in
the initrd file, it parses the microcode and saves matching microcode in memory.
If matching microcode is found, it will be uploaded in BSP and later on in all
APs.
The cached microcode patch is applied when CPUs resume from a sleep state.
There are two legacy user space interfaces to load microcode, either through
/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file
in sysfs.
In addition to these two legacy methods, the early loading method described
here is the third method with which microcode can be uploaded to a system's
CPUs.
The following example script shows how to generate a new combined initrd file in
/boot/initrd-3.5.0.ucode.img with original microcode microcode.bin and
original initrd image /boot/initrd-3.5.0.img.
mkdir initrd
cd initrd
mkdir -p kernel/x86/microcode
cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin)
find . | cpio -o -H newc >../ucode.cpio
cd ..
cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img
<end>
That is what we do in the patch. Furthermoere there is also
an off-switch: "no-early-microcode" to disable it.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[v1: Support --host-only parameter]
2013-07-13 01:02:54 +04:00
if [ [ " $( get_cpu_vendor) " = = "AMD" ] ] ; then
2017-12-14 14:24:53 +03:00
if [ [ $family -ge 21 ] ] ; then
2021-03-26 14:30:15 +03:00
printf "microcode_amd_fam%xh.bin" " $family "
dracut.sh: Support early microcode loading.
On Wed, Jul 10, 2013 at 10:58:15AM -0400, Konrad Rzeszutek Wilk wrote:
> On Wed, Jul 10, 2013 at 09:37:11AM +0200, Harald Hoyer wrote:
> > On 07/10/2013 02:29 AM, Yu, Fenghua wrote:
> > >> From: Konrad Rzeszutek Wilk [mailto:konrad.wilk@oracle.com]
> > >> Sent: Tuesday, July 09, 2013 12:24 PM
> > >> Implement it per Linux kernel Documentation/x86/early-microcode.txt
> > >> (from v3.11-rc0):
> > [...]
> > > This patch works fine with one microcode blob in binary format. There are situations that the microcode is not delivered in one blob in binary format:
> > >
> > > First, each microcode patch is one file instead all microcode patches are in one big blob. Secondly, old delivered microcode file is in ascii format.
> > >
> > > To handle those formats, additional code needs to convert the formats into one big binary microcode blob. I'm not sure if we should consider the code and if we should put the code in dracut.
> > >
> > > Thanks.
> > >
> > > -Fenghua
> > >
> >
> >
> > $ ls /lib/firmware/amd-ucode
> > microcode_amd.bin microcode_amd_fam15h.bin microcode_amd_solaris.bin
>
> Right, so all of those blobs (for AMD) get stuck in AuthenticAMD.bin.
>
> > $ ls /lib/firmware/intel-ucode
> > 06-03-02 06-06-00 06-07-02 06-08-0a 06-0b-04 06-0f-06 06-16-01 06-1c-02
> > 06-25-02 06-2d-07 0f-01-02 0f-02-09 0f-04-03 0f-04-0a
> > 06-05-00 06-06-05 06-07-03 06-09-05 06-0d-06 06-0f-07 06-17-06 06-1c-0a
> > 06-25-05 06-2f-02 0f-02-04 0f-03-02 0f-04-04 0f-06-02
> > 06-05-01 06-06-0a 06-08-01 06-0a-00 06-0e-08 06-0f-0a 06-17-07 06-1d-01
> > 06-26-01 06-3a-09 0f-02-05 0f-03-03 0f-04-07 0f-06-04
> > 06-05-02 06-06-0d 06-08-03 06-0a-01 06-0e-0c 06-0f-0b 06-17-0a 06-1e-04
> > 06-2a-07 0f-00-07 0f-02-06 0f-03-04 0f-04-08 0f-06-05
> > 06-05-03 06-07-01 06-08-06 06-0b-01 06-0f-02 06-0f-0d 06-1a-04 06-1e-05
> > 06-2d-06 0f-00-0a 0f-02-07 0f-04-01 0f-04-09 0f-06-08
>
> And all of those get catted in GenuineIntel.bin.
>
> >
> > Also, for [[ $hostonly ]], we only want to add the current running CPU microcode.
>
> <nods> Will do that. Are you OK with me adding some of this CPU detection logic
> in dracut-functions.sh?
This is still RFC, as I had not done the --no-compress logic (or tested it).
Please see if this is OK:
>From 5f853d2ececd4cadff648e22cb9c9287a01a9783 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Tue, 9 Jul 2013 13:57:01 -0400
Subject: [PATCH] dracut.sh: Support early microcode loading.
Implement it per Linux kernel Documentation/x86/early-microcode.txt
(from v3.11-rc0):
<start>
Early load microcode
====================
By Fenghua Yu <fenghua.yu@intel.com>
Kernel can update microcode in early phase of boot time. Loading microcode early
can fix CPU issues before they are observed during kernel boot time.
Microcode is stored in an initrd file. The microcode is read from the initrd
file and loaded to CPUs during boot time.
The format of the combined initrd image is microcode in cpio format followed by
the initrd image (maybe compressed). Kernel parses the combined initrd image
during boot time. The microcode file in cpio name space is:
on Intel: kernel/x86/microcode/GenuineIntel.bin
on AMD : kernel/x86/microcode/AuthenticAMD.bin
During BSP boot (before SMP starts), if the kernel finds the microcode file in
the initrd file, it parses the microcode and saves matching microcode in memory.
If matching microcode is found, it will be uploaded in BSP and later on in all
APs.
The cached microcode patch is applied when CPUs resume from a sleep state.
There are two legacy user space interfaces to load microcode, either through
/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file
in sysfs.
In addition to these two legacy methods, the early loading method described
here is the third method with which microcode can be uploaded to a system's
CPUs.
The following example script shows how to generate a new combined initrd file in
/boot/initrd-3.5.0.ucode.img with original microcode microcode.bin and
original initrd image /boot/initrd-3.5.0.img.
mkdir initrd
cd initrd
mkdir -p kernel/x86/microcode
cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin)
find . | cpio -o -H newc >../ucode.cpio
cd ..
cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img
<end>
That is what we do in the patch. Furthermoere there is also
an off-switch: "no-early-microcode" to disable it.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[v1: Support --host-only parameter]
2013-07-13 01:02:54 +04:00
else
printf "microcode_amd.bin"
fi
fi
if [ [ " $( get_cpu_vendor) " = = "Intel" ] ] ; then
# The /proc/cpuinfo are in decimal.
2021-03-26 14:30:15 +03:00
printf "%02x-%02x-%02x" " ${ family } " " ${ model } " " ${ stepping } "
dracut.sh: Support early microcode loading.
On Wed, Jul 10, 2013 at 10:58:15AM -0400, Konrad Rzeszutek Wilk wrote:
> On Wed, Jul 10, 2013 at 09:37:11AM +0200, Harald Hoyer wrote:
> > On 07/10/2013 02:29 AM, Yu, Fenghua wrote:
> > >> From: Konrad Rzeszutek Wilk [mailto:konrad.wilk@oracle.com]
> > >> Sent: Tuesday, July 09, 2013 12:24 PM
> > >> Implement it per Linux kernel Documentation/x86/early-microcode.txt
> > >> (from v3.11-rc0):
> > [...]
> > > This patch works fine with one microcode blob in binary format. There are situations that the microcode is not delivered in one blob in binary format:
> > >
> > > First, each microcode patch is one file instead all microcode patches are in one big blob. Secondly, old delivered microcode file is in ascii format.
> > >
> > > To handle those formats, additional code needs to convert the formats into one big binary microcode blob. I'm not sure if we should consider the code and if we should put the code in dracut.
> > >
> > > Thanks.
> > >
> > > -Fenghua
> > >
> >
> >
> > $ ls /lib/firmware/amd-ucode
> > microcode_amd.bin microcode_amd_fam15h.bin microcode_amd_solaris.bin
>
> Right, so all of those blobs (for AMD) get stuck in AuthenticAMD.bin.
>
> > $ ls /lib/firmware/intel-ucode
> > 06-03-02 06-06-00 06-07-02 06-08-0a 06-0b-04 06-0f-06 06-16-01 06-1c-02
> > 06-25-02 06-2d-07 0f-01-02 0f-02-09 0f-04-03 0f-04-0a
> > 06-05-00 06-06-05 06-07-03 06-09-05 06-0d-06 06-0f-07 06-17-06 06-1c-0a
> > 06-25-05 06-2f-02 0f-02-04 0f-03-02 0f-04-04 0f-06-02
> > 06-05-01 06-06-0a 06-08-01 06-0a-00 06-0e-08 06-0f-0a 06-17-07 06-1d-01
> > 06-26-01 06-3a-09 0f-02-05 0f-03-03 0f-04-07 0f-06-04
> > 06-05-02 06-06-0d 06-08-03 06-0a-01 06-0e-0c 06-0f-0b 06-17-0a 06-1e-04
> > 06-2a-07 0f-00-07 0f-02-06 0f-03-04 0f-04-08 0f-06-05
> > 06-05-03 06-07-01 06-08-06 06-0b-01 06-0f-02 06-0f-0d 06-1a-04 06-1e-05
> > 06-2d-06 0f-00-0a 0f-02-07 0f-04-01 0f-04-09 0f-06-08
>
> And all of those get catted in GenuineIntel.bin.
>
> >
> > Also, for [[ $hostonly ]], we only want to add the current running CPU microcode.
>
> <nods> Will do that. Are you OK with me adding some of this CPU detection logic
> in dracut-functions.sh?
This is still RFC, as I had not done the --no-compress logic (or tested it).
Please see if this is OK:
>From 5f853d2ececd4cadff648e22cb9c9287a01a9783 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date: Tue, 9 Jul 2013 13:57:01 -0400
Subject: [PATCH] dracut.sh: Support early microcode loading.
Implement it per Linux kernel Documentation/x86/early-microcode.txt
(from v3.11-rc0):
<start>
Early load microcode
====================
By Fenghua Yu <fenghua.yu@intel.com>
Kernel can update microcode in early phase of boot time. Loading microcode early
can fix CPU issues before they are observed during kernel boot time.
Microcode is stored in an initrd file. The microcode is read from the initrd
file and loaded to CPUs during boot time.
The format of the combined initrd image is microcode in cpio format followed by
the initrd image (maybe compressed). Kernel parses the combined initrd image
during boot time. The microcode file in cpio name space is:
on Intel: kernel/x86/microcode/GenuineIntel.bin
on AMD : kernel/x86/microcode/AuthenticAMD.bin
During BSP boot (before SMP starts), if the kernel finds the microcode file in
the initrd file, it parses the microcode and saves matching microcode in memory.
If matching microcode is found, it will be uploaded in BSP and later on in all
APs.
The cached microcode patch is applied when CPUs resume from a sleep state.
There are two legacy user space interfaces to load microcode, either through
/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file
in sysfs.
In addition to these two legacy methods, the early loading method described
here is the third method with which microcode can be uploaded to a system's
CPUs.
The following example script shows how to generate a new combined initrd file in
/boot/initrd-3.5.0.ucode.img with original microcode microcode.bin and
original initrd image /boot/initrd-3.5.0.img.
mkdir initrd
cd initrd
mkdir -p kernel/x86/microcode
cp ../microcode.bin kernel/x86/microcode/GenuineIntel.bin (or AuthenticAMD.bin)
find . | cpio -o -H newc >../ucode.cpio
cd ..
cat ucode.cpio /boot/initrd-3.5.0.img >/boot/initrd-3.5.0.ucode.img
<end>
That is what we do in the patch. Furthermoere there is also
an off-switch: "no-early-microcode" to disable it.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[v1: Support --host-only parameter]
2013-07-13 01:02:54 +04:00
fi
}
2013-10-18 16:40:40 +04:00
# Not every device in /dev/mapper should be examined.
# If it is an LVM device, touch only devices which have /dev/VG/LV symlink.
lvm_internal_dev( ) {
local dev_dm_dir = /sys/dev/block/$1 /dm
2021-03-26 14:30:15 +03:00
[ [ ! -f $dev_dm_dir /uuid || $( < " $dev_dm_dir " /uuid) != LVM-* ] ] && return 1 # Not an LVM device
2013-10-18 16:40:40 +04:00
local DM_VG_NAME DM_LV_NAME DM_LV_LAYER
2021-03-26 14:30:15 +03:00
eval " $( dmsetup splitname --nameprefixes --noheadings --rows " $( < " $dev_dm_dir " /name) " 2> /dev/null) "
2013-10-18 16:40:40 +04:00
[ [ ${ DM_VG_NAME } ] ] && [ [ ${ DM_LV_NAME } ] ] || return 0 # Better skip this!
[ [ ${ DM_LV_LAYER } ] ] || [ [ ! -L /dev/${ DM_VG_NAME } /${ DM_LV_NAME } ] ]
}
2015-07-09 14:18:13 +03:00
btrfs_devs( ) {
local _mp = " $1 "
btrfs device usage " $_mp " \
2021-03-26 14:30:15 +03:00
| while read -r _dev _; do
2021-02-25 11:42:54 +03:00
str_starts " $_dev " "/" || continue
_dev = ${ _dev %, }
printf -- "%s\n" " $_dev "
2015-07-09 14:18:13 +03:00
done
}
2020-07-11 01:15:34 +03:00
iface_for_remote_addr( ) {
2021-03-26 14:30:15 +03:00
# shellcheck disable=SC2046
2020-07-11 01:15:34 +03:00
set -- $( ip -o route get to " $1 " )
2021-03-26 14:30:15 +03:00
echo " $3 "
2020-07-11 01:15:34 +03:00
}
local_addr_for_remote_addr( ) {
2021-03-26 14:30:15 +03:00
# shellcheck disable=SC2046
2020-07-11 01:15:34 +03:00
set -- $( ip -o route get to " $1 " )
2021-03-26 14:30:15 +03:00
echo " $5 "
2020-07-11 01:15:34 +03:00
}
peer_for_addr( ) {
local addr = $1
local qtd
# quote periods in IPv4 address
qtd = ${ addr //./ \\ . }
2021-02-25 11:42:54 +03:00
ip -o addr show \
| sed -n 's%^.* ' " $qtd " ' peer \([0-9a-f.:]\{1,\}\(/[0-9]*\)\?\).*$%\1%p'
2020-07-11 01:15:34 +03:00
}
netmask_for_addr( ) {
local addr = $1
local qtd
# quote periods in IPv4 address
qtd = ${ addr //./ \\ . }
ip -o addr show | sed -n 's,^.* ' " $qtd " '/\([0-9]*\) .*$,\1,p'
}
gateway_for_iface( ) {
local ifname = $1 addr = $2
case $addr in
2021-02-25 11:42:54 +03:00
*.*) proto = 4 ; ;
*:*) proto = 6 ; ;
*) return ; ;
2020-07-11 01:15:34 +03:00
esac
2021-02-25 11:42:54 +03:00
ip -o -$proto route show \
| sed -n " s/^default via \([0-9a-z.:]\{1,\}\) dev $ifname .*\$/\1/p "
2020-07-11 01:15:34 +03:00
}
# This works only for ifcfg-style network configuration!
bootproto_for_iface( ) {
local ifname = $1
local dir
# follow ifcfg settings for boot protocol
for dir in network-scripts network; do
[ -f " /etc/sysconfig/ $dir /ifcfg- $ifname " ] && {
sed -n "s/BOOTPROTO=[\"']\?\([[:alnum:]]\{1,\}\)[\"']\?.*\$/\1/p" \
" /etc/sysconfig/ $dir /ifcfg- $ifname "
return
}
done
}
is_unbracketed_ipv6_address( ) {
strglob " $1 " '*:*' && ! strglob " $1 " '\[*:*\]'
}
# Create an ip= string to set up networking such that the given
# remote address can be reached
ip_params_for_remote_addr( ) {
local remote_addr = $1
2021-03-26 14:30:15 +03:00
local ifname local_addr peer netmask gateway ifmac
2020-07-11 01:15:34 +03:00
[ [ $remote_addr ] ] || return 1
ifname = $( iface_for_remote_addr " $remote_addr " )
[ [ $ifname ] ] || {
berror " failed to determine interface to connect to $remote_addr "
return 1
}
# ifname clause to bind the interface name to a MAC address
if [ -d " /sys/class/net/ $ifname /bonding " ] ; then
dinfo " Found bonded interface ' ${ ifname } '. Make sure to provide an appropriate 'bond=' cmdline. "
2021-02-25 11:42:54 +03:00
elif [ -e " /sys/class/net/ $ifname /address " ] ; then
2020-07-11 01:15:34 +03:00
ifmac = $( cat " /sys/class/net/ $ifname /address " )
[ [ $ifmac ] ] && printf 'ifname=%s:%s ' " ${ ifname } " " ${ ifmac } "
fi
bootproto = $( bootproto_for_iface " $ifname " )
case $bootproto in
2021-02-25 11:42:54 +03:00
dhcp | dhcp6 | auto6) ; ;
2020-07-11 01:15:34 +03:00
dhcp4)
2021-02-25 11:42:54 +03:00
bootproto = dhcp
; ;
static* | "" )
bootproto =
; ;
2020-07-11 01:15:34 +03:00
*)
derror " bootproto \" $bootproto \" is unsupported by dracut, trying static configuration "
2021-02-25 11:42:54 +03:00
bootproto =
; ;
2020-07-11 01:15:34 +03:00
esac
if [ [ $bootproto ] ] ; then
printf 'ip=%s:%s ' " ${ ifname } " " ${ bootproto } "
else
local_addr = $( local_addr_for_remote_addr " $remote_addr " )
[ [ $local_addr ] ] || {
berror " failed to determine local address to connect to $remote_addr "
return 1
}
peer = $( peer_for_addr " $local_addr " )
# Set peer or netmask, but not both
[ [ $peer ] ] || netmask = $( netmask_for_addr " $local_addr " )
gateway = $( gateway_for_iface " $ifname " " $local_addr " )
# Quote IPv6 addresses with brackets
is_unbracketed_ipv6_address " $local_addr " && local_addr = " [ $local_addr ] "
is_unbracketed_ipv6_address " $peer " && peer = " [ $peer ] "
is_unbracketed_ipv6_address " $gateway " && gateway = " [ $gateway ] "
printf 'ip=%s:%s:%s:%s::%s:none ' \
2021-02-25 11:42:54 +03:00
" ${ local_addr } " " ${ peer } " " ${ gateway } " " ${ netmask } " " ${ ifname } "
2020-07-11 01:15:34 +03:00
fi
}
2020-08-04 11:20:51 +03:00
# block_is_nbd <maj:min>
# Check whether $1 is an nbd device
block_is_nbd( ) {
[ [ -b /dev/block/$1 && $1 = = 43:* ] ]
}
# block_is_iscsi <maj:min>
# Check whether $1 is an nbd device
block_is_iscsi( ) {
local _dir
local _dev = $1
[ [ -L " /sys/dev/block/ $_dev " ] ] || return
_dir = " $( readlink -f " /sys/dev/block/ $_dev " ) " || return
until [ [ -d " $_dir /sys " || -d " $_dir /iscsi_session " ] ] ; do
_dir = " $_dir /.. "
done
[ [ -d " $_dir /iscsi_session " ] ]
}
# block_is_fcoe <maj:min>
# Check whether $1 is an FCoE device
# Will not work for HBAs that hide the ethernet aspect
# completely and present a pure FC device
block_is_fcoe( ) {
local _dir
local _dev = $1
[ [ -L " /sys/dev/block/ $_dev " ] ] || return
_dir = " $( readlink -f " /sys/dev/block/ $_dev " ) "
until [ [ -d " $_dir /sys " ] ] ; do
_dir = " $_dir /.. "
if [ [ -d " $_dir /subsystem " ] ] ; then
2021-03-26 14:30:15 +03:00
subsystem = $( basename " $( readlink " $_dir " /subsystem) " )
2020-08-04 11:20:51 +03:00
[ [ $subsystem = = "fcoe" ] ] && return 0
fi
done
return 1
}
# block_is_netdevice <maj:min>
# Check whether $1 is a net device
block_is_netdevice( ) {
block_is_nbd " $1 " || block_is_iscsi " $1 " || block_is_fcoe " $1 "
}
2020-10-12 10:18:45 +03:00
# get the corresponding kernel modules of a /sys/class/*/* or/dev/* device
get_dev_module( ) {
udevadm info -a " $1 " | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p'
}