eaiovnaovbqoebvqoeavibavo
dracut-version.sh 0000644 00000000047 15023162470 0010046 0 ustar 00 DRACUT_VERSION=049-233.git20240115.el8
dracut-functions.sh 0000755 00000052214 15023162470 0010377 0 ustar 00 #!/bin/bash
#
# functions used by dracut and other tools.
#
# Copyright 2005-2009 Red Hat, Inc. All rights reserved.
#
# 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
# along with this program. If not, see .
#
export LC_MESSAGES=C
# is_func
# Check whether $1 is a function.
is_func() {
[[ "$(type -t "$1")" = "function" ]]
}
# Generic substring function. If $2 is in $1, return 0.
strstr() { [[ $1 = *"$2"* ]]; }
# Generic glob matching function. If glob pattern $2 matches anywhere in $1, OK
strglobin() { [[ $1 = *$2* ]]; }
# Generic glob matching function. If glob pattern $2 matches all of $1, OK
strglob() { [[ $1 = $2 ]]; }
# 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" ]; }
# find a binary. If we were not passed the full path directly,
# search in the usual places to find the binary.
find_binary() {
if [[ -z ${1##/*} ]]; then
if [[ -x $1 ]] || { [[ "$1" == *.so* ]] && ldd "$1" &>/dev/null; }; then
printf "%s\n" "$1"
return 0
fi
fi
type -P "${1##*/}"
}
ldconfig_paths()
{
ldconfig -pN 2>/dev/null | grep -E -v '/(lib|lib64|usr/lib|usr/lib64)/[^/]*$' | sed -n 's,.* => \(.*\)/.*,\1,p' | sort | uniq
}
# Version comparision function. Assumes Linux style version scheme.
# $1 = version a
# $2 = comparision op (gt, ge, eq, le, lt, ne)
# $3 = version b
vercmp() {
local _n1=(${1//./ }) _op=$2 _n2=(${3//./ }) _i _res
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
fi
break
done
case $_op in
gt) ((_res == 1));;
ge) ((_res != 2));;
eq) ((_res == 0));;
le) ((_res != 1));;
lt) ((_res == 2));;
ne) ((_res != 0));;
esac
}
# Create all subdirectories for given path without creating the last element.
# $1 = path
mksubdirs() {
[[ -e ${1%/*} ]] || mkdir -m 0755 -p -- "${1%/*}"
}
# Function prints global variables in format name=value line by line.
# $@ = list of global variables' name
print_vars() {
local _var _value
for _var in "$@"
do
eval printf -v _value "%s" \""\$$_var"\"
[[ ${_value} ]] && printf '%s="%s"\n' "$_var" "$_value"
done
}
# normalize_path
# Prints the normalized path, where it removes any duplicated
# and trailing slashes.
# Example:
# $ normalize_path ///test/test//
# /test/test
normalize_path() {
shopt -q -s extglob
set -- "${1//+(\/)//}"
shopt -q -u extglob
printf "%s\n" "${1%/}"
}
# convert_abs_rel
# Prints the relative path, when creating a symlink to 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
convert_abs_rel() {
local __current __absolute __abssize __cursize __newpath
local -i __i __level
set -- "$(normalize_path "$1")" "$(normalize_path "$2")"
# corner case #1 - self looping link
[[ "$1" == "$2" ]] && { printf "%s\n" "${1##*/}"; return; }
# corner case #2 - own dir link
[[ "${1%/*}" == "$2" ]] && { printf ".\n"; return; }
IFS="/" __current=($1)
IFS="/" __absolute=($2)
__abssize=${#__absolute[@]}
__cursize=${#__current[@]}
while [[ "${__absolute[__level]}" == "${__current[__level]}" ]]
do
(( __level++ ))
if (( __level > __abssize || __level > __cursize ))
then
break
fi
done
for ((__i = __level; __i < __cursize-1; __i++))
do
if ((__i > __level))
then
__newpath=$__newpath"/"
fi
__newpath=$__newpath".."
done
for ((__i = __level; __i < __abssize; __i++))
do
if [[ -n $__newpath ]]
then
__newpath=$__newpath"/"
fi
__newpath=$__newpath${__absolute[__i]}
done
printf "%s\n" "$__newpath"
}
# get_fs_env
# Get and the ID_FS_TYPE variable from udev for a device.
# Example:
# $ get_fs_env /dev/sda2
# ext4
get_fs_env() {
local evalstr
local found
[[ $1 ]] || return
unset ID_FS_TYPE
ID_FS_TYPE=$(blkid -u filesystem -o export -- "$1" \
| while read line || [ -n "$line" ]; do
if [[ "$line" == TYPE\=* ]]; then
printf "%s" "${line#TYPE=}";
exit 0;
fi
done)
if [[ $ID_FS_TYPE ]]; then
printf "%s" "$ID_FS_TYPE"
return 0
fi
return 1
}
# get_maj_min
# Prints the major and minor of a device node.
# Example:
# $ get_maj_min /dev/sda2
# 8:2
get_maj_min() {
local _majmin
local _out
if [[ $get_maj_min_cache_file ]]; then
_out="$(grep -m1 -oP "^$1 \K\S+$" "$get_maj_min_cache_file")"
fi
if ! [[ "$_out" ]]; then
_majmin="$(stat -L -c '%t:%T' "$1" 2>/dev/null)"
_out="$(printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))")"
if [[ $get_maj_min_cache_file ]]; then
echo "$1 $_out" >> "$get_maj_min_cache_file"
fi
fi
echo -n "$_out"
}
# get_devpath_block
# get the DEVPATH in /sys of a block device
get_devpath_block() {
local _majmin _i
_majmin=$(get_maj_min "$1")
for _i in /sys/block/*/dev /sys/block/*/*/dev; do
[[ -e "$_i" ]] || continue
if [[ "$_majmin" == "$(<"$_i")" ]]; then
printf "%s" "${_i%/dev}"
return 0
fi
done
return 1
}
# get a persistent path from a device
get_persistent_dev() {
local i _tmp _dev _pol
_dev=$(get_maj_min "$1")
[ -z "$_dev" ] && return
if [[ -n "$persistent_policy" ]]; then
_pol="/dev/disk/${persistent_policy}/*"
else
_pol=
fi
for i in \
$_pol \
/dev/mapper/* \
/dev/disk/by-uuid/* \
/dev/disk/by-label/* \
/dev/disk/by-partuuid/* \
/dev/disk/by-partlabel/* \
/dev/disk/by-id/* \
/dev/disk/by-path/* \
; do
[[ -e "$i" ]] || continue
[[ $i == /dev/mapper/control ]] && continue
[[ $i == /dev/mapper/mpath* ]] && continue
_tmp=$(get_maj_min "$i")
if [ "$_tmp" = "$_dev" ]; then
printf -- "%s" "$i"
return
fi
done
printf -- "%s" "$1"
}
expand_persistent_dev() {
local _dev=$1
case "$_dev" in
LABEL=*)
_dev="/dev/disk/by-label/${_dev#LABEL=}"
;;
UUID=*)
_dev="${_dev#UUID=}"
_dev="${_dev,,}"
_dev="/dev/disk/by-uuid/${_dev}"
;;
PARTUUID=*)
_dev="${_dev#PARTUUID=}"
_dev="${_dev,,}"
_dev="/dev/disk/by-partuuid/${_dev}"
;;
PARTLABEL=*)
_dev="/dev/disk/by-partlabel/${_dev#PARTLABEL=}"
;;
esac
printf "%s" "$_dev"
}
shorten_persistent_dev() {
local _dev="$1"
case "$_dev" in
/dev/disk/by-uuid/*)
printf "%s" "UUID=${_dev##*/}";;
/dev/disk/by-label/*)
printf "%s" "LABEL=${_dev##*/}";;
/dev/disk/by-partuuid/*)
printf "%s" "PARTUUID=${_dev##*/}";;
/dev/disk/by-partlabel/*)
printf "%s" "PARTLABEL=${_dev##*/}";;
*)
printf "%s" "$_dev";;
esac
}
# find_block_device
# 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
find_block_device() {
local _dev _majmin _find_mpt
_find_mpt="$1"
if [[ $use_fstab != yes ]]; then
[[ -d $_find_mpt/. ]]
findmnt -e -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" | { \
while read _majmin _dev || [ -n "$_dev" ]; do
if [[ -b $_dev ]]; then
if ! [[ $_majmin ]] || [[ $_majmin == 0:* ]]; then
_majmin=$(get_maj_min $_dev)
fi
if [[ $_majmin ]]; then
printf "%s\n" "$_majmin"
else
printf "%s\n" "$_dev"
fi
return 0
fi
if [[ $_dev = *:* ]]; then
printf "%s\n" "$_dev"
return 0
fi
done; return 1; } && return 0
fi
# fall back to /etc/fstab
findmnt -e --fstab -v -n -o 'MAJ:MIN,SOURCE' --target "$_find_mpt" | { \
while read _majmin _dev || [ -n "$_dev" ]; do
if ! [[ $_dev ]]; then
_dev="$_majmin"
unset _majmin
fi
if [[ -b $_dev ]]; then
[[ $_majmin ]] || _majmin=$(get_maj_min $_dev)
if [[ $_majmin ]]; then
printf "%s\n" "$_majmin"
else
printf "%s\n" "$_dev"
fi
return 0
fi
if [[ $_dev = *:* ]]; then
printf "%s\n" "$_dev"
return 0
fi
done; return 1; } && return 0
return 1
}
# find_mp_fstype
# Echo the filesystem type 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_fstype /;echo
# ext4
find_mp_fstype() {
local _fs
if [[ $use_fstab != yes ]]; then
findmnt -e -v -n -o 'FSTYPE' --target "$1" | { \
while read _fs || [ -n "$_fs" ]; do
[[ $_fs ]] || continue
[[ $_fs = "autofs" ]] && continue
printf "%s" "$_fs"
return 0
done; return 1; } && return 0
fi
findmnt --fstab -e -v -n -o 'FSTYPE' --target "$1" | { \
while read _fs || [ -n "$_fs" ]; do
[[ $_fs ]] || continue
[[ $_fs = "autofs" ]] && continue
printf "%s" "$_fs"
return 0
done; return 1; } && return 0
return 1
}
# find_dev_fstype
# Echo the filesystem type for a given device.
# /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_dev_fstype /dev/sda2;echo
# ext4
find_dev_fstype() {
local _find_dev _fs
_find_dev="$1"
if ! [[ "$_find_dev" = /dev* ]]; then
[[ -b "/dev/block/$_find_dev" ]] && _find_dev="/dev/block/$_find_dev"
fi
if [[ $use_fstab != yes ]]; then
findmnt -e -v -n -o 'FSTYPE' --source "$_find_dev" | { \
while read _fs || [ -n "$_fs" ]; do
[[ $_fs ]] || continue
[[ $_fs = "autofs" ]] && continue
printf "%s" "$_fs"
return 0
done; return 1; } && return 0
fi
findmnt --fstab -e -v -n -o 'FSTYPE' --source "$_find_dev" | { \
while read _fs || [ -n "$_fs" ]; do
[[ $_fs ]] || continue
[[ $_fs = "autofs" ]] && continue
printf "%s" "$_fs"
return 0
done; return 1; } && return 0
return 1
}
# find_mp_fsopts
# 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
findmnt -e -v -n -o 'OPTIONS' --target "$1" 2>/dev/null && return 0
fi
findmnt --fstab -e -v -n -o 'OPTIONS' --target "$1"
}
# find_dev_fsopts
# 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.
# Example:
# $ find_dev_fsopts /dev/sda2
# rw,relatime,discard,data=ordered
find_dev_fsopts() {
local _find_dev _opts
_find_dev="$1"
if ! [[ "$_find_dev" = /dev* ]]; then
[[ -b "/dev/block/$_find_dev" ]] && _find_dev="/dev/block/$_find_dev"
fi
if [[ $use_fstab != yes ]]; then
findmnt -e -v -n -o 'OPTIONS' --source "$_find_dev" 2>/dev/null && return 0
fi
findmnt --fstab -e -v -n -o 'OPTIONS' --source "$_find_dev"
}
# finds the major:minor of the block device backing the root filesystem.
find_root_block_device() { find_block_device /; }
# for_each_host_dev_fs
# Execute " " for every " " pair found
# in ${host_fs_types[@]}
for_each_host_dev_fs()
{
local _func="$1"
local _dev
local _ret=1
[[ "${#host_fs_types[@]}" ]] || return 2
for _dev in "${!host_fs_types[@]}"; do
$_func "$_dev" "${host_fs_types[$_dev]}" && _ret=0
done
return $_ret
}
host_fs_all()
{
printf "%s\n" "${host_fs_types[@]}"
}
# 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
check_block_and_slaves() {
local _x
[[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
if ! lvm_internal_dev $2; then "$1" $2 && return; fi
check_vol_slaves "$@" && return 0
if [[ -f /sys/dev/block/$2/../dev ]] && [[ /sys/dev/block/$2/../subsystem -ef /sys/class/block ]]; then
check_block_and_slaves $1 $(<"/sys/dev/block/$2/../dev") && return 0
fi
[[ -d /sys/dev/block/$2/slaves ]] || return 1
for _x in /sys/dev/block/$2/slaves/*; do
[[ -f $_x/dev ]] || continue
[[ $_x/subsystem -ef /sys/class/block ]] || continue
check_block_and_slaves $1 $(<"$_x/dev") && return 0
done
return 1
}
check_block_and_slaves_all() {
local _x _ret=1
[[ -b /dev/block/$2 ]] || return 1 # Not a block device? So sorry.
if ! lvm_internal_dev $2 && "$1" $2; then
_ret=0
fi
check_vol_slaves_all "$@" && return 0
if [[ -f /sys/dev/block/$2/../dev ]] && [[ /sys/dev/block/$2/../subsystem -ef /sys/class/block ]]; then
check_block_and_slaves_all $1 $(<"/sys/dev/block/$2/../dev") && _ret=0
fi
[[ -d /sys/dev/block/$2/slaves ]] || return 1
for _x in /sys/dev/block/$2/slaves/*; do
[[ -f $_x/dev ]] || continue
[[ $_x/subsystem -ef /sys/class/block ]] || continue
check_block_and_slaves_all $1 $(<"$_x/dev") && _ret=0
done
return $_ret
}
# for_each_host_dev_and_slaves
# Execute " " for every "" found
# in ${host_devs[@]} and their slaves
for_each_host_dev_and_slaves_all()
{
local _func="$1"
local _dev
local _ret=1
[[ "${host_devs[@]}" ]] || return 2
for _dev in "${host_devs[@]}"; do
[[ -b "$_dev" ]] || continue
if check_block_and_slaves_all $_func $(get_maj_min $_dev); then
_ret=0
fi
done
return $_ret
}
for_each_host_dev_and_slaves()
{
local _func="$1"
local _dev
[[ "${host_devs[@]}" ]] || return 2
for _dev in "${host_devs[@]}"; do
[[ -b "$_dev" ]] || continue
check_block_and_slaves $_func $(get_maj_min $_dev) && return 0
done
return 1
}
# 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.
# And the volume group might be bigger than the devices the LV needs.
check_vol_slaves() {
local _lv _vg _pv _dm _majmin
_majmin="$2"
_lv="/dev/block/$_majmin"
_dm=/sys/dev/block/$_majmin/dm
[[ -f $_dm/uuid && $(<$_dm/uuid) =~ LVM-* ]] || return 1
_vg=$(dmsetup splitname --noheadings -o vg_name $(<"$_dm/name") )
# strip space
_vg="${_vg//[[:space:]]/}"
if [[ $_vg ]]; then
for _pv in $(lvm vgs --noheadings -o pv_name "$_vg" 2>/dev/null)
do
check_block_and_slaves $1 $(get_maj_min $_pv) && return 0
done
fi
return 1
}
check_vol_slaves_all() {
local _lv _vg _pv _majmin
_majmin="$2"
_lv="/dev/block/$_majmin"
_dm="/sys/dev/block/$_majmin/dm"
[[ -f $_dm/uuid && $(<$_dm/uuid) =~ LVM-* ]] || return 1
_vg=$(dmsetup splitname --noheadings -o vg_name $(<"$_dm/name") )
# strip space
_vg="${_vg//[[:space:]]/}"
if [[ $_vg ]]; then
for _pv in $(lvm vgs --noheadings -o pv_name "$_vg" 2>/dev/null)
do
check_block_and_slaves_all $1 $(get_maj_min $_pv)
done
return 0
fi
return 1
}
# fs_get_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=,
set -- $_fsopts
IFS="$OLDIFS"
while [ $# -gt 0 ]; do
case $1 in
$_option=*)
echo ${1#${_option}=}
break
esac
shift
done
}
check_kernel_config()
{
local _config_opt="$1"
local _config_file
[[ -f /boot/config-$kernel ]] \
&& _config_file="/boot/config-$kernel"
[[ -f /lib/modules/$kernel/config ]] \
&& _config_file="/lib/modules/$kernel/config"
# no kernel config file, so return true
[[ $_config_file ]] || return 0
grep -q -F "${_config_opt}=" "$_config_file" && return 0
return 1
}
# get_cpu_vendor
# Only two values are returned: AMD or Intel
get_cpu_vendor ()
{
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
get_ucode_file ()
{
local family=`grep -E "cpu family" /proc/cpuinfo | head -1 | sed s/.*:\ //`
local model=`grep -E "model" /proc/cpuinfo |grep -v name | head -1 | sed s/.*:\ //`
local stepping=`grep -E "stepping" /proc/cpuinfo | head -1 | sed s/.*:\ //`
if [[ "$(get_cpu_vendor)" == "AMD" ]]; then
if [[ $family -ge 21 ]]; then
printf "microcode_amd_fam%xh.bin" $family
else
printf "microcode_amd.bin"
fi
fi
if [[ "$(get_cpu_vendor)" == "Intel" ]]; then
# The /proc/cpuinfo are in decimal.
printf "%02x-%02x-%02x" ${family} ${model} ${stepping}
fi
}
# Get currently loaded modules
# sorted, and delimited by newline
get_loaded_kernel_modules ()
{
local modules=( )
while read _module _size _used _used_by; do
modules+=( "$_module" )
done <<< "$(lsmod | sed -n '1!p')"
printf '%s\n' "${modules[@]}" | sort
}
# 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
[[ ! -f $dev_dm_dir/uuid || $(<$dev_dm_dir/uuid) != LVM-* ]] && return 1 # Not an LVM device
local DM_VG_NAME DM_LV_NAME DM_LV_LAYER
eval $(dmsetup splitname --nameprefixes --noheadings --rows "$(<$dev_dm_dir/name)" 2>/dev/null)
[[ ${DM_VG_NAME} ]] && [[ ${DM_LV_NAME} ]] || return 0 # Better skip this!
[[ ${DM_LV_LAYER} ]] || [[ ! -L /dev/${DM_VG_NAME}/${DM_LV_NAME} ]]
}
btrfs_devs() {
local _mp="$1"
btrfs device usage "$_mp" \
| while read _dev _rest; do
str_starts "$_dev" "/" || continue
_dev=${_dev%,}
printf -- "%s\n" "$_dev"
done
}
# block_is_nbd
# Check whether $1 is an nbd device
block_is_nbd() {
[[ -b /dev/block/$1 && $1 == 43:* ]]
}
# block_is_iscsi
# 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
# 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
subsystem=$(basename $(readlink $_dir/subsystem))
[[ $subsystem == "fcoe" ]] && return 0
fi
done
return 1
}
# block_is_netdevice
# Check whether $1 is a net device
block_is_netdevice() {
block_is_nbd "$1" || block_is_iscsi "$1" || block_is_fcoe "$1"
} dracut-init.sh 0000755 00000104533 15023162470 0007334 0 ustar 00 #!/bin/bash
#
# functions used only by dracut and dracut modules
#
# Copyright 2005-2009 Red Hat, Inc. All rights reserved.
#
# 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
# along with this program. If not, see .
#
export LC_MESSAGES=C
if [[ "$EUID" = "0" ]]; then
export DRACUT_CP="cp --reflink=auto --sparse=auto --preserve=mode,timestamps,xattr,links -dfr"
else
export DRACUT_CP="cp --reflink=auto --sparse=auto --preserve=mode,timestamps,links -dfr"
fi
# is_func
# Check whether $1 is a function.
is_func() {
[[ "$(type -t "$1")" = "function" ]]
}
if ! [[ $dracutbasedir ]]; then
dracutbasedir=${BASH_SOURCE[0]%/*}
[[ $dracutbasedir = dracut-functions* ]] && dracutbasedir="."
[[ $dracutbasedir ]] || dracutbasedir="."
dracutbasedir="$(readlink -f $dracutbasedir)"
fi
if ! is_func dinfo >/dev/null 2>&1; then
. "$dracutbasedir/dracut-logger.sh"
dlog_init
fi
if ! [[ $initdir ]]; then
dfatal "initdir not set"
exit 1
fi
if ! [[ -d $initdir ]]; then
mkdir -p "$initdir"
fi
if ! [[ $kernel ]]; then
kernel=$(uname -r)
export kernel
fi
srcmods="/lib/modules/$kernel/"
[[ $drivers_dir ]] && {
if ! command -v kmod &>/dev/null && vercmp "$(modprobe --version | cut -d' ' -f3)" lt 3.7; then
dfatal 'To use --kmoddir option module-init-tools >= 3.7 is required.'
exit 1
fi
srcmods="$drivers_dir"
}
export srcmods
[[ $DRACUT_FIRMWARE_PATH ]] || export DRACUT_FIRMWARE_PATH="/lib/firmware/updates:/lib/firmware:/lib/firmware/$kernel"
# export standard hookdirs
[[ $hookdirs ]] || {
hookdirs="cmdline pre-udev pre-trigger netroot "
hookdirs+="initqueue initqueue/settled initqueue/online initqueue/finished initqueue/timeout "
hookdirs+="pre-mount pre-pivot cleanup mount "
hookdirs+="emergency shutdown-emergency pre-shutdown shutdown "
export hookdirs
}
DRACUT_LDD=${DRACUT_LDD:-ldd}
DRACUT_TESTBIN=${DRACUT_TESTBIN:-/bin/sh}
DRACUT_LDCONFIG=${DRACUT_LDCONFIG:-ldconfig}
. $dracutbasedir/dracut-functions.sh
# Detect lib paths
if ! [[ $libdirs ]] ; then
if [[ "$(ldd /bin/sh)" == */lib64/* ]] &>/dev/null \
&& [[ -d /lib64 ]]; then
libdirs+=" /lib64"
[[ -d /usr/lib64 ]] && libdirs+=" /usr/lib64"
else
libdirs+=" /lib"
[[ -d /usr/lib ]] && libdirs+=" /usr/lib"
fi
libdirs+=" $(ldconfig_paths)"
export libdirs
fi
# helper function for check() in module-setup.sh
# to check for required installed binaries
# issues a standardized warning message
require_binaries() {
local _module_name="${moddir##*/}"
local _ret=0
if [[ "$1" = "-m" ]]; then
_module_name="$2"
shift 2
fi
for cmd in "$@"; do
if ! find_binary "$cmd" &>/dev/null; then
dinfo "dracut module '${_module_name#[0-9][0-9]}' will not be installed, because command '$cmd' could not be found!"
((_ret++))
fi
done
return $_ret
}
require_any_binary() {
local _module_name="${moddir##*/}"
local _ret=1
if [[ "$1" = "-m" ]]; then
_module_name="$2"
shift 2
fi
for cmd in "$@"; do
if find_binary "$cmd" &>/dev/null; then
_ret=0
break
fi
done
if (( $_ret != 0 )); then
dinfo "$_module_name: Could not find any command of '$@'!"
return 1
fi
return 0
}
dracut_need_initqueue() {
>"$initdir/lib/dracut/need-initqueue"
}
dracut_module_included() {
[[ " $mods_to_load $modules_loaded " == *\ $*\ * ]]
}
dracut_no_switch_root() {
>"$initdir/lib/dracut/no-switch-root"
}
dracut_module_path() {
echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; }
}
if ! [[ $DRACUT_INSTALL ]]; then
DRACUT_INSTALL=$(find_binary dracut-install)
fi
if ! [[ $DRACUT_INSTALL ]] && [[ -x $dracutbasedir/dracut-install ]]; then
DRACUT_INSTALL=$dracutbasedir/dracut-install
elif ! [[ $DRACUT_INSTALL ]] && [[ -x $dracutbasedir/install/dracut-install ]]; then
DRACUT_INSTALL=$dracutbasedir/install/dracut-install
fi
if ! [[ -x $DRACUT_INSTALL ]]; then
dfatal "dracut-install not found!"
exit 10
fi
if [[ $hostonly == "-h" ]]; then
if ! [[ $DRACUT_KERNEL_MODALIASES ]] || ! [[ -f "$DRACUT_KERNEL_MODALIASES" ]]; then
export DRACUT_KERNEL_MODALIASES="${DRACUT_TMPDIR}/modaliases"
$DRACUT_INSTALL ${srcmods:+--kerneldir "$srcmods"} --modalias > "$DRACUT_KERNEL_MODALIASES"
fi
fi
[[ $DRACUT_RESOLVE_LAZY ]] || export DRACUT_RESOLVE_DEPS=1
inst_dir() {
[[ -e ${initdir}/"$1" ]] && return 0 # already there
$DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@"
(($? != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} -d "$@" || :
}
inst() {
local _hostonly_install
if [[ "$1" == "-H" ]]; then
_hostonly_install="-H"
shift
fi
[[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"
(($? != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" || :
}
inst_simple() {
local _hostonly_install
if [[ "$1" == "-H" ]]; then
_hostonly_install="-H"
shift
fi
[[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
[[ -e $1 ]] || return 1 # no source
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${_hostonly_install:+-H} "$@"
(($? != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${_hostonly_install:+-H} "$@" || :
}
inst_symlink() {
local _hostonly_install
if [[ "$1" == "-H" ]]; then
_hostonly_install="-H"
shift
fi
[[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
[[ -L $1 ]] || return 1
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"
(($? != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" || :
}
inst_multiple() {
local _ret
$DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"
_ret=$?
(($_ret != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} -a ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" || :
return $_ret
}
dracut_install() {
inst_multiple "$@"
}
dracut_instmods() {
local _silent=0;
local i;
[[ $no_kernel = yes ]] && return
for i in "$@"; do
[[ $i == "--silent" ]] && _silent=1
done
$DRACUT_INSTALL \
${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${srcmods:+--kerneldir "$srcmods"} -m "$@"
(($? != 0)) && (($_silent == 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${hostonly:+-H} ${omit_drivers:+-N "$omit_drivers"} ${srcmods:+--kerneldir "$srcmods"} -m "$@" || :
}
inst_library() {
local _hostonly_install
if [[ "$1" == "-H" ]]; then
_hostonly_install="-H"
shift
fi
[[ -e ${initdir}/"${2:-$1}" ]] && return 0 # already there
[[ -e $1 ]] || return 1 # no source
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@"
(($? != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} ${_hostonly_install:+-H} "$@" || :
}
inst_binary() {
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"
(($? != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@" || :
}
inst_script() {
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@"
(($? != 0)) && derror FAILED: $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$@" || :
}
inst_fsck_help() {
local _helper="/run/dracut/fsck/fsck_help_$1.txt"
$DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$2" $_helper
(($? != 0)) && derror $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${loginstall:+-L "$loginstall"} ${DRACUT_RESOLVE_DEPS:+-l} ${DRACUT_FIPS_MODE:+-f} "$2" $_helper || :
}
# Use with form hostonly="$(optional_hostonly)" inst_xxxx
# If hosotnly mode is set to "strict", hostonly restrictions will still
# be applied, else will ignore hostonly mode and try to install all
# given modules.
optional_hostonly() {
if [[ $hostonly_mode = "strict" ]]; then
printf -- "$hostonly"
else
printf ""
fi
}
mark_hostonly() {
for i in "$@"; do
echo "$i" >> "$initdir/lib/dracut/hostonly-files"
done
}
# find symlinks linked to given library file
# $1 = library file
# Function searches for symlinks by stripping version numbers appended to
# library filename, checks if it points to the same target and finally
# prints the list of symlinks to stdout.
#
# Example:
# rev_lib_symlinks libfoo.so.8.1
# output: libfoo.so.8 libfoo.so
# (Only if libfoo.so.8 and libfoo.so exists on host system.)
rev_lib_symlinks() {
[[ ! $1 ]] && return 0
local fn="$1" orig="$(readlink -f "$1")" links=''
[[ ${fn} == *.so.* ]] || return 1
until [[ ${fn##*.} == so ]]; do
fn="${fn%.*}"
[[ -L ${fn} && $(readlink -f "${fn}") == ${orig} ]] && links+=" ${fn}"
done
echo "${links}"
}
# attempt to install any programs specified in a udev rule
inst_rule_programs() {
local _prog _bin
for _prog in $(sed -nr 's/.*PROGRAM==?"([^ "]+).*/\1/p' "$1"); do
_bin=""
if [ -x ${udevdir}/$_prog ]; then
_bin=${udevdir}/$_prog
elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then
_bin=$(find_binary "$_prog") || {
dinfo "Skipping program $_prog using in udev rule ${1##*/} as it cannot be found"
continue;
}
fi
[[ $_bin ]] && inst_binary "$_bin"
done
for _prog in $(sed -nr 's/.*RUN[+=]=?"([^ "]+).*/\1/p' "$1"); do
_bin=""
if [ -x ${udevdir}/$_prog ]; then
_bin=${udevdir}/$_prog
elif [[ "${_prog/\$env\{/}" == "$_prog" ]] && [[ "${_prog}" != "/sbin/initqueue" ]]; then
_bin=$(find_binary "$_prog") || {
dinfo "Skipping program $_prog using in udev rule ${1##*/} as it cannot be found"
continue;
}
fi
[[ $_bin ]] && inst_binary "$_bin"
done
for _prog in $(sed -nr 's/.*IMPORT\{program\}==?"([^ "]+).*/\1/p' "$1"); do
_bin=""
if [ -x ${udevdir}/$_prog ]; then
_bin=${udevdir}/$_prog
elif [[ "${_prog/\$env\{/}" == "$_prog" ]]; then
_bin=$(find_binary "$_prog") || {
dinfo "Skipping program $_prog using in udev rule ${1##*/} as it cannot be found"
continue;
}
fi
[[ $_bin ]] && dracut_install "$_bin"
done
}
# attempt to install any programs specified in a udev rule
inst_rule_group_owner() {
local i
for i in $(sed -nr 's/.*OWNER=?"([^ "]+).*/\1/p' "$1"); do
if ! grep -Eq "^$i:" "$initdir/etc/passwd" 2>/dev/null; then
grep -E "^$i:" /etc/passwd 2>/dev/null >> "$initdir/etc/passwd"
fi
done
for i in $(sed -nr 's/.*GROUP=?"([^ "]+).*/\1/p' "$1"); do
if ! grep -Eq "^$i:" "$initdir/etc/group" 2>/dev/null; then
grep -E "^$i:" /etc/group 2>/dev/null >> "$initdir/etc/group"
fi
done
}
inst_rule_initqueue() {
if grep -q -F initqueue "$1"; then
dracut_need_initqueue
fi
}
# udev rules always get installed in the same place, so
# create a function to install them to make life simpler.
inst_rules() {
local _target=/etc/udev/rules.d _rule _found
inst_dir "${udevdir}/rules.d"
inst_dir "$_target"
for _rule in "$@"; do
if [ "${_rule#/}" = "$_rule" ]; then
for r in ${udevdir}/rules.d ${hostonly:+/etc/udev/rules.d}; do
[[ -e $r/$_rule ]] || continue
_found="$r/$_rule"
inst_rule_programs "$_found"
inst_rule_group_owner "$_found"
inst_rule_initqueue "$_found"
inst_simple "$_found"
done
fi
for r in '' $dracutbasedir/rules.d/; do
# skip rules without an absolute path
[[ "${r}$_rule" != /* ]] && continue
[[ -f ${r}$_rule ]] || continue
_found="${r}$_rule"
inst_rule_programs "$_found"
inst_rule_group_owner "$_found"
inst_rule_initqueue "$_found"
inst_simple "$_found" "$_target/${_found##*/}"
done
[[ $_found ]] || dinfo "Skipping udev rule: $_rule"
done
}
inst_rules_wildcard() {
local _target=/etc/udev/rules.d _rule _found
inst_dir "${udevdir}/rules.d"
inst_dir "$_target"
for _rule in ${udevdir}/rules.d/$1 ${dracutbasedir}/rules.d/$1 ; do
[[ -e $_rule ]] || continue
inst_rule_programs "$_rule"
inst_rule_group_owner "$_rule"
inst_rule_initqueue "$_rule"
inst_simple "$_rule"
_found=$_rule
done
if [[ -n ${hostonly} ]] ; then
for _rule in ${_target}/$1 ; do
[[ -f $_rule ]] || continue
inst_rule_programs "$_rule"
inst_rule_group_owner "$_rule"
inst_rule_initqueue "$_rule"
inst_simple "$_rule"
_found=$_rule
done
fi
[[ $_found ]] || dinfo "Skipping udev rule: $_rule"
}
# make sure that library links are correct and up to date
build_ld_cache() {
for f in "$dracutsysrootdir"/etc/ld.so.conf "$dracutsysrootdir"/etc/ld.so.conf.d/*; do
[[ -f $f ]] && inst_simple "${f#$dracutsysrootdir}"
done
if ! ldconfig -r "$initdir" -f /etc/ld.so.conf; then
if [[ $EUID == 0 ]]; then
derror "ldconfig exited ungracefully"
else
derror "ldconfig might need uid=0 (root) for chroot()"
fi
fi
}
prepare_udev_rules() {
[ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version | { read v _ ; echo $v ; })
for f in "$@"; do
f="${initdir}/etc/udev/rules.d/$f"
[ -e "$f" ] || continue
while read line || [ -n "$line" ]; do
if [ "${line%%IMPORT PATH_ID}" != "$line" ]; then
if [ $UDEVVERSION -ge 174 ]; then
printf '%sIMPORT{builtin}="path_id"\n' "${line%%IMPORT PATH_ID}"
else
printf '%sIMPORT{program}="path_id %%p"\n' "${line%%IMPORT PATH_ID}"
fi
elif [ "${line%%IMPORT BLKID}" != "$line" ]; then
if [ $UDEVVERSION -ge 176 ]; then
printf '%sIMPORT{builtin}="blkid"\n' "${line%%IMPORT BLKID}"
else
printf '%sIMPORT{program}="/sbin/blkid -o udev -p $tempnode"\n' "${line%%IMPORT BLKID}"
fi
else
echo "$line"
fi
done < "${f}" > "${f}.new"
mv "${f}.new" "$f"
done
}
# install function specialized for hooks
# $1 = type of hook, $2 = hook priority (lower runs first), $3 = hook
# All hooks should be POSIX/SuS compliant, they will be sourced by init.
inst_hook() {
if ! [[ -f $3 ]]; then
dfatal "Cannot install a hook ($3) that does not exist."
dfatal "Aborting initrd creation."
exit 1
elif ! [[ "$hookdirs" == *$1* ]]; then
dfatal "No such hook type $1. Aborting initrd creation."
exit 1
fi
inst_simple "$3" "/lib/dracut/hooks/${1}/${2}-${3##*/}"
}
# install any of listed files
#
# If first argument is '-d' and second some destination path, first accessible
# source is installed into this path, otherwise it will installed in the same
# path as source. If none of listed files was installed, function return 1.
# On first successful installation it returns with 0 status.
#
# Example:
#
# inst_any -d /bin/foo /bin/bar /bin/baz
#
# Lets assume that /bin/baz exists, so it will be installed as /bin/foo in
# initramfs.
inst_any() {
local to f
[[ $1 = '-d' ]] && to="$2" && shift 2
for f in "$@"; do
[[ -e $f ]] || continue
[[ $to ]] && inst "$f" "$to" && return 0
inst "$f" && return 0
done
return 1
}
# inst_libdir_file [-n ] [...]
# Install a located on a lib directory to the initramfs image
# -n install matching files
inst_libdir_file() {
local _files
if [[ "$1" == "-n" ]]; then
local _pattern=$2
shift 2
for _dir in $libdirs; do
for _i in "$@"; do
for _f in "$_dir"/$_i; do
[[ "$_f" =~ $_pattern ]] || continue
[[ -e "$_f" ]] && _files+="$_f "
done
done
done
else
for _dir in $libdirs; do
for _i in "$@"; do
for _f in "$_dir"/$_i; do
[[ -e "$_f" ]] && _files+="$_f "
done
done
done
fi
[[ $_files ]] && inst_multiple $_files
}
# install function decompressing the target and handling symlinks
# $@ = list of compressed (gz or bz2) files or symlinks pointing to such files
#
# Function install targets in the same paths inside overlay but decompressed
# and without extensions (.gz, .bz2).
inst_decompress() {
local _src _cmd
for _src in $@
do
case ${_src} in
*.gz) _cmd='gzip -f -d' ;;
*.bz2) _cmd='bzip2 -d' ;;
*) return 1 ;;
esac
inst_simple ${_src}
# Decompress with chosen tool. We assume that tool changes name e.g.
# from 'name.gz' to 'name'.
${_cmd} "${initdir}${_src}"
done
}
# It's similar to above, but if file is not compressed, performs standard
# install.
# $@ = list of files
inst_opt_decompress() {
local _src
for _src in $@; do
inst_decompress "${_src}" || inst "${_src}"
done
}
# module_check
# execute the check() function of module-setup.sh of
# or the "check" script, if module-setup.sh is not found
# "check $hostonly" is called
module_check() {
local _moddir=$(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
local _ret
local _forced=0
local _hostonly=$hostonly
[ $# -eq 2 ] && _forced=$2
[[ -d $_moddir ]] || return 1
if [[ ! -f $_moddir/module-setup.sh ]]; then
# if we do not have a check script, we are unconditionally included
[[ -x $_moddir/check ]] || return 0
[ $_forced -ne 0 ] && unset hostonly
$_moddir/check $hostonly
_ret=$?
else
unset check depends cmdline install installkernel
check() { true; }
. $_moddir/module-setup.sh
is_func check || return 0
[ $_forced -ne 0 ] && unset hostonly
moddir=$_moddir check $hostonly
_ret=$?
unset check depends cmdline install installkernel
fi
hostonly=$_hostonly
return $_ret
}
# module_check_mount
# execute the check() function of module-setup.sh of
# or the "check" script, if module-setup.sh is not found
# "mount_needs=1 check 0" is called
module_check_mount() {
local _moddir=$(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
local _ret
mount_needs=1
[[ -d $_moddir ]] || return 1
if [[ ! -f $_moddir/module-setup.sh ]]; then
# if we do not have a check script, we are unconditionally included
[[ -x $_moddir/check ]] || return 0
mount_needs=1 $_moddir/check 0
_ret=$?
else
unset check depends cmdline install installkernel
check() { false; }
. $_moddir/module-setup.sh
moddir=$_moddir check 0
_ret=$?
unset check depends cmdline install installkernel
fi
unset mount_needs
return $_ret
}
# module_depends
# execute the depends() function of module-setup.sh of
# or the "depends" script, if module-setup.sh is not found
module_depends() {
local _moddir=$(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
local _ret
[[ -d $_moddir ]] || return 1
if [[ ! -f $_moddir/module-setup.sh ]]; then
# if we do not have a check script, we have no deps
[[ -x $_moddir/check ]] || return 0
$_moddir/check -d
return $?
else
unset check depends cmdline install installkernel
depends() { true; }
. $_moddir/module-setup.sh
moddir=$_moddir depends
_ret=$?
unset check depends cmdline install installkernel
return $_ret
fi
}
# module_cmdline
# execute the cmdline() function of module-setup.sh of
# or the "cmdline" script, if module-setup.sh is not found
module_cmdline() {
local _moddir=$(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
local _ret
[[ -d $_moddir ]] || return 1
if [[ ! -f $_moddir/module-setup.sh ]]; then
[[ -x $_moddir/cmdline ]] && . "$_moddir/cmdline"
return $?
else
unset check depends cmdline install installkernel
cmdline() { true; }
. $_moddir/module-setup.sh
moddir=$_moddir cmdline
_ret=$?
unset check depends cmdline install installkernel
return $_ret
fi
}
# module_install
# execute the install() function of module-setup.sh of
# or the "install" script, if module-setup.sh is not found
module_install() {
local _moddir=$(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
local _ret
[[ -d $_moddir ]] || return 1
if [[ ! -f $_moddir/module-setup.sh ]]; then
[[ -x $_moddir/install ]] && . "$_moddir/install"
return $?
else
unset check depends cmdline install installkernel
install() { true; }
. $_moddir/module-setup.sh
moddir=$_moddir install
_ret=$?
unset check depends cmdline install installkernel
return $_ret
fi
}
# module_installkernel
# execute the installkernel() function of module-setup.sh of
# or the "installkernel" script, if module-setup.sh is not found
module_installkernel() {
local _moddir=$(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
local _ret
[[ -d $_moddir ]] || return 1
if [[ ! -f $_moddir/module-setup.sh ]]; then
[[ -x $_moddir/installkernel ]] && . "$_moddir/installkernel"
return $?
else
unset check depends cmdline install installkernel
installkernel() { true; }
. $_moddir/module-setup.sh
moddir=$_moddir installkernel
_ret=$?
unset check depends cmdline install installkernel
return $_ret
fi
}
# check_mount
# check_mount checks, if a dracut module is needed for the given
# device and filesystem types in "${host_fs_types[@]}"
check_mount() {
local _mod=$1
local _moddir=$(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
local _ret
local _moddep
[ "${#host_fs_types[@]}" -le 0 ] && return 1
# If we are already scheduled to be loaded, no need to check again.
[[ " $mods_to_load " == *\ $_mod\ * ]] && return 0
[[ " $mods_checked_as_dep " == *\ $_mod\ * ]] && return 1
# This should never happen, but...
[[ -d $_moddir ]] || return 1
[[ $2 ]] || mods_checked_as_dep+=" $_mod "
if [[ " $omit_dracutmodules " == *\ $_mod\ * ]]; then
return 1
fi
if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\ $_mod\ * ]]; then
module_check_mount $_mod; ret=$?
# explicit module, so also accept ret=255
[[ $ret = 0 || $ret = 255 ]] || return 1
else
# module not in our list
if [[ $dracutmodules = all ]]; then
# check, if we can and should install this module
module_check_mount $_mod || return 1
else
# skip this module
return 1
fi
fi
for _moddep in $(module_depends $_mod); do
# handle deps as if they were manually added
[[ " $dracutmodules " == *\ $_mod\ * ]] \
&& [[ " $dracutmodules " != *\ $_moddep\ * ]] \
&& dracutmodules+=" $_moddep "
[[ " $add_dracutmodules " == *\ $_mod\ * ]] \
&& [[ " $add_dracutmodules " != *\ $_moddep\ * ]] \
&& add_dracutmodules+=" $_moddep "
[[ " $force_add_dracutmodules " == *\ $_mod\ * ]] \
&& [[ " $force_add_dracutmodules " != *\ $_moddep\ * ]] \
&& force_add_dracutmodules+=" $_moddep "
# if a module we depend on fail, fail also
if ! check_module $_moddep; then
derror "dracut module '$_mod' depends on '$_moddep', which can't be installed"
return 1
fi
done
[[ " $mods_to_load " == *\ $_mod\ * ]] || \
mods_to_load+=" $_mod "
return 0
}
# check_module []
# check if a dracut module is to be used in the initramfs process
# if is set, then the process also keeps track
# that the modules were checked for the dependency tracking process
check_module() {
local _mod=$1
local _moddir=$(echo ${dracutbasedir}/modules.d/??${1} | { read a b; echo "$a"; })
local _ret
local _moddep
# If we are already scheduled to be loaded, no need to check again.
[[ " $mods_to_load " == *\ $_mod\ * ]] && return 0
[[ " $mods_checked_as_dep " == *\ $_mod\ * ]] && return 1
# This should never happen, but...
[[ -d $_moddir ]] || return 1
[[ $2 ]] || mods_checked_as_dep+=" $_mod "
if [[ " $omit_dracutmodules " == *\ $_mod\ * ]]; then
dinfo "dracut module '$_mod' will not be installed, because it's in the list to be omitted!"
return 1
fi
if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules" == *\ $_mod\ * ]]; then
if [[ " $dracutmodules $force_add_dracutmodules " == *\ $_mod\ * ]]; then
module_check $_mod 1; ret=$?
else
module_check $_mod 0; ret=$?
fi
# explicit module, so also accept ret=255
[[ $ret = 0 || $ret = 255 ]] || return 1
else
# module not in our list
if [[ $dracutmodules = all ]]; then
# check, if we can and should install this module
module_check $_mod; ret=$?
if [[ $ret != 0 ]]; then
[[ $2 ]] && return 1
[[ $ret != 255 ]] && return 1
fi
else
# skip this module
return 1
fi
fi
for _moddep in $(module_depends $_mod); do
# handle deps as if they were manually added
[[ " $dracutmodules " == *\ $_mod\ * ]] \
&& [[ " $dracutmodules " != *\ $_moddep\ * ]] \
&& dracutmodules+=" $_moddep "
[[ " $add_dracutmodules " == *\ $_mod\ * ]] \
&& [[ " $add_dracutmodules " != *\ $_moddep\ * ]] \
&& add_dracutmodules+=" $_moddep "
[[ " $force_add_dracutmodules " == *\ $_mod\ * ]] \
&& [[ " $force_add_dracutmodules " != *\ $_moddep\ * ]] \
&& force_add_dracutmodules+=" $_moddep "
# if a module we depend on fail, fail also
if ! check_module $_moddep; then
derror "dracut module '$_mod' depends on '$_moddep', which can't be installed"
return 1
fi
done
[[ " $mods_to_load " == *\ $_mod\ * ]] || \
mods_to_load+=" $_mod "
return 0
}
# for_each_module_dir
# execute " 1"
for_each_module_dir() {
local _modcheck
local _mod
local _moddir
local _func
_func=$1
for _moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
[[ -d $_moddir ]] || continue;
[[ -e $_moddir/install || -e $_moddir/installkernel || \
-e $_moddir/module-setup.sh ]] || continue
_mod=${_moddir##*/}; _mod=${_mod#[0-9][0-9]}
$_func $_mod 1
done
# Report any missing dracut modules, the user has specified
_modcheck="$add_dracutmodules $force_add_dracutmodules"
[[ $dracutmodules != all ]] && _modcheck="$_modcheck $dracutmodules"
for _mod in $_modcheck; do
[[ " $mods_to_load " == *\ $_mod\ * ]] && continue
[[ " $force_add_dracutmodules " != *\ $_mod\ * ]] \
&& [[ " $dracutmodules " != *\ $_mod\ * ]] \
&& [[ " $omit_dracutmodules " == *\ $_mod\ * ]] \
&& continue
derror "dracut module '$_mod' cannot be found or installed."
[[ " $force_add_dracutmodules " == *\ $_mod\ * ]] && exit 1
[[ " $dracutmodules " == *\ $_mod\ * ]] && exit 1
[[ " $add_dracutmodules " == *\ $_mod\ * ]] && exit 1
done
}
# Install a single kernel module along with any firmware it may require.
# $1 = full path to kernel module to install
install_kmod_with_fw() {
# no need to go further if the module is already installed
[[ -e "${initdir}/lib/modules/$kernel/${1##*/lib/modules/$kernel/}" ]] \
&& return 0
if [[ $omit_drivers ]]; then
local _kmod=${1##*/}
_kmod=${_kmod%.ko*}
_kmod=${_kmod/-/_}
if [[ "$_kmod" =~ $omit_drivers ]]; then
dinfo "Omitting driver $_kmod"
return 0
fi
if [[ "${1##*/lib/modules/$kernel/}" =~ $omit_drivers ]]; then
dinfo "Omitting driver $_kmod"
return 0
fi
fi
if [[ $silent_omit_drivers ]]; then
local _kmod=${1##*/}
_kmod=${_kmod%.ko*}
_kmod=${_kmod/-/_}
[[ "$_kmod" =~ $silent_omit_drivers ]] && return 0
[[ "${1##*/lib/modules/$kernel/}" =~ $silent_omit_drivers ]] && return 0
fi
inst_simple "$1" "/lib/modules/$kernel/${1##*/lib/modules/$kernel/}"
ret=$?
(($ret != 0)) && return $ret
local _modname=${1##*/} _fwdir _found _fw
_modname=${_modname%.ko*}
for _fw in $(modinfo -k $kernel -F firmware $1 2>/dev/null); do
_found=''
for _fwdir in $fw_dir; do
[[ -d $_fwdir && -f $_fwdir/$_fw ]] || continue
inst_simple "$_fwdir/$_fw" "/lib/firmware/$_fw"
_found=yes
done
if [[ $_found != yes ]]; then
if ! [[ -d $(echo /sys/module/${_modname//-/_}|{ read a b; echo $a; }) ]]; then
dinfo "Possible missing firmware \"${_fw}\" for kernel module" \
"\"${_modname}.ko\""
else
dwarn "Possible missing firmware \"${_fw}\" for kernel module" \
"\"${_modname}.ko\""
fi
fi
done
return 0
}
# Do something with all the dependencies of a kernel module.
# Note that kernel modules depend on themselves using the technique we use
# $1 = function to call for each dependency we find
# It will be passed the full path to the found kernel module
# $2 = module to get dependencies for
# rest of args = arguments to modprobe
# _fderr specifies FD passed from surrounding scope
for_each_kmod_dep() {
local _func=$1 _kmod=$2 _cmd _modpath _options
shift 2
modprobe "$@" --ignore-install --show-depends $_kmod 2>&${_fderr} | (
while read _cmd _modpath _options || [ -n "$_cmd" ]; do
[[ $_cmd = insmod ]] || continue
$_func ${_modpath} || exit $?
done
)
}
dracut_kernel_post() {
for _f in modules.builtin.bin modules.builtin modules.order; do
[[ -e $srcmods/$_f ]] && inst_simple "$srcmods/$_f" "/lib/modules/$kernel/$_f"
done
# generate module dependencies for the initrd
if [[ -d $initdir/lib/modules/$kernel ]] && \
! depmod -a -b "$initdir" $kernel; then
dfatal "\"depmod -a $kernel\" failed."
exit 1
fi
}
instmods() {
# instmods [-c [-s]] [ ... ]
# instmods [-c [-s]]
# install kernel modules along with all their dependencies.
# can be e.g. "=block" or "=drivers/usb/storage"
# -c check
# -s silent
local _optional="-o"
local _silent
local _ret
[[ $no_kernel = yes ]] && return
if [[ $1 = '-c' ]]; then
unset _optional
shift
fi
if [[ $1 = '-s' ]]; then
_silent=1
shift
fi
if (($# == 0)); then
read -r -d '' -a args
set -- "${args[@]}"
fi
if (($# == 0)); then
return 0
fi
$DRACUT_INSTALL \
${initdir:+-D "$initdir"} \
${loginstall:+-L "$loginstall"} \
${hostonly:+-H} \
${omit_drivers:+-N "$omit_drivers"} \
${srcmods:+--kerneldir "$srcmods"} \
${_optional:+-o} \
${_silent:+--silent} \
-m "$@"
_ret=$?
if (($_ret != 0)) && [[ -z "$_silent" ]]; then
derror "FAILED: " \
$DRACUT_INSTALL \
${initdir:+-D "$initdir"} \
${loginstall:+-L "$loginstall"} \
${hostonly:+-H} \
${omit_drivers:+-N "$omit_drivers"} \
${srcmods:+--kerneldir "$srcmods"} \
${_optional:+-o} \
${_silent:+--silent} \
-m "$@"
fi
[[ "$optional" ]] && return 0
return $_ret
}
if [[ "$(ln --help)" == *--relative* ]]; then
ln_r() {
ln -sfnr "${initdir}/$1" "${initdir}/$2"
}
else
ln_r() {
local _source=$1
local _dest=$2
[[ -d "${_dest%/*}" ]] && _dest=$(readlink -f "${_dest%/*}")/${_dest##*/}
ln -sfn -- "$(convert_abs_rel "${_dest}" "${_source}")" "${initdir}/${_dest}"
}
fi
dracut.conf.d/99-microcode-override.conf 0000644 00000000425 15023162470 0014064 0 ustar 00 ## Uncomment the following line in order to disable
## microcode_ctl module that is used for $fw_dir variable overriding.
##
## Please refer to /usr/share/doc/microcode_ctl/README.caveats
## for additional information.
##
#omit_dracutmodules+=' microcode_ctl-fw_dir_override '
dracut.conf.d/02-rescue.conf 0000644 00000000032 15023162470 0011543 0 ustar 00 dracut_rescue_image="yes"
dracut.conf.d/50-nss-softokn.conf 0000644 00000000101 15023162470 0012541 0 ustar 00 # turn on nss-softokn module
add_dracutmodules+=" nss-softokn "
dracut.conf.d/01-dist.conf 0000644 00000001030 15023162470 0011216 0 ustar 00 # dracut config file customized for RedHat/Fedora.
# i18n
i18n_vars="/etc/sysconfig/keyboard:KEYTABLE-KEYMAP /etc/sysconfig/i18n:SYSFONT-FONT,FONTACM-FONT_MAP,FONT_UNIMAP"
i18n_default_font="eurlatgr"
i18n_install_all="yes"
stdloglvl=3
sysloglvl=5
install_optional_items+=" vi /etc/virc ps grep cat rm "
prefix="/"
systemdutildir=/usr/lib/systemd
systemdsystemunitdir=/usr/lib/systemd/system
systemdsystemconfdir=/etc/systemd/system
udevdir=/usr/lib/udev
hostonly="yes"
hostonly_cmdline="no"
early_microcode="yes"
reproducible="yes"
dracut.conf.d/01-microcode.conf 0000644 00000000026 15023162470 0012223 0 ustar 00 early_microcode="yes"
modules.d/90crypt/parse-crypt.sh 0000755 00000015741 15023162470 0012570 0 ustar 00 #!/bin/sh
type crypttab_contains >/dev/null 2>&1 || . /lib/dracut-crypt-lib.sh
_cryptgetargsname() {
debug_off
local _o _found _key
unset _o
unset _found
CMDLINE=$(getcmdline)
_key="$1"
set --
for _o in $CMDLINE; do
if [ "$_o" = "$_key" ]; then
_found=1;
elif [ "${_o%=*}" = "${_key%=}" ]; then
[ -n "${_o%=*}" ] && set -- "$@" "${_o#*=}";
_found=1;
fi
done
if [ -n "$_found" ]; then
[ $# -gt 0 ] && printf '%s' "$*"
return 0
fi
return 1;
}
if ! getargbool 1 rd.luks -d -n rd_NO_LUKS; then
info "rd.luks=0: removing cryptoluks activation"
rm -f -- /etc/udev/rules.d/70-luks.rules
else
{
echo 'SUBSYSTEM!="block", GOTO="luks_end"'
echo 'ACTION!="add|change", GOTO="luks_end"'
} > /etc/udev/rules.d/70-luks.rules.new
PARTUUID=$(getargs rd.luks.partuuid -d rd_LUKS_PARTUUID)
SERIAL=$(getargs rd.luks.serial -d rd_LUKS_SERIAL)
LUKS=$(getargs rd.luks.uuid -d rd_LUKS_UUID)
tout=$(getarg rd.luks.key.tout)
if [ -e /etc/crypttab ]; then
while read -r _ _dev _ || [ -n "$_dev" ]; do
set_systemd_timeout_for_dev "$_dev"
done < /etc/crypttab
fi
if [ -n "$PARTUUID" ]; then
for uuid in $PARTUUID; do
uuid=${uuid##luks-}
if luksname=$(_cryptgetargsname "rd.luks.name=$uuid="); then
luksname="${luksname#$uuid=}"
else
luksname="luks-$uuid"
fi
if [ -z "$DRACUT_SYSTEMD" ]; then
{
printf -- 'ENV{ID_PART_ENTRY_UUID}=="*%s*", ' "$uuid"
printf -- 'RUN+="%s --settled --unique --onetime ' "$(command -v initqueue)"
printf -- '--name cryptroot-ask-%%k %s ' "$(command -v cryptroot-ask)"
printf -- '$env{DEVNAME} %s %s"\n' "$luksname" "$tout"
} >> /etc/udev/rules.d/70-luks.rules.new
else
luksname=$(dev_unit_name "$luksname")
luksname="$(str_replace "$luksname" '\' '\\')"
if ! crypttab_contains "$uuid"; then
{
printf -- 'ENV{ID_PART_ENTRY_UUID}=="*%s*", ' "$uuid"
printf -- 'RUN+="%s --settled --unique --onetime ' "$(command -v initqueue)"
printf -- '--name systemd-cryptsetup-%%k %s start ' "$(command -v systemctl)"
printf -- 'systemd-cryptsetup@%s.service"\n' "$luksname"
} >> /etc/udev/rules.d/70-luks.rules.new
fi
fi
done
elif [ -n "$SERIAL" ]; then
for serialid in $SERIAL; do
serialid=${serialid##luks-}
if luksname=$(_cryptgetargsname "rd.luks.name=$serialid="); then
luksname="${luksname#$serialid=}"
else
luksname="luks-$serialid"
fi
if [ -z "$DRACUT_SYSTEMD" ]; then
{
printf -- 'ENV{ID_SERIAL_SHORT}=="*%s*", ' "$serialid"
printf -- 'RUN+="%s --settled --unique --onetime ' "$(command -v initqueue)"
printf -- '--name cryptroot-ask-%%k %s ' "$(command -v cryptroot-ask)"
printf -- '$env{DEVNAME} %s %s"\n' "$luksname" "$tout"
} >> /etc/udev/rules.d/70-luks.rules.new
else
luksname=$(dev_unit_name "$luksname")
luksname="$(str_replace "$luksname" '\' '\\')"
if ! crypttab_contains "$serialid"; then
{
printf -- 'ENV{ID_SERIAL_SHORT}=="*%s*", ' "$serialid"
printf -- 'RUN+="%s --settled --unique --onetime ' "$(command -v initqueue)"
printf -- '--name systemd-cryptsetup-%%k %s start ' "$(command -v systemctl)"
printf -- 'systemd-cryptsetup@%s.service"\n' "$luksname"
} >> /etc/udev/rules.d/70-luks.rules.new
fi
fi
done
elif [ -n "$LUKS" ]; then
for luksid in $LUKS; do
luksid=${luksid##luks-}
if luksname=$(_cryptgetargsname "rd.luks.name=$luksid="); then
luksname="${luksname#$luksid=}"
else
luksname="luks-$luksid"
fi
if [ -z "$DRACUT_SYSTEMD" ]; then
{
printf -- 'ENV{ID_FS_TYPE}=="crypto_LUKS", '
printf -- 'ENV{ID_FS_UUID}=="*%s*", ' "$luksid"
printf -- 'RUN+="%s --settled --unique --onetime ' "$(command -v initqueue)"
printf -- '--name cryptroot-ask-%%k %s ' "$(command -v cryptroot-ask)"
printf -- '$env{DEVNAME} %s %s"\n' "$luksname" "$tout"
} >> /etc/udev/rules.d/70-luks.rules.new
else
luksname=$(dev_unit_name "$luksname")
luksname="$(str_replace "$luksname" '\' '\\')"
if ! crypttab_contains "$luksid"; then
{
printf -- 'ENV{ID_FS_TYPE}=="crypto_LUKS", '
printf -- 'ENV{ID_FS_UUID}=="*%s*", ' "$luksid"
printf -- 'RUN+="%s --settled --unique --onetime ' "$(command -v initqueue)"
printf -- '--name systemd-cryptsetup-%%k %s start ' "$(command -v systemctl)"
printf -- 'systemd-cryptsetup@%s.service"\n' "$luksname"
} >> /etc/udev/rules.d/70-luks.rules.new
fi
fi
uuid=$luksid
while [ "$uuid" != "${uuid#*-}" ]; do uuid=${uuid%%-*}${uuid#*-}; done
printf -- '[ -e /dev/disk/by-id/dm-uuid-CRYPT-LUKS?-*%s*-* ] || exit 1\n' $uuid \
>> "$hookdir/initqueue/finished/90-crypt.sh"
{
printf -- '[ -e /dev/disk/by-uuid/*%s* ] || ' $luksid
printf -- 'warn "crypto LUKS UUID "%s" not found"\n' $luksid
} >> "$hookdir/emergency/90-crypt.sh"
done
elif getargbool 0 rd.auto; then
if [ -z "$DRACUT_SYSTEMD" ]; then
{
printf -- 'ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="%s ' "$(command -v initqueue)"
printf -- '--unique --settled --onetime --name cryptroot-ask-%%k '
printf -- '%s $env{DEVNAME} luks-$env{ID_FS_UUID} %s"\n' "$(command -v cryptroot-ask)" "$tout"
} >> /etc/udev/rules.d/70-luks.rules.new
else
{
printf -- 'ENV{ID_FS_TYPE}=="crypto_LUKS", RUN+="%s ' "$(command -v initqueue)"
printf -- '--unique --settled --onetime --name crypt-run-generator-%%k '
printf -- '%s $env{DEVNAME} luks-$env{ID_FS_UUID}"\n' "$(command -v crypt-run-generator)"
} >> /etc/udev/rules.d/70-luks.rules.new
fi
fi
echo 'LABEL="luks_end"' >> /etc/udev/rules.d/70-luks.rules.new
mv /etc/udev/rules.d/70-luks.rules.new /etc/udev/rules.d/70-luks.rules
fi
modules.d/90crypt/cryptroot-ask.sh 0000755 00000011406 15023162470 0013132 0 ustar 00 #!/bin/sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin
NEWROOT=${NEWROOT:-"/sysroot"}
# do not ask, if we already have root
[ -f $NEWROOT/proc ] && exit 0
. /lib/dracut-lib.sh
# if device name is /dev/dm-X, convert to /dev/mapper/name
if [ "${1##/dev/dm-}" != "$1" ]; then
device="/dev/mapper/$(dmsetup info -c --noheadings -o name "$1")"
else
device="$1"
fi
# default luksname - luks-UUID
luksname=$2
# number of tries
numtries=${3:-10}
# TODO: improve to support what cmdline does
if [ -f /etc/crypttab ] && getargbool 1 rd.luks.crypttab -d -n rd_NO_CRYPTTAB; then
while read name dev luksfile luksoptions || [ -n "$name" ]; do
# ignore blank lines and comments
if [ -z "$name" -o "${name#\#}" != "$name" ]; then
continue
fi
# PARTUUID used in crypttab
if [ "${dev%%=*}" = "PARTUUID" ]; then
if [ "luks-${dev##PARTUUID=}" = "$luksname" ]; then
luksname="$name"
break
fi
# UUID used in crypttab
elif [ "${dev%%=*}" = "UUID" ]; then
if [ "luks-${dev##UUID=}" = "$luksname" ]; then
luksname="$name"
break
fi
# ID used in crypttab
elif [ "${dev%%=*}" = "ID" ]; then
if [ "luks-${dev##ID=}" = "$luksname" ]; then
luksname="$name"
break
fi
# path used in crypttab
else
cdev=$(readlink -f $dev)
mdev=$(readlink -f $device)
if [ "$cdev" = "$mdev" ]; then
luksname="$name"
break
fi
fi
done < /etc/crypttab
unset name dev
fi
# check if destination already exists
[ -b /dev/mapper/$luksname ] && exit 0
# we already asked for this device
asked_file=/tmp/cryptroot-asked-$luksname
[ -f $asked_file ] && exit 0
# load dm_crypt if it is not already loaded
[ -d /sys/module/dm_crypt ] || modprobe dm_crypt
. /lib/dracut-crypt-lib.sh
#
# Open LUKS device
#
info "luksOpen $device $luksname $luksfile $luksoptions"
OLD_IFS="$IFS"
IFS=,
set -- $luksoptions
IFS="$OLD_IFS"
while [ $# -gt 0 ]; do
case $1 in
noauto)
# skip this
exit 0
;;
swap)
# skip this
exit 0
;;
tmp)
# skip this
exit 0
;;
allow-discards)
allowdiscards="--allow-discards"
;;
header=*)
cryptsetupopts="${cryptsetupopts} --${1}"
;;
esac
shift
done
# parse for allow-discards
if strstr "$(cryptsetup --help)" "allow-discards"; then
if discarduuids=$(getargs "rd.luks.allow-discards"); then
discarduuids=$(str_replace "$discarduuids" 'luks-' '')
if strstr " $discarduuids " " ${luksdev##luks-}"; then
allowdiscards="--allow-discards"
fi
elif getargbool 0 rd.luks.allow-discards; then
allowdiscards="--allow-discards"
fi
fi
if strstr "$(cryptsetup --help)" "allow-discards"; then
cryptsetupopts="$cryptsetupopts $allowdiscards"
fi
unset allowdiscards
# fallback to passphrase
ask_passphrase=1
if [ -n "$luksfile" -a "$luksfile" != "none" -a -e "$luksfile" ]; then
if cryptsetup --key-file "$luksfile" $cryptsetupopts luksOpen "$device" "$luksname"; then
ask_passphrase=0
fi
else
while [ -n "$(getarg rd.luks.key)" ]; do
if tmp=$(getkey /tmp/luks.keys $device); then
keydev="${tmp%%:*}"
keypath="${tmp#*:}"
else
if [ $numtries -eq 0 ]; then
warn "No key found for $device. Fallback to passphrase mode."
break
fi
sleep 1
info "No key found for $device. Will try $numtries time(s) more later."
initqueue --unique --onetime --settled \
--name cryptroot-ask-$luksname \
$(command -v cryptroot-ask) "$device" "$luksname" "$(($numtries-1))"
exit 0
fi
unset tmp
info "Using '$keypath' on '$keydev'"
readkey "$keypath" "$keydev" "$device" \
| cryptsetup -d - $cryptsetupopts luksOpen "$device" "$luksname"
unset keypath keydev
ask_passphrase=0
break
done
fi
if [ $ask_passphrase -ne 0 ]; then
luks_open="$(command -v cryptsetup) $cryptsetupopts luksOpen"
_timeout=$(getargs "rd.luks.timeout")
_timeout=${_timeout:-0}
ask_for_password --ply-tries 5 \
--ply-cmd "$luks_open -T1 $device $luksname" \
--ply-prompt "Password ($device)" \
--tty-tries 1 \
--tty-cmd "$luks_open -T5 -t $_timeout $device $luksname"
unset luks_open
unset _timeout
fi
unset device luksname luksfile
# mark device as asked
>> $asked_file
need_shutdown
udevsettle
exit 0
modules.d/90crypt/crypt-cleanup.sh 0000755 00000000672 15023162470 0013102 0 ustar 00 #!/bin/sh
# close everything which is not busy
rm -f -- /etc/udev/rules.d/70-luks.rules >/dev/null 2>&1
if ! getarg rd.luks.uuid -d rd_LUKS_UUID >/dev/null 2>&1 && getargbool 1 rd.luks -d -n rd_NO_LUKS >/dev/null 2>&1; then
while true; do
local do_break="y"
for i in /dev/mapper/luks-*; do
cryptsetup luksClose $i >/dev/null 2>&1 && do_break=n
done
[ "$do_break" = "y" ] && break
done
fi
modules.d/90crypt/parse-keydev.sh 0000755 00000002541 15023162470 0012710 0 ustar 00 #!/bin/sh
if getargbool 1 rd.luks -n rd_NO_LUKS && \
[ -n "$(getarg rd.luks.key)" ]; then
exec 7>/etc/udev/rules.d/65-luks-keydev.rules
echo 'SUBSYSTEM!="block", GOTO="luks_keydev_end"' >&7
echo 'ACTION!="add|change", GOTO="luks_keydev_end"' >&7
for arg in $(getargs rd.luks.key); do
unset keypath keydev luksdev
splitsep : "$arg" keypath keydev luksdev
info "rd.luks.key: keypath='$keypath' keydev='$keydev' luksdev='$luksdev'"
if [ -z "$keypath" ]; then
warn 'keypath required!'
continue
fi
# A keydev of '/' is treated as the initrd itself
if [ "/" == "$keydev" ]; then
[ -z "$luksdev" ] && luksdev='*'
echo "$luksdev:$keydev:$keypath" >> /tmp/luks.keys
continue
elif [ -n "$keydev" ]; then
udevmatch "$keydev" >&7 || {
warn 'keydev incorrect!'
continue
}
printf ', ' >&7
fi
{
printf -- 'RUN+="%s --unique --onetime ' $(command -v initqueue)
printf -- '--name probe-keydev-%%k '
printf -- '%s /dev/%%k %s %s"\n' \
$(command -v probe-keydev) "${keypath}" "${luksdev}"
} >&7
done
unset arg keypath keydev luksdev
echo 'LABEL="luks_keydev_end"' >&7
exec 7>&-
fi
modules.d/90crypt/crypt-run-generator.sh 0000755 00000001402 15023162470 0014233 0 ustar 00 #!/bin/sh
. /lib/dracut-lib.sh
type crypttab_contains >/dev/null 2>&1 || . /lib/dracut-crypt-lib.sh
dev=$1
luks=$2
crypttab_contains "$luks" "$dev" && exit 0
allowdiscards="-"
# parse for allow-discards
if strstr "$(cryptsetup --help)" "allow-discards"; then
if discarduuids=$(getargs "rd.luks.allow-discards"); then
discarduuids=$(str_replace "$discarduuids" 'luks-' '')
if strstr " $discarduuids " " ${luks##luks-}"; then
allowdiscards="discard"
fi
elif getargbool 0 rd.luks.allow-discards; then
allowdiscards="discard"
fi
fi
echo "$luks $dev - timeout=0,$allowdiscards" >> /etc/crypttab
if command -v systemctl >/dev/null; then
systemctl daemon-reload
systemctl start cryptsetup.target
fi
exit 0
modules.d/90crypt/crypt-lib.sh 0000755 00000016743 15023162470 0012227 0 ustar 00 #!/bin/sh
command -v getarg >/dev/null || . /lib/dracut-lib.sh
# check if the crypttab contains an entry for a LUKS UUID
crypttab_contains() {
local luks="$1"
local dev="$2"
local l d rest
if [ -f /etc/crypttab ]; then
while read l d rest || [ -n "$l" ]; do
strstr "${l##luks-}" "${luks##luks-}" && return 0
strstr "$d" "${luks##luks-}" && return 0
if [ -n "$dev" ]; then
for _dev in $(devnames $d); do
[ "$dev" -ef "$_dev" ] && return 0
done
fi
if [ -e /etc/block_uuid.map ]; then
# search for line starting with $d
_line=$(sed -n "\,^$d .*$,{p}" /etc/block_uuid.map)
[ -z "$_line" ] && continue
# get second column with uuid
_uuid="$(echo $_line | sed 's,^.* \(.*$\),\1,')"
strstr "$_uuid" "${luks##luks-}" && return 0
fi
done < /etc/crypttab
fi
return 1
}
# ask_for_password
#
# Wraps around plymouth ask-for-password and adds fallback to tty password ask
# if plymouth is not present.
#
# --cmd command
# Command to execute. Required.
# --prompt prompt
# Password prompt. Note that function already adds ':' at the end.
# Recommended.
# --tries n
# How many times repeat command on its failure. Default is 3.
# --ply-[cmd|prompt|tries]
# Command/prompt/tries specific for plymouth password ask only.
# --tty-[cmd|prompt|tries]
# Command/prompt/tries specific for tty password ask only.
# --tty-echo-off
# Turn off input echo before tty command is executed and turn on after.
# It's useful when password is read from stdin.
ask_for_password() {
local cmd; local prompt; local tries=3
local ply_cmd; local ply_prompt; local ply_tries=3
local tty_cmd; local tty_prompt; local tty_tries=3
local ret
while [ $# -gt 0 ]; do
case "$1" in
--cmd) ply_cmd="$2"; tty_cmd="$2"; shift;;
--ply-cmd) ply_cmd="$2"; shift;;
--tty-cmd) tty_cmd="$2"; shift;;
--prompt) ply_prompt="$2"; tty_prompt="$2"; shift;;
--ply-prompt) ply_prompt="$2"; shift;;
--tty-prompt) tty_prompt="$2"; shift;;
--tries) ply_tries="$2"; tty_tries="$2"; shift;;
--ply-tries) ply_tries="$2"; shift;;
--tty-tries) tty_tries="$2"; shift;;
--tty-echo-off) tty_echo_off=yes;;
esac
shift
done
{ flock -s 9;
# Prompt for password with plymouth, if installed and running.
if type plymouth >/dev/null 2>&1 && plymouth --ping 2>/dev/null; then
plymouth ask-for-password \
--prompt "$ply_prompt" --number-of-tries=$ply_tries \
--command="$ply_cmd"
ret=$?
else
if [ "$tty_echo_off" = yes ]; then
stty_orig="$(stty -g)"
stty -echo
fi
local i=1
while [ $i -le $tty_tries ]; do
[ -n "$tty_prompt" ] && \
printf "$tty_prompt [$i/$tty_tries]:" >&2
eval "$tty_cmd" && ret=0 && break
ret=$?
i=$(($i+1))
[ -n "$tty_prompt" ] && printf '\n' >&2
done
[ "$tty_echo_off" = yes ] && stty $stty_orig
fi
} 9>/.console_lock
[ $ret -ne 0 ] && echo "Wrong password" >&2
return $ret
}
# Try to mount specified device (by path, by UUID or by label) and check
# the path with 'test'.
#
# example:
# test_dev -f LABEL="nice label" /some/file1
test_dev() {
local test_op=$1; local dev="$2"; local f="$3"
local ret=1; local mount_point=$(mkuniqdir /mnt testdev)
local path
[ -n "$dev" -a -n "$*" ] || return 1
[ -d "$mount_point" ] || die 'Mount point does not exist!'
if mount -r "$dev" "$mount_point" >/dev/null 2>&1; then
test $test_op "${mount_point}/${f}"
ret=$?
umount "$mount_point"
fi
rmdir "$mount_point"
return $ret
}
# match_dev devpattern dev
#
# Returns true if 'dev' matches 'devpattern'. Both 'devpattern' and 'dev' are
# expanded to kernel names and then compared. If name of 'dev' is on list of
# names of devices matching 'devpattern', the test is positive. 'dev' and
# 'devpattern' may be anything which function 'devnames' recognizes.
#
# If 'devpattern' is empty or '*' then function just returns true.
#
# Example:
# match_dev UUID=123 /dev/dm-1
# Returns true if /dev/dm-1 UUID starts with "123".
match_dev() {
[ -z "$1" -o "$1" = '*' ] && return 0
local devlist; local dev
devlist="$(devnames "$1")" || return 255
dev="$(devnames "$2")" || return 255
strstr "
$devlist
" "
$dev
"
}
# getkey keysfile for_dev
#
# Reads file produced by probe-keydev and looks for first line to
# which device matches. The successful result is printed in format
# ":". When nothing found, just false is returned.
#
# Example:
# getkey /tmp/luks.keys /dev/sdb1
# May print:
# /dev/sdc1:/keys/some.key
getkey() {
local keys_file="$1"; local for_dev="$2"
local luks_dev; local key_dev; local key_path
[ -z "$keys_file" -o -z "$for_dev" ] && die 'getkey: wrong usage!'
[ -f "$keys_file" ] || return 1
local IFS=:
while read luks_dev key_dev key_path || [ -n "$luks_dev" ]; do
if match_dev "$luks_dev" "$for_dev"; then
echo "${key_dev}:${key_path}"
return 0
fi
done < "$keys_file"
return 1
}
# readkey keypath keydev device
#
# Mounts , reads key from file , optionally processes it (e.g.
# if encrypted with GPG) and prints to standard output which is supposed to be
# read by cryptsetup. is just passed to helper function for
# informational purpose.
readkey() {
local keypath="$1"
local keydev="$2"
local device="$3"
# No mounting needed if the keyfile resides inside the initrd
if [ "/" == "$keydev" ]; then
local mntp=/
else
# This creates a unique single mountpoint for *, or several for explicitly
# given LUKS devices. It accomplishes unlocking multiple LUKS devices with
# a single password entry.
local mntp="/mnt/$(str_replace "keydev-$keydev-$keypath" '/' '-')"
if [ ! -d "$mntp" ]; then
mkdir "$mntp"
mount -r "$keydev" "$mntp" || die 'Mounting rem. dev. failed!'
fi
fi
case "${keypath##*.}" in
gpg)
if [ -f /lib/dracut-crypt-gpg-lib.sh ]; then
. /lib/dracut-crypt-gpg-lib.sh
gpg_decrypt "$mntp" "$keypath" "$keydev" "$device"
else
die "No GPG support to decrypt '$keypath' on '$keydev'."
fi
;;
img)
if [ -f /lib/dracut-crypt-loop-lib.sh ]; then
. /lib/dracut-crypt-loop-lib.sh
loop_decrypt "$mntp" "$keypath" "$keydev" "$device"
printf "%s\n" "umount \"$mntp\"; rmdir \"$mntp\";" > ${hookdir}/cleanup/"crypt-loop-cleanup-99-${mntp##*/}".sh
return 0
else
die "No loop file support to decrypt '$keypath' on '$keydev'."
fi
;;
*) cat "$mntp/$keypath" ;;
esac
# No unmounting if the keyfile resides inside the initrd
if [ "/" != "$keydev" ]; then
# General unmounting mechanism, modules doing custom cleanup should return earlier
# and install a pre-pivot cleanup hook
umount "$mntp"
rmdir "$mntp"
fi
}
modules.d/90crypt/probe-keydev.sh 0000755 00000000576 15023162470 0012713 0 ustar 00 #!/bin/sh
. /lib/dracut-crypt-lib.sh
real_keydev="$1"; keypath="$2"; luksdev="$3"
[ -z "$real_keydev" -o -z "$keypath" ] && die 'probe-keydev: wrong usage!'
[ -z "$luksdev" ] && luksdev='*'
info "Probing $real_keydev for $keypath..."
test_dev -f "$real_keydev" "$keypath" || exit 1
info "Found $keypath on $real_keydev"
echo "$luksdev:$real_keydev:$keypath" >> /tmp/luks.keys
modules.d/90crypt/module-setup.sh 0000755 00000011154 15023162470 0012734 0 ustar 00 #!/bin/bash
# called by dracut
check() {
local _rootdev
# if cryptsetup is not installed, then we cannot support encrypted devices.
require_any_binary $systemdutildir/systemd-cryptsetup cryptsetup || return 1
[[ $hostonly ]] || [[ $mount_needs ]] && {
for fs in "${host_fs_types[@]}"; do
[[ $fs = "crypto_LUKS" ]] && return 0
done
return 255
}
return 0
}
# called by dracut
depends() {
echo dm rootfs-block
return 0
}
# called by dracut
installkernel() {
hostonly="" instmods drbg
arch=$(arch)
[[ $arch == x86_64 ]] && arch=x86
[[ $arch == s390x ]] && arch=s390
instmods dm_crypt =crypto =drivers/crypto =arch/$arch/crypto
}
# called by dracut
cmdline() {
local dev UUID
for dev in "${!host_fs_types[@]}"; do
[[ "${host_fs_types[$dev]}" != "crypto_LUKS" ]] && continue
UUID=$(
blkid -u crypto -o export $dev \
| while read line || [ -n "$line" ]; do
[[ ${line#UUID} = $line ]] && continue
printf "%s" "${line#UUID=}"
break
done
)
[[ ${UUID} ]] || continue
printf "%s" " rd.luks.uuid=luks-${UUID}"
done
}
# called by dracut
install() {
if [[ $hostonly_cmdline == "yes" ]]; then
local _cryptconf=$(cmdline)
[[ $_cryptconf ]] && printf "%s\n" "$_cryptconf" >> "${initdir}/etc/cmdline.d/90crypt.conf"
fi
inst_hook cmdline 30 "$moddir/parse-crypt.sh"
if ! dracut_module_included "systemd"; then
inst_multiple cryptsetup rmdir readlink umount
inst_script "$moddir"/cryptroot-ask.sh /sbin/cryptroot-ask
inst_script "$moddir"/probe-keydev.sh /sbin/probe-keydev
inst_hook cmdline 10 "$moddir/parse-keydev.sh"
inst_hook cleanup 30 "$moddir/crypt-cleanup.sh"
fi
if [[ $hostonly ]] && [[ -f /etc/crypttab ]]; then
# filter /etc/crypttab for the devices we need
while read _mapper _dev _luksfile _luksoptions || [ -n "$_mapper" ]; do
[[ $_mapper = \#* ]] && continue
[[ $_dev ]] || continue
[[ $_dev == PARTUUID=* ]] && \
_dev="/dev/disk/by-partuuid/${_dev#PARTUUID=}"
[[ $_dev == UUID=* ]] && \
_dev="/dev/disk/by-uuid/${_dev#UUID=}"
[[ $_dev == ID=* ]] && \
_dev="/dev/disk/by-id/${_dev#ID=}"
echo "$_dev $(blkid $_dev -s UUID -o value)" >> "${initdir}/etc/block_uuid.map"
# loop through the options to check for the force option
luksoptions=${_luksoptions}
OLD_IFS="${IFS}"
IFS=,
set -- ${luksoptions}
IFS="${OLD_IFS}"
while [ $# -gt 0 ]; do
case $1 in
force)
forceentry="yes"
break
;;
esac
shift
done
# include the entry regardless
if [ "${forceentry}" = "yes" ]; then
echo "$_mapper $_dev $_luksfile $_luksoptions"
else
for _hdev in "${!host_fs_types[@]}"; do
[[ ${host_fs_types[$_hdev]} == "crypto_LUKS" ]] || continue
if [[ $_hdev -ef $_dev ]] || [[ /dev/block/$_hdev -ef $_dev ]]; then
echo "$_mapper $_dev $_luksfile $_luksoptions"
break
fi
done
fi
done < /etc/crypttab > $initdir/etc/crypttab
mark_hostonly /etc/crypttab
fi
inst_simple "$moddir/crypt-lib.sh" "/lib/dracut-crypt-lib.sh"
if dracut_module_included "systemd"; then
# the cryptsetup targets are already pulled in by 00systemd, but not
# the enablement symlinks
inst_multiple -o \
$systemdutildir/system-generators/systemd-cryptsetup-generator \
$systemdutildir/systemd-cryptsetup \
$systemdsystemunitdir/systemd-ask-password-console.path \
$systemdsystemunitdir/systemd-ask-password-console.service \
$systemdsystemunitdir/cryptsetup.target \
$systemdsystemunitdir/sysinit.target.wants/cryptsetup.target \
$systemdsystemunitdir/remote-cryptsetup.target \
$systemdsystemunitdir/initrd-root-device.target.wants/remote-cryptsetup.target \
systemd-ask-password systemd-tty-ask-password-agent
inst_script "$moddir"/crypt-run-generator.sh /sbin/crypt-run-generator
fi
dracut_need_initqueue
}
modules.d/71prefixdevname/module-setup.sh 0000755 00000000365 15023162470 0014431 0 ustar 00 #!/bin/bash
# Make sure we always include generated link files in initrd
check() {
return 0
}
install() {
if dracut_module_included "systemd"; then
inst_multiple -H -o /etc/systemd/network/71-net-ifnames-prefix-*.link
fi
}
modules.d/04watchdog-modules/module-setup.sh 0000755 00000003623 15023162470 0015036 0 ustar 00 #!/bin/bash
# called by dracut
check() {
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
install() {
return 0
}
installkernel() {
local -A _drivers
local _alldrivers _wdtdrv _wdtppath _dir
[[ -d /sys/class/watchdog/ ]] || return
for _dir in /sys/class/watchdog/*; do
[[ -d "$_dir" ]] || continue
[[ -f "$_dir/state" ]] || continue
# device/modalias will return driver of this device
_wdtdrv=$(< "$_dir/device/modalias")
# There can be more than one module represented by same
# modalias. Currently load all of them.
# TODO: Need to find a way to avoid any unwanted module
# represented by modalias
_wdtdrv=$(modprobe --set-version "$kernel" -R $_wdtdrv 2>/dev/null)
if [[ $_wdtdrv ]]; then
instmods $_wdtdrv
for i in $_wdtdrv; do
_drivers[$i]=1
done
fi
# however in some cases, we also need to check that if there is
# a specific driver for the parent bus/device. In such cases
# we also need to enable driver for parent bus/device.
_wdtppath=$(readlink -f "$_dir/device")
while [[ -d "$_wdtppath" ]] && [[ "$_wdtppath" != "/sys" ]]; do
_wdtppath=$(readlink -f "$_wdtppath/..")
[[ -f "$_wdtppath/modalias" ]] || continue
_wdtdrv=$(< "$_wdtppath/modalias")
_wdtdrv=$(modprobe --set-version "$kernel" -R $_wdtdrv 2>/dev/null)
if [[ $_wdtdrv ]]; then
instmods $_wdtdrv
for i in $_wdtdrv; do
_drivers[$i]=1
done
fi
done
done
# ensure that watchdog module is loaded as early as possible
_alldrivers="${!_drivers[*]}"
[[ $_alldrivers ]] && echo "rd.driver.pre=${_alldrivers// /,}" > ${initdir}/etc/cmdline.d/00-watchdog.conf
return 0
}
modules.d/95nfs/nfsroot.sh 0000755 00000001313 15023162470 0011431 0 ustar 00 #!/bin/sh
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
. /lib/nfs-lib.sh
[ "$#" = 3 ] || exit 1
# root is in the form root=nfs[4]:[server:]path[:options], either from
# cmdline or dhcp root-path
netif="$1"
root="$2"
NEWROOT="$3"
nfs_to_var $root $netif
[ -z "$server" ] && die "Required parameter 'server' is missing"
mount_nfs $root $NEWROOT $netif && { [ -e /dev/root ] || ln -s null /dev/root ; [ -e /dev/nfs ] || ln -s null /dev/nfs; }
[ -f $NEWROOT/etc/fstab ] && cat $NEWROOT/etc/fstab > /dev/null
# inject new exit_if_exists
echo 'settle_exit_if_exists="--exit-if-exists=/dev/root"; rm -- "$job"' > $hookdir/initqueue/nfs.sh
# force udevsettle to break
> $hookdir/initqueue/work
need_shutdown
modules.d/95nfs/nfs-start-rpc.sh 0000755 00000001546 15023162470 0012452 0 ustar 00 #!/bin/sh
if modprobe sunrpc || strstr "$(cat /proc/filesystems)" rpc_pipefs; then
[ ! -d /var/lib/nfs/rpc_pipefs/nfs ] && \
mount -t rpc_pipefs rpc_pipefs /var/lib/nfs/rpc_pipefs
# Start rpcbind or rpcbind
# FIXME occasionally saw 'rpcbind: fork failed: No such device' -- why?
command -v portmap >/dev/null && [ -z "$(pidof portmap)" ] && portmap
if command -v rpcbind >/dev/null && [ -z "$(pidof rpcbind)" ]; then
mkdir -p /run/rpcbind
rpcbind
fi
# Start rpc.statd as mount won't let us use locks on a NFSv4
# filesystem without talking to it. NFSv4 does locks internally,
# rpc.lockd isn't needed
[ -z "$(pidof rpc.statd)" ] && rpc.statd
[ -z "$(pidof rpc.idmapd)" ] && rpc.idmapd
else
warn 'Kernel module "sunrpc" not in the initramfs, or support for filesystem "rpc_pipefs" missing!'
fi
modules.d/95nfs/nfs-lib.sh 0000755 00000011044 15023162470 0011273 0 ustar 00 #!/bin/sh
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
. /lib/net-lib.sh
# TODO: make these things not pollute the calling namespace
# nfs_to_var NFSROOT [NETIF]
# use NFSROOT to set $nfs, $server, $path, and $options.
# NFSROOT is something like: nfs[4]::/[:|,]
# NETIF is used to get information from DHCP options, if needed.
nfs_to_var() {
# Unfortunately, there's multiple styles of nfs "URL" in use, so we need
# extra functions to parse them into $nfs, $server, $path, and $options.
# FIXME: local netif=${2:-$netif}?
case "$1" in
nfs://*) rfc2224_nfs_to_var "$1" ;;
nfs:*[*) anaconda_nfsv6_to_var "$1" ;;
nfs:*:*:/*) anaconda_nfs_to_var "$1" ;;
*) nfsroot_to_var "$1" ;;
esac
# if anything's missing, try to fill it in from DHCP options
if [ -z "$server" ] || [ -z "$path" ]; then nfsroot_from_dhcp $2; fi
# if there's a "%s" in the path, replace it with the hostname/IP
if strstr "$path" "%s"; then
local node=""
read node < /proc/sys/kernel/hostname
[ "$node" = "(none)" ] && node=$(get_ip $2)
path=${path%%%s*}$node${path#*%s} # replace only the first %s
fi
}
# root=nfs:[:][:]
# root=nfs4:[:][:]
nfsroot_to_var() {
# strip nfs[4]:
local arg="$@:"
nfs="${arg%%:*}"
arg="${arg##$nfs:}"
# check if we have a server
if strstr "$arg" ':/' ; then
server="${arg%%:/*}"
arg="/${arg##*:/}"
fi
path="${arg%%:*}"
# rest are options
options="${arg##$path}"
# strip leading ":"
options="${options##:}"
# strip ":"
options="${options%%:}"
# Does it really start with '/'?
[ -n "${path%%/*}" ] && path="error";
#Fix kernel legacy style separating path and options with ','
if [ "$path" != "${path#*,}" ] ; then
options=${path#*,}
path=${path%%,*}
fi
}
# RFC2224: nfs://[:]/
rfc2224_nfs_to_var() {
nfs="nfs"
server="${1#nfs://}"
path="/${server#*/}"
server="${server%%/*}"
server="${server%%:}" # anaconda compat (nfs://:/)
local port="${server##*:}"
[ "$port" != "$server" ] && options="port=$port"
}
# Anaconda-style path with options: nfs:::/
# (without mount options, anaconda is the same as dracut)
anaconda_nfs_to_var() {
nfs="nfs"
options="${1#nfs:}"
server="${options#*:}"
server="${server%:/*}"
options="${options%%:*}"
path="/${1##*:/}"
}
# IPv6 nfs path will be treated separately
anaconda_nfsv6_to_var() {
nfs="nfs"
path="$1"
options="${path#*:/}"
path="/${options%%:*}"
server="${1#*nfs:}"
if str_starts $server '['; then
server="${server%:/*}"
options="${options#*:*}"
else
server="${server%:/*}"
options="${server%%:*}"
server="${server#*:}"
fi
}
# nfsroot_from_dhcp NETIF
# fill in missing server/path from DHCP options.
nfsroot_from_dhcp() {
local f
for f in /tmp/net.$1.override /tmp/dhclient.$1.dhcpopts; do
[ -f $f ] && . $f
done
[ -n "$new_root_path" ] && nfsroot_to_var "$nfs:$new_root_path"
[ -z "$path" ] && [ "$(getarg root=)" = "/dev/nfs" ] && path=/tftpboot/%s
[ -z "$server" ] && server=$srv
[ -z "$server" ] && server=$new_next_server
[ -z "$server" ] && server=$new_dhcp_server_identifier
[ -z "$server" ] && server=${new_root_path%%:*}
}
# Look through $options, fix "rw"/"ro", move "lock"/"nolock" to $nfslock
munge_nfs_options() {
local f="" flags="" nfsrw="ro" OLDIFS="$IFS"
IFS=,
for f in $options; do
case $f in
ro|rw) nfsrw=$f ;;
lock|nolock) nfslock=$f ;;
*) flags=${flags:+$flags,}$f ;;
esac
done
IFS="$OLDIFS"
# Override rw/ro if set on cmdline
getarg ro >/dev/null && nfsrw=ro
getarg rw >/dev/null && nfsrw=rw
options=$nfsrw${flags:+,$flags}
}
# mount_nfs NFSROOT MNTDIR [NETIF]
mount_nfs() {
local nfsroot="$1" mntdir="$2" netif="$3"
local nfs="" server="" path="" options=""
nfs_to_var "$nfsroot" $netif
munge_nfs_options
if [ "$nfs" = "nfs4" ]; then
options=$options${nfslock:+,$nfslock}
else
# NFSv{2,3} doesn't support using locks as it requires a helper to
# transfer the rpcbind state to the new root
[ "$nfslock" = "lock" ] \
&& warn "Locks unsupported on NFSv{2,3}, using nolock" 1>&2
options=$options,nolock
fi
mount -t $nfs -o$options "$server:$path" "$mntdir"
}
modules.d/95nfs/nfsroot-cleanup.sh 0000755 00000001515 15023162470 0013062 0 ustar 00 #!/bin/sh
type incol2 >/dev/null 2>&1 || . /lib/dracut-lib.sh
[ -f /tmp/nfs.rpc_pipefs_path ] && rpcpipefspath=`cat /tmp/nfs.rpc_pipefs_path`
[ -z "$rpcpipefspath" ] && rpcpipefspath=var/lib/nfs/rpc_pipefs
pid=$(pidof rpc.statd)
[ -n "$pid" ] && kill $pid
pid=$(pidof rpc.idmapd)
[ -n "$pid" ] && kill $pid
pid=$(pidof rpcbind)
[ -n "$pid" ] && kill $pid
if incol2 /proc/mounts /var/lib/nfs/rpc_pipefs; then
# try to create the destination directory
[ -d $NEWROOT/$rpcpipefspath ] || \
mkdir -m 0755 -p $NEWROOT/$rpcpipefspath 2>/dev/null
if [ -d $NEWROOT/$rpcpipefspath ]; then
# mount --move does not seem to work???
mount --bind /var/lib/nfs/rpc_pipefs $NEWROOT/$rpcpipefspath
umount /var/lib/nfs/rpc_pipefs 2>/dev/null
else
umount /var/lib/nfs/rpc_pipefs 2>/dev/null
fi
fi
modules.d/95nfs/parse-nfsroot.sh 0000755 00000006405 15023162470 0012550 0 ustar 00 #!/bin/sh
#
# Preferred format:
# root=nfs[4]:[server:]path[:options]
#
# This syntax can come from DHCP root-path as well.
#
# Legacy format:
# root=/dev/nfs nfsroot=[server:]path[,options]
#
# In Legacy root=/dev/nfs mode, if the 'nfsroot' parameter is not given
# on the command line or is empty, the dhcp root-path is used as
# [server:]path[:options] or the default "/tftpboot/%s" will be used.
#
# If server is unspecified it will be pulled from one of the following
# sources, in order:
# static ip= option on kernel command line
# DHCP next-server option
# DHCP server-id option
# DHCP root-path option
#
# NFSv4 is only used if explicitly requested with nfs4: prefix, otherwise
# NFSv3 is used.
#
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
# This script is sourced, so root should be set. But let's be paranoid
[ -z "$root" ] && root=$(getarg root=)
[ -z "$nfsroot" ] && nfsroot=$(getarg nfsroot=)
[ -n "$netroot" ] && oldnetroot="$netroot"
# netroot= cmdline argument must be ignored, but must be used if
# we're inside netroot to parse dhcp root-path
if [ -n "$netroot" ] ; then
for n in $(getargs netroot=); do
[ "$n" = "$netroot" ] && break
done
if [ "$n" = "$netroot" ]; then
#warn "Ignoring netroot argument for NFS"
netroot=$root
fi
else
netroot=$root;
fi
# LEGACY: nfsroot= is valid only if root=/dev/nfs
if [ -n "$nfsroot" ] ; then
# @deprecated
warn "Argument nfsroot is deprecated and might be removed in a future release. See 'man dracut.kernel' for more information."
if [ "$(getarg root=)" != "/dev/nfs" ]; then
die "Argument nfsroot only accepted for legacy root=/dev/nfs"
fi
netroot=nfs:$nfsroot;
fi
case "$netroot" in
/dev/nfs) netroot=nfs;;
/dev/*)
if [ -n "$oldnetroot" ]; then
netroot="$oldnetroot"
else
unset netroot
fi
return
;;
# LEGACY: root=:/> /etc/idmapd.conf
fi
nfsroot_to_var $netroot
[ "$path" = "error" ] && die "Argument nfsroot must contain a valid path!"
# Set fstype, might help somewhere
fstype=${nfs#/dev/}
# Rewrite root so we don't have to parse this uglyness later on again
netroot="$fstype:$server:$path:$options"
# If we don't have a server, we need dhcp
if [ -z "$server" ] ; then
DHCPORSERVER="1"
fi;
# Done, all good!
rootok=1
# Shut up init error check or make sure that block parser wont get
# confused by having /dev/nfs[4]
root="$fstype"
echo '[ -e $NEWROOT/proc ]' > $hookdir/initqueue/finished/nfsroot.sh
mkdir -p /var/lib/rpcbind
chown rpc:rpc /var/lib/rpcbind
chmod 770 /var/lib/rpcbind
modules.d/95nfs/module-setup.sh 0000755 00000010454 15023162470 0012370 0 ustar 00 #!/bin/bash
# called by dracut
check() {
# If our prerequisites are not met, fail anyways.
require_any_binary rpcbind portmap || return 1
require_binaries rpc.statd mount.nfs mount.nfs4 umount || return 1
[[ $hostonly ]] || [[ $mount_needs ]] && {
for fs in "${host_fs_types[@]}"; do
[[ "$fs" == "nfs" ]] && return 0
[[ "$fs" == "nfs3" ]] && return 0
[[ "$fs" == "nfs4" ]] && return 0
done
return 255
}
return 0
}
# called by dracut
depends() {
# We depend on network modules being loaded
echo network
}
# called by dracut
installkernel() {
hostonly='' instmods =net/sunrpc =fs/nfs ipv6 nfs_acl nfs_layout_nfsv41_files
}
cmdline() {
local nfs_device
local nfs_options
local nfs_root
local nfs_address
local lookup
local ifname
### nfsroot= ###
nfs_device=$(findmnt -t nfs4 -n -o SOURCE /)
if [ -n "$nfs_device" ];then
nfs_root="root=nfs4:$nfs_device"
else
nfs_device=$(findmnt -t nfs -n -o SOURCE /)
[ -z "$nfs_device" ] && return
nfs_root="root=nfs:$nfs_device"
fi
nfs_options=$(findmnt -t nfs4,nfs -n -o OPTIONS /)
[ -n "$nfs_options" ] && nfs_root="$nfs_root:$nfs_options"
echo "$nfs_root"
### ip= ###
if [[ $nfs_device = [0-9]*\.[0-9]*\.[0-9]*.[0-9]* ]] || [[ $nfs_device = \[.*\] ]]; then
nfs_address="${nfs_device%%:*}"
else
lookup=$(host "${nfs_device%%:*}"| grep " address " | head -n1)
nfs_address=${lookup##* }
fi
ifname=$(ip -o route get to $nfs_address | sed -n 's/.*dev \([^ ]*\).*/\1/p')
if [ -d /sys/class/net/$ifname/bonding ]; then
dinfo "Found bonded interface '${ifname}'. Make sure to provide an appropriate 'bond=' cmdline."
return
elif [ -e /sys/class/net/$ifname/address ] ; then
ifmac=$(cat /sys/class/net/$ifname/address)
printf 'ifname=%s:%s ' ${ifname} ${ifmac}
fi
printf 'ip=%s:static\n' ${ifname}
}
# called by dracut
install() {
local _i
local _nsslibs
inst_multiple -o portmap rpcbind rpc.statd mount.nfs \
mount.nfs4 umount rpc.idmapd sed /etc/netconfig chmod "$tmpfilesdir/rpcbind.conf"
inst_multiple /etc/services /etc/nsswitch.conf /etc/rpc /etc/protocols /etc/idmapd.conf
if [[ $hostonly_cmdline == "yes" ]]; then
local _netconf="$(cmdline)"
[[ $_netconf ]] && printf "%s\n" "$_netconf" >> "${initdir}/etc/cmdline.d/95nfs.conf"
fi
if [ -f /lib/modprobe.d/nfs.conf ]; then
inst_multiple /lib/modprobe.d/nfs.conf
else
[ -d $initdir/etc/modprobe.d/ ] || mkdir $initdir/etc/modprobe.d
echo "alias nfs4 nfs" > $initdir/etc/modprobe.d/nfs.conf
fi
inst_libdir_file 'libnfsidmap_nsswitch.so*' 'libnfsidmap/*.so' 'libnfsidmap*.so*'
_nsslibs=$(sed -e '/^#/d' -e 's/^.*://' -e 's/\[NOTFOUND=return\]//' /etc/nsswitch.conf \
| tr -s '[:space:]' '\n' | sort -u | tr -s '[:space:]' '|')
_nsslibs=${_nsslibs#|}
_nsslibs=${_nsslibs%|}
inst_libdir_file -n "$_nsslibs" 'libnss_*.so*'
inst_hook cmdline 90 "$moddir/parse-nfsroot.sh"
inst_hook pre-udev 99 "$moddir/nfs-start-rpc.sh"
inst_hook cleanup 99 "$moddir/nfsroot-cleanup.sh"
inst "$moddir/nfsroot.sh" "/sbin/nfsroot"
inst "$moddir/nfs-lib.sh" "/lib/nfs-lib.sh"
mkdir -m 0755 -p "$initdir/var/lib/nfs/rpc_pipefs"
mkdir -m 0770 -p "$initdir/var/lib/rpcbind"
[ -d "$dracutsysrootdir/var/lib/nfs/statd/sm" ] && \
mkdir -m 0700 -p "$initdir/var/lib/nfs/statd" && \
mkdir -m 0755 -p "$initdir/var/lib/nfs/statd/sm" && \
chown -R rpcuser:rpcuser "$initdir/var/lib/nfs/statd"
[ -d "$dracutsysrootdir/var/lib/nfs/sm" ] && \
mkdir -m 0755 -p "$initdir/var/lib/nfs/sm" &&
chown -R rpcuser:rpcuser "$initdir/var/lib/nfs/sm"
# Rather than copy the passwd file in, just set a user for rpcbind
# We'll save the state and restart the daemon from the root anyway
grep -E '^nfsnobody:|^rpc:|^rpcuser:' /etc/passwd >> "$initdir/etc/passwd"
grep -E '^nogroup:|^rpc:|^nobody:' /etc/group >> "$initdir/etc/group"
# rpc user needs to be able to write to this directory to save the warmstart
# file
chmod 770 "$initdir/var/lib/rpcbind"
grep -q '^rpc:' /etc/passwd \
&& grep -q '^rpc:' /etc/group
dracut_need_initqueue
}
modules.d/80lvmthinpool-monitor/start-thinpool-monitor.service 0000644 00000000506 15023162470 0020705 0 ustar 00 [Unit]
Description=Lvm thinpool monitor service
Before=initrd.target
After=initrd-fs.target
Conflicts=shutdown.target emergency.target
[Service]
Type=forking
ExecStart=/bin/start-thinpool-monitor
PIDFile=/run/thinpool-moni.pid
StandardInput=null
StandardOutput=journal+console
StandardError=journal+console
KillSignal=SIGHUP
modules.d/80lvmthinpool-monitor/start-thinpool-monitor.sh 0000755 00000002402 15023162470 0017657 0 ustar 00 #!/bin/sh
type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh
LVS=$(getargs rd.lvm.lv -d rd_LVM_LV=)
is_lvm2_thinp_device() {
_device_path=$1
_lvm2_thin_device=$(lvm lvs -S 'lv_layout=sparse && lv_layout=thin' \
--nosuffix --noheadings -o vg_name,lv_name "$_device_path" 2> /dev/null)
[ -n "$_lvm2_thin_device" ] && return $?
}
for LV in $LVS; do
if is_lvm2_thinp_device "/dev/$LV"; then
THIN_POOLS="$(lvm lvs -S 'lv_layout=sparse && lv_layout=thin' \
--nosuffix --noheadings -o vg_name,pool_lv "$LV" \
| awk '{printf("%s/%s",$1,$2);}') $THIN_POOLS"
fi
done
THIN_POOLS=$(echo "$THIN_POOLS" | tr ' ' '\n' | sort -u | tr '\n' ' ')
if [ -n "$THIN_POOLS" ]; then
if [ -e "/etc/lvm/lvm.conf" ]; then
# Use 'monitoring=0' to override the value in lvm.conf, in case
# dmeventd monitoring been started after the calling.
CONFIG="activation {monitoring=0}"
else
CONFIG="activation {monitoring=0 thin_pool_autoextend_threshold=70 thin_pool_autoextend_percent=20}"
fi
while true; do
for THIN_POOL in $THIN_POOLS; do
lvm lvextend --use-policies --config "$CONFIG" "$THIN_POOL"
done
sleep 5
done &
echo $! > /run/thinpool-moni.pid
fi
modules.d/80lvmthinpool-monitor/module-setup.sh 0000755 00000001100 15023162470 0015620 0 ustar 00 #!/bin/bash
# called by dracut
check() {
# No point trying to support lvm if the binaries are missing
require_binaries lvm sort tr awk || return 1
return 255
}
# called by dracut
depends() {
echo lvm
return 0
}
# called by dracut
install() {
inst_multiple sort tr awk
inst_script "$moddir/start-thinpool-monitor.sh" "/bin/start-thinpool-monitor"
inst "$moddir/start-thinpool-monitor.service" "$systemdsystemunitdir/start-thinpool-monitor.service"
systemctl -q --root "$initdir" add-wants initrd.target start-thinpool-monitor.service
}
modules.d/95resume/parse-resume.sh 0000755 00000007047 15023162470 0013073 0 ustar 00 #!/bin/sh
if resume=$(getarg resume=) && ! getarg noresume; then
export resume
echo "$resume" >/.resume
else
unset resume
fi
case "$resume" in
LABEL=*) \
resume="$(echo $resume | sed 's,/,\\x2f,g')"
resume="/dev/disk/by-label/${resume#LABEL=}" ;;
UUID=*) \
resume="/dev/disk/by-uuid/${resume#UUID=}" ;;
PARTUUID=*) \
resume="/dev/disk/by-partuuid/${resume#PARTUUID=}" ;;
PARTLABEL=*) \
resume="/dev/disk/by-partlabel/${resume#PARTLABEL=}" ;;
esac
if splash=$(getarg splash=); then
export splash
else
unset splash
fi
case "$splash" in
quiet )
a_splash="-P splash=y"
;;
* )
a_splash="-P splash=n"
;;
esac
if ! getarg noresume; then
if [ -n "$resume" ]; then
wait_for_dev /dev/resume
{
printf "KERNEL==\"%s\", ACTION==\"add|change\", SYMLINK+=\"resume\"\n" \
${resume#/dev/};
printf "SYMLINK==\"%s\", ACTION==\"add|change\", SYMLINK+=\"resume\"\n" \
${resume#/dev/};
} >> /etc/udev/rules.d/99-resume-link.rules
{
if [ -x /usr/sbin/resume ]; then
printf -- 'KERNEL=="%s", ' "${resume#/dev/}"
printf -- '%s' 'ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",'
printf -- " RUN+=\"/sbin/initqueue --finished --unique --name 00resume /usr/sbin/resume %s \'%s\'\"\n" \
"$a_splash" "$resume";
printf -- 'SYMLINK=="%s", ' "${resume#/dev/}"
printf -- '%s' 'ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",'
printf -- " RUN+=\"/sbin/initqueue --finished --unique --name 00resume /usr/sbin/resume %s \'%s\'\"\n" \
"$a_splash" "$resume";
fi
printf -- 'KERNEL=="%s", ' "${resume#/dev/}"
printf -- '%s' 'ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",'
printf -- '%s\n' ' RUN+="/sbin/initqueue --finished --unique --name 00resume echo %M:%m > /sys/power/resume"'
printf -- 'SYMLINK=="%s", ' "${resume#/dev/}"
printf -- '%s' 'ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",'
printf -- '%s\n' ' RUN+="/sbin/initqueue --finished --unique --name 00resume echo %M:%m > /sys/power/resume"'
} >> /etc/udev/rules.d/99-resume.rules
printf '[ -e "%s" ] && { ln -fs "%s" /dev/resume 2> /dev/null; rm -f -- "$job" "%s/initqueue/timeout/resume.sh"; }\n' \
"$resume" "$resume" "$hookdir" >> $hookdir/initqueue/settled/resume.sh
{
printf -- "%s" 'warn "Cancelling resume operation. Device not found.";'
printf -- ' cancel_wait_for_dev /dev/resume; rm -f -- "$job" "%s/initqueue/settled/resume.sh";\n' "$hookdir"
} >> $hookdir/initqueue/timeout/resume.sh
mv /lib/dracut/resume.sh /lib/dracut/hooks/pre-mount/10-resume.sh
else
{
if [ -x /usr/sbin/resume ]; then
printf -- '%s' 'SUBSYSTEM=="block", ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",'
printf -- ' RUN+="/sbin/initqueue --finished --unique --name 00resume /usr/sbin/resume %s $tempnode"\n' "$a_splash"
fi
printf -- '%s' 'SUBSYSTEM=="block", ACTION=="add|change", ENV{ID_FS_TYPE}=="suspend|swsuspend|swsupend",'
printf -- '%s\n' ' RUN+="/sbin/initqueue --finished --unique --name 00resume echo %M:%m > /sys/power/resume"';
} >> /etc/udev/rules.d/99-resume.rules
fi
fi
modules.d/95resume/resume.sh 0000755 00000001060 15023162470 0011750 0 ustar 00 #!/bin/sh
PATH=/usr/sbin:/usr/bin:/sbin:/bin
[ -s /.resume -a -b "$resume" ] && {
# First try user level resume; it offers splash etc
case "$splash" in
quiet )
a_splash="-P splash=y"
;;
* )
a_splash="-P splash=n"
;;
esac
[ -x "$(command -v resume)" ] && command resume $a_splash "$resume"
# parsing the output of ls is Bad, but until there is a better way...
ls -lH "$resume" | (
read x x x x maj min x;
echo "${maj%,}:$min"> /sys/power/resume)
>/.resume
}
modules.d/95resume/module-setup.sh 0000755 00000003600 15023162470 0013075 0 ustar 00 #!/bin/bash
# called by dracut
check() {
# No point trying to support resume, if no swap partition exist
[[ $hostonly ]] || [[ $mount_needs ]] && {
for fs in "${host_fs_types[@]}"; do
[[ $fs =~ ^(swap|swsuspend|swsupend)$ ]] && return 0
done
return 255
}
return 0
}
# called by dracut
cmdline() {
local _resume
for dev in "${!host_fs_types[@]}"; do
[[ ${host_fs_types[$dev]} =~ ^(swap|swsuspend|swsupend)$ ]] || continue
_resume=$(shorten_persistent_dev "$(get_persistent_dev "$dev")")
[[ -n ${_resume} ]] && printf " resume=%s" "${_resume}"
done
}
# called by dracut
install() {
local _bin
if [[ $hostonly_cmdline == "yes" ]]; then
local _resumeconf=$(cmdline)
[[ $_resumeconf ]] && printf "%s\n" "$_resumeconf" >> "${initdir}/etc/cmdline.d/95resume.conf"
fi
# if systemd is included and has the hibernate-resume tool, use it and nothing else
if dracut_module_included "systemd" && [[ -x $systemdutildir/systemd-hibernate-resume ]]; then
inst_multiple -o \
$systemdutildir/system-generators/systemd-hibernate-resume-generator \
$systemdsystemunitdir/systemd-hibernate-resume@.service \
$systemdutildir/systemd-hibernate-resume
return 0
fi
# Optional uswsusp support
for _bin in /usr/sbin/resume /usr/lib/suspend/resume /usr/lib/uswsusp/resume
do
[[ -x "${_bin}" ]] && {
inst "${_bin}" /usr/sbin/resume
[[ $hostonly ]] && [[ -f /etc/suspend.conf ]] && inst -H /etc/suspend.conf
break
}
done
if ! dracut_module_included "systemd"; then
inst_hook cmdline 10 "$moddir/parse-resume.sh"
else
inst_script "$moddir/parse-resume.sh" /lib/dracut/parse-resume.sh
fi
inst_script "$moddir/resume.sh" /lib/dracut/resume.sh
}
modules.d/90qemu-net/module-setup.sh 0000755 00000001442 15023162470 0013325 0 ustar 00 #!/bin/bash
# called by dracut
check() {
if [[ $hostonly ]] || [[ $mount_needs ]]; then
if type -P systemd-detect-virt >/dev/null 2>&1; then
vm=$(systemd-detect-virt --vm >/dev/null 2>&1)
(($? != 0)) && return 255
[[ $vm = "qemu" ]] && return 0
[[ $vm = "kvm" ]] && return 0
[[ $vm = "bochs" ]] && return 0
fi
for i in /sys/class/dmi/id/*_vendor; do
[[ -f $i ]] || continue
read vendor < $i
[[ "$vendor" == "QEMU" ]] && return 0
[[ "$vendor" == "Bochs" ]] && return 0
done
return 255
fi
return 0
}
# called by dracut
installkernel() {
# qemu specific modules
hostonly='' instmods virtio_net e1000 8139cp pcnet32 e100 ne2k_pci
}
modules.d/99kdumpbase/kdump-capture.service 0000644 00000001661 15023162470 0014742 0 ustar 00 # This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Kdump Vmcore Save Service
After=initrd.target initrd-parse-etc.service sysroot.mount
After=dracut-initqueue.service dracut-pre-mount.service dracut-mount.service dracut-pre-pivot.service
Before=initrd-cleanup.service
ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
OnFailureJobMode=isolate
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=/bin/kdump.sh
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
KillMode=process
RemainAfterExit=yes
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/99kdumpbase/kdump-error-handler.sh 0000755 00000000221 15023162470 0015007 0 ustar 00 #!/bin/sh
. /lib/kdump-lib-initramfs.sh
set -o pipefail
export PATH=$PATH:$KDUMP_SCRIPT_DIR
get_kdump_confs
do_failure_action
do_final_action
modules.d/99kdumpbase/kdump-emergency.service 0000644 00000001611 15023162470 0015250 0 ustar 00 # This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This service will be placed in kdump initramfs and replace both the systemd
# emergency service and dracut emergency shell. IOW, any emergency will be
# kick this service and in turn isolating to kdump error handler.
[Unit]
Description=Kdump Emergency
DefaultDependencies=no
IgnoreOnIsolate=yes
[Service]
ExecStart=/usr/bin/systemctl --no-block isolate kdump-error-handler.service
Type=oneshot
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/99kdumpbase/kdump-emergency.target 0000644 00000000703 15023162470 0015077 0 ustar 00 # This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Emergency Mode
Documentation=man:systemd.special(7)
Requires=emergency.service
After=emergency.service
AllowIsolate=yes
IgnoreOnIsolate=yes
modules.d/99kdumpbase/monitor_dd_progress 0000644 00000000742 15023162470 0014603 0 ustar 00 #!/bin/sh
SRC_FILE_MB=$1
while true
do
DD_PID=`pidof dd`
if [ -n "$DD_PID" ]; then
break
fi
done
while true
do
sleep 5
if [ ! -d /proc/$DD_PID ]; then
break
fi
kill -s USR1 $DD_PID
CURRENT_SIZE=`tail -n 1 /tmp/dd_progress_file | sed "s/[^0-9].*//g"`
[ -n "$CURRENT_SIZE" ] && {
CURRENT_MB=$(($CURRENT_SIZE / 1048576))
echo -e "Copied $CURRENT_MB MB / $SRC_FILE_MB MB\r"
}
done
rm -f /tmp/dd_progress_file
modules.d/99kdumpbase/kdump-error-handler.service 0000644 00000001646 15023162470 0016046 0 ustar 00 # This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This service will run the real kdump error handler code. Executing the
# failure action configured in kdump.conf
[Unit]
Description=Kdump Error Handler
DefaultDependencies=no
After=systemd-vconsole-setup.service
Wants=systemd-vconsole-setup.service
AllowIsolate=yes
[Service]
Environment=HOME=/
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
WorkingDirectory=/
ExecStart=/bin/kdump-error-handler.sh
Type=oneshot
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/99kdumpbase/kdump.sh 0000755 00000017603 15023162470 0012261 0 ustar 00 #!/bin/sh
# continue here only if we have to save dump.
if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ] && [ ! -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then
exit 0
fi
. /lib/dracut-lib.sh
. /lib/kdump-lib-initramfs.sh
set -o pipefail
DUMP_RETVAL=0
export PATH=$PATH:$KDUMP_SCRIPT_DIR
do_dump()
{
local _ret
eval $DUMP_INSTRUCTION
_ret=$?
if [ $_ret -ne 0 ]; then
derror "saving vmcore failed"
fi
return $_ret
}
do_kdump_pre()
{
local _ret
if [ -n "$KDUMP_PRE" ]; then
"$KDUMP_PRE"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$KDUMP_PRE exited with $_ret status"
return $_ret
fi
fi
# if any script fails, it just raises warning and continues
if [ -d /etc/kdump/pre.d ]; then
for file in /etc/kdump/pre.d/*; do
"$file"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$file exited with $_ret status"
fi
done
fi
return 0
}
do_kdump_post()
{
local _ret
if [ -d /etc/kdump/post.d ]; then
for file in /etc/kdump/post.d/*; do
"$file" "$1"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$file exited with $_ret status"
fi
done
fi
if [ -n "$KDUMP_POST" ]; then
"$KDUMP_POST" "$1"
_ret=$?
if [ $_ret -ne 0 ]; then
derror "$KDUMP_POST exited with $_ret status"
fi
fi
}
add_dump_code()
{
DUMP_INSTRUCTION=$1
}
dump_raw()
{
local _raw=$1
[ -b "$_raw" ] || return 1
dinfo "saving to raw disk $_raw"
if ! $(echo -n $CORE_COLLECTOR|grep -q makedumpfile); then
_src_size=`ls -l /proc/vmcore | cut -d' ' -f5`
_src_size_mb=$(($_src_size / 1048576))
monitor_dd_progress $_src_size_mb &
fi
dinfo "saving vmcore"
$CORE_COLLECTOR /proc/vmcore | dd of=$_raw bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1
sync
dinfo "saving vmcore complete"
return 0
}
dump_ssh()
{
local _ret=0
local _exitcode=0 _exitcode2=0
local _opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes"
local _dir="$KDUMP_PATH/$HOST_IP-$DATEDIR"
local _host=$2
local _vmcore="vmcore"
local _ipv6_addr="" _username=""
dinfo "saving to $_host:$_dir"
cat /var/lib/random-seed > /dev/urandom
ssh -q $_opt $_host mkdir -p $_dir || return 1
save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host
save_opalcore_ssh ${_dir} "${_opt}" $_host
dinfo "saving vmcore"
if is_ipv6_address "$_host"; then
_username=${_host%@*}
_ipv6_addr="[${_host#*@}]"
fi
if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then
if [ -n "$_username" ] && [ -n "$_ipv6_addr" ]; then
scp -q $_opt /proc/vmcore "$_username@$_ipv6_addr:$_dir/vmcore-incomplete"
else
scp -q $_opt /proc/vmcore "$_host:$_dir/vmcore-incomplete"
fi
_exitcode=$?
else
$CORE_COLLECTOR /proc/vmcore | ssh $_opt $_host "umask 0077 && dd bs=512 of=$_dir/vmcore-incomplete"
_exitcode=$?
_vmcore="vmcore.flat"
fi
if [ $_exitcode -eq 0 ]; then
ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/$_vmcore"
_exitcode2=$?
if [ $_exitcode2 -ne 0 ]; then
derror "moving vmcore failed, _exitcode:$_exitcode2"
else
dinfo "saving vmcore complete"
fi
else
derror "saving vmcore failed, _exitcode:$_exitcode"
fi
dinfo "saving the $KDUMP_LOG_FILE to $_host:$_dir/"
save_log
if [ -n "$_username" ] && [ -n "$_ipv6_addr" ]; then
scp -q $_opt $KDUMP_LOG_FILE "$_username@$_ipv6_addr:$_dir/"
else
scp -q $_opt $KDUMP_LOG_FILE "$_host:$_dir/"
fi
_ret=$?
if [ $_ret -ne 0 ]; then
derror "saving log file failed, _exitcode:$_ret"
fi
if [ $_exitcode -ne 0 ] || [ $_exitcode2 -ne 0 ];then
return 1
fi
return 0
}
save_opalcore_ssh() {
local _path=$1
local _opts="$2"
local _location=$3
local _user_name="" _ipv6addr=""
ddebug "_path=$_path _opts=$_opts _location=$_location"
if [ ! -f $OPALCORE ]; then
# Check if we are on an old kernel that uses a different path
if [ -f /sys/firmware/opal/core ]; then
OPALCORE="/sys/firmware/opal/core"
else
return 0
fi
fi
if is_ipv6_address "$_host"; then
_user_name=${_location%@*}
_ipv6addr="[${_location#*@}]"
fi
dinfo "saving opalcore:$OPALCORE to $_location:$_path"
if [ -n "$_user_name" ] && [ -n "$_ipv6addr" ]; then
scp $_opts $OPALCORE $_user_name@$_ipv6addr:$_path/opalcore-incomplete
else
scp $_opts $OPALCORE $_location:$_path/opalcore-incomplete
fi
if [ $? -ne 0 ]; then
derror "saving opalcore failed"
return 1
fi
ssh $_opts $_location mv $_path/opalcore-incomplete $_path/opalcore
dinfo "saving opalcore complete"
return 0
}
save_vmcore_dmesg_ssh() {
local _dmesg_collector=$1
local _path=$2
local _opts="$3"
local _location=$4
dinfo "saving vmcore-dmesg.txt to $_location:$_path"
$_dmesg_collector /proc/vmcore | ssh $_opts $_location "umask 0077 && dd of=$_path/vmcore-dmesg-incomplete.txt"
_exitcode=$?
if [ $_exitcode -eq 0 ]; then
ssh -q $_opts $_location mv $_path/vmcore-dmesg-incomplete.txt $_path/vmcore-dmesg.txt
dinfo "saving vmcore-dmesg.txt complete"
else
derror "saving vmcore-dmesg.txt failed"
fi
}
get_host_ip()
{
local _host
if is_nfs_dump_target || is_ssh_dump_target
then
kdumpnic=$(getarg kdumpnic=)
[ -z "$kdumpnic" ] && derror "failed to get kdumpnic!" && return 1
_host=`ip addr show dev $kdumpnic|grep '[ ]*inet'`
[ $? -ne 0 ] && derror "wrong kdumpnic: $kdumpnic" && return 1
_host=`echo $_host | head -n 1 | cut -d' ' -f2`
_host="${_host%%/*}"
[ -z "$_host" ] && derror "wrong kdumpnic: $kdumpnic" && return 1
HOST_IP=$_host
fi
return 0
}
read_kdump_conf()
{
if [ ! -f "$KDUMP_CONF" ]; then
derror "$KDUMP_CONF not found"
return
fi
get_kdump_confs
# rescan for add code for dump target
while read config_opt config_val;
do
# remove inline comments after the end of a directive.
case "$config_opt" in
dracut_args)
config_val=$(get_dracut_args_target "$config_val")
if [ -n "$config_val" ]; then
config_val=$(get_mntpoint_from_target "$config_val")
add_dump_code "dump_fs $config_val"
fi
;;
ext[234]|xfs|btrfs|minix|nfs)
config_val=$(get_mntpoint_from_target "$config_val")
add_dump_code "dump_fs $config_val"
;;
raw)
add_dump_code "dump_raw $config_val"
;;
ssh)
add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val"
;;
esac
done <<< "$(read_strip_comments $KDUMP_CONF)"
}
fence_kdump_notify()
{
if [ -n "$FENCE_KDUMP_NODES" ]; then
$FENCE_KDUMP_SEND $FENCE_KDUMP_ARGS $FENCE_KDUMP_NODES &
fi
}
read_kdump_conf
fence_kdump_notify
get_host_ip
if [ $? -ne 0 ]; then
derror "get_host_ip exited with non-zero status!"
exit 1
fi
if [ -z "$DUMP_INSTRUCTION" ]; then
add_dump_code "dump_fs $NEWROOT"
fi
do_kdump_pre
if [ $? -ne 0 ]; then
derror "kdump_pre script exited with non-zero status!"
do_final_action
# During systemd service to reboot the machine, stop this shell script running
exit 1
fi
make_trace_mem "kdump saving vmcore" '1:shortmem' '2+:mem' '3+:slab'
do_dump
DUMP_RETVAL=$?
do_kdump_post $DUMP_RETVAL
if [ $? -ne 0 ]; then
derror "kdump_post script exited with non-zero status!"
fi
if [ $DUMP_RETVAL -ne 0 ]; then
exit 1
fi
do_final_action
modules.d/99kdumpbase/module-setup.sh 0000755 00000105664 15023162470 0013571 0 ustar 00 #!/bin/bash
_save_kdump_netifs() {
local _name
if [[ -n $2 ]]; then
_name=$2
else
_name=$1
fi
unique_netifs[$1]=$_name
}
_get_kdump_netifs() {
echo -n "${!unique_netifs[@]}"
}
kdump_module_init() {
if ! [[ -d "${initdir}/tmp" ]]; then
mkdir -p "${initdir}/tmp"
fi
. /lib/kdump/kdump-lib.sh
}
check() {
[[ $debug ]] && set -x
#kdumpctl sets this explicitly
if [ -z "$IN_KDUMP" ] || [ ! -f /etc/kdump.conf ]
then
return 1
fi
return 0
}
depends() {
local _dep="base shutdown"
kdump_module_init
add_opt_module() {
[[ " $omit_dracutmodules " != *\ $1\ * ]] && _dep="$_dep $1"
}
if is_squash_available; then
add_opt_module squash
else
dwarning "Required modules to build a squashed kdump image is missing!"
fi
add_opt_module watchdog-modules
if is_wdt_active; then
add_opt_module watchdog
fi
if is_ssh_dump_target; then
_dep="$_dep ssh-client"
fi
if is_lvm2_thinp_dump_target; then
if grep -q lvmthinpool-monitor <<< $(dracut --list-modules); then
add_opt_module lvmthinpool-monitor
else
dwarning "Required lvmthinpool-monitor modules is missing! Please upgrade dracut >= 057."
fi
fi
if [ "$(uname -m)" = "s390x" ]; then
_dep="$_dep znet"
fi
if [ -n "$( find /sys/devices -name drm )" ] || [ -d /sys/module/hyperv_fb ]; then
add_opt_module drm
fi
if is_generic_fence_kdump || is_pcs_fence_kdump; then
_dep="$_dep network"
fi
echo $_dep
}
kdump_is_bridge() {
[ -d /sys/class/net/"$1"/bridge ]
}
kdump_is_bond() {
[ -d /sys/class/net/"$1"/bonding ]
}
kdump_is_team() {
[ -f /usr/bin/teamnl ] && teamnl $1 ports &> /dev/null
}
kdump_is_vlan() {
[ -f /proc/net/vlan/"$1" ]
}
# $1: netdev name
source_ifcfg_file() {
local ifcfg_file
ifcfg_file=$(get_ifcfg_filename $1)
if [ -f "${ifcfg_file}" ]; then
. ${ifcfg_file}
else
dwarning "The ifcfg file of $1 is not found!"
fi
}
add_dns_netdev() {
local _server _route
_server=$1
_route=`/sbin/ip -o route get to $_server 2>&1`
[ $? != 0 ] && echo "DNS server $_server unreachable"
_netdev=$(get_ip_route_field "$_route" "dev")
_save_kdump_netifs "$_netdev" "$(kdump_setup_ifname $_netdev)"
}
# $1: netdev name
kdump_setup_dns() {
local _nameserver _dns
local _dnsfile=${initdir}/etc/cmdline.d/42dns.conf
source_ifcfg_file $1
[ -n "$DNS1" ] && echo "nameserver=$DNS1" > "$_dnsfile" && add_dns_netdev "$DNS1"
[ -n "$DNS2" ] && echo "nameserver=$DNS2" >> "$_dnsfile" && add_dns_netdev "$DNS2"
while read content;
do
_nameserver=$(echo $content | grep ^nameserver)
[ -z "$_nameserver" ] && continue
_dns=$(echo $_nameserver | cut -d' ' -f2)
[ -z "$_dns" ] && continue
if [ ! -f $_dnsfile ] || [ ! $(cat $_dnsfile | grep -q $_dns) ]; then
echo "nameserver=$_dns" >> "$_dnsfile"
add_dns_netdev "$_dns"
fi
done < "/etc/resolv.conf"
}
# $1: repeat times
# $2: string to be repeated
# $3: separator
repeatedly_join_str() {
local _count="$1"
local _str="$2"
local _separator="$3"
local i _res
if [[ "$_count" -le 0 ]]; then
echo -n ""
return
fi
i=0
_res="$_str"
((_count--))
while [[ "$i" -lt "$_count" ]]; do
((i++))
_res="${_res}${_separator}${_str}"
done
echo -n "$_res"
}
# $1: prefix
# $2: ipv6_flag="-6" indicates it's IPv6
# Given a prefix, calculate the netmask (equivalent of "ipcalc -m")
# by concatenating three parts,
# 1) the groups with all bits set 1
# 2) a group with partial bits set to 0
# 3) the groups with all bits set to 0
cal_netmask_by_prefix() {
local _prefix="$1"
local _ipv6_flag="$2" _ipv6
local _bits_per_octet=8
local _count _res _octets_per_group _octets_total _seperator _total_groups
local _max_group_value _max_group_value_repr _bits_per_group _tmp _zero_bits
if [[ "$_ipv6_flag" == "-6" ]]; then
_ipv6=1
else
_ipv6=0
fi
if [[ "$_prefix" -lt 0 || "$_prefix" -gt 128 ]] || \
( ((!_ipv6)) && [[ "$_prefix" -gt 32 ]] ); then
derror "Bad prefix:$_prefix for calculating netmask"
exit 1
fi
if ((_ipv6)); then
_octets_per_group=2
_octets_total=16
_seperator=":"
else
_octets_per_group=1
_octets_total=4
_seperator="."
fi
_total_groups=$((_octets_total/_octets_per_group))
_bits_per_group=$((_octets_per_group * _bits_per_octet))
_max_group_value=$(((1 << _bits_per_group) - 1))
if ((_ipv6)); then
_max_group_value_repr=$(printf "%x" $_max_group_value)
else
_max_group_value_repr="$_max_group_value"
fi
_count=$((_prefix/_octets_per_group/_bits_per_octet))
_first_part=$(repeatedly_join_str "$_count" "$_max_group_value_repr" "$_seperator")
_res="$_first_part"
_tmp=$((_octets_total*_bits_per_octet-_prefix))
_zero_bits=$(expr $_tmp % $_bits_per_group)
if [[ "$_zero_bits" -ne 0 ]]; then
_second_part=$((_max_group_value >> _zero_bits << _zero_bits))
if ((_ipv6)); then
_second_part=$(printf "%x" $_second_part)
fi
((_count++))
if [[ -z "$_first_part" ]]; then
_res="$_second_part"
else
_res="${_first_part}${_seperator}${_second_part}"
fi
fi
_count=$((_total_groups-_count))
if [[ "$_count" -eq 0 ]]; then
echo -n "$_res"
return
fi
if ((_ipv6)) && [[ "$_count" -gt 1 ]] ; then
# use condensed notion for IPv6
_third_part=":"
else
_third_part=$(repeatedly_join_str "$_count" "0" "$_seperator")
fi
if [[ -z "$_res" ]] && ((!_ipv6)) ; then
echo -n "${_third_part}"
else
echo -n "${_res}${_seperator}${_third_part}"
fi
}
#$1: netdev name
#$2: srcaddr
#if it use static ip echo it, or echo null
kdump_static_ip() {
local _netdev="$1" _srcaddr="$2" kdumpnic="$3" _ipv6_flag
local _netmask _gateway _ipaddr _target _nexthop _prefix
_ipaddr=$(ip addr show dev $_netdev permanent | awk "/ $_srcaddr\/.* /{print \$2}")
if is_ipv6_address $_srcaddr; then
_ipv6_flag="-6"
fi
if [ -n "$_ipaddr" ]; then
_gateway=$(ip $_ipv6_flag route list dev $_netdev | \
awk '/^default /{print $3}' | head -n 1)
if [ "x" != "x"$_ipv6_flag ]; then
# _ipaddr="2002::56ff:feb6:56d5/64", _netmask is the number after "/"
_netmask=${_ipaddr#*\/}
_srcaddr="[$_srcaddr]"
_gateway="[$_gateway]"
else
_prefix=$(cut -d'/' -f2 <<< "$_ipaddr")
_netmask=$(cal_netmask_by_prefix "$_prefix" "$_ipv6_flag")
if [[ "$?" -ne 0 ]]; then
derror "Failed to calculate netmask for $_ipaddr"
exit 1
fi
fi
echo -n "${_srcaddr}::${_gateway}:${_netmask}::"
fi
/sbin/ip $_ipv6_flag route show | grep -v default | grep ".*via.* $_netdev " |\
while read _route; do
_target=`echo $_route | cut -d ' ' -f1`
_nexthop=`echo $_route | cut -d ' ' -f3`
if [ "x" != "x"$_ipv6_flag ]; then
_target="[$_target]"
_nexthop="[$_nexthop]"
fi
echo "rd.route=$_target:$_nexthop:$kdumpnic"
done >> ${initdir}/etc/cmdline.d/45route-static.conf
}
kdump_get_mac_addr() {
cat /sys/class/net/$1/address
}
#Bonding or team master modifies the mac address
#of its slaves, we should use perm address
kdump_get_perm_addr() {
local addr=$(ethtool -P $1 | sed -e 's/Permanent address: //')
if [ -z "$addr" ] || [ "$addr" = "00:00:00:00:00:00" ]
then
derror "Can't get the permanent address of $1"
else
echo "$addr"
fi
}
# Prefix kernel assigned names with "kdump-". EX: eth0 -> kdump-eth0
# Because kernel assigned names are not persistent between 1st and 2nd
# kernel. We could probably end up with eth0 being eth1, eth0 being
# eth1, and naming conflict happens.
kdump_setup_ifname() {
local _ifname
# If ifname already has 'kdump-' prefix, we must be switching from
# fadump to kdump. Skip prefixing 'kdump-' in this case as adding
# another prefix may truncate the ifname. Since an ifname with
# 'kdump-' is already persistent, this should be fine.
if [[ $1 =~ ^eth.* ]] && [[ ! $1 =~ ^kdump-* ]]; then
_ifname="kdump-$1"
else
_ifname="$1"
fi
echo "$_ifname"
}
kdump_install_nm_netif_allowlist() {
local _netif _except_netif _netif_allowlist _netif_allowlist_nm_conf
for _netif in $1; do
_per_mac=$(kdump_get_perm_addr "$_netif")
if [[ "$_per_mac" != 'not set' ]]; then
_except_netif="mac:$_per_mac"
else
_except_netif="interface-name:${unique_netifs[${_netif}]}"
fi
_netif_allowlist="${_netif_allowlist}except:${_except_netif};"
done
_netif_allowlist_nm_conf=${initdir}/tmp/netif_allowlist_nm_conf
cat << EOF > "$_netif_allowlist_nm_conf"
[device-others]
match-device=${_netif_allowlist}
managed=false
EOF
inst "$_netif_allowlist_nm_conf" "/etc/NetworkManager/conf.d/10-kdump-netif_allowlist.conf"
rm -f "$_netif_allowlist_nm_conf"
}
_get_nic_driver() {
ethtool -i "$1" | sed -n -E "s/driver: (.*)/\1/p"
}
_get_hpyerv_physical_driver() {
local _physical_nic
_physical_nic=$(find /sys/class/net/"$1"/ -name 'lower_*' | sed -En "s/\/.*lower_(.*)/\1/p")
[[ -n $_physical_nic ]] || return
_get_nic_driver "$_physical_nic"
}
kdump_install_nic_driver() {
local _netif _driver _drivers
_drivers=()
for _netif in $1; do
[[ $_netif == lo ]] && continue
_driver=$(_get_nic_driver "$_netif")
if [[ -z $_driver ]]; then
derror "Failed to get the driver of $_netif"
exit 1
fi
if [[ $_driver == "802.1Q VLAN Support" ]]; then
# ethtool somehow doesn't return the driver name for a VLAN NIC
_driver=8021q
elif [[ $_driver == "team" ]]; then
# install the team mode drivers like team_mode_roundrobin.ko as well
_driver='=drivers/net/team'
elif [[ $_driver == "hv_netvsc" ]]; then
# A Hyper-V VM may have accelerated networking
# https://learn.microsoft.com/en-us/azure/virtual-network/accelerated-networking-overview
# Install the driver of physical NIC as well
_drivers+=("$(_get_hpyerv_physical_driver "$_netif")")
fi
_drivers+=("$_driver")
done
[[ -n ${_drivers[*]} ]] || return
instmods "${_drivers[@]}"
}
kdump_setup_bridge() {
local _netdev=$1
local _brif _dev _mac _kdumpdev
for _dev in `ls /sys/class/net/$_netdev/brif/`; do
_kdumpdev=""
if kdump_is_bond "$_dev"; then
kdump_setup_bond "$_dev"
elif kdump_is_team "$_dev"; then
kdump_setup_team "$_dev"
elif kdump_is_vlan "$_dev"; then
kdump_setup_vlan "$_dev"
else
_mac=$(kdump_get_mac_addr $_dev)
_kdumpdev=$(kdump_setup_ifname $_dev)
echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/41bridge.conf
fi
_save_kdump_netifs "$_dev" "$_kdumpdev"
[[ -z $_kdumpdev ]] && _kdumpdev=$_dev
_brif+="$_kdumpdev,"
done
echo " bridge=$_netdev:$(echo $_brif | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/41bridge.conf
}
kdump_setup_bond() {
local _netdev=$1
local _dev _mac _slaves _kdumpdev
for _dev in `cat /sys/class/net/$_netdev/bonding/slaves`; do
_mac=$(kdump_get_perm_addr $_dev)
_kdumpdev=$(kdump_setup_ifname $_dev)
_save_kdump_netifs "$_dev" "$_kdumpdev"
echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/42bond.conf
_slaves+="$_kdumpdev,"
done
echo -n " bond=$_netdev:$(echo $_slaves | sed 's/,$//')" >> ${initdir}/etc/cmdline.d/42bond.conf
# Get bond options specified in ifcfg
source_ifcfg_file $_netdev
bondoptions=":$(echo $BONDING_OPTS | xargs echo | tr " " ",")"
echo "$bondoptions" >> ${initdir}/etc/cmdline.d/42bond.conf
}
kdump_setup_team() {
local _netdev=$1
local _dev _mac _slaves _kdumpdev
for _dev in `teamnl $_netdev ports | awk -F':' '{print $2}'`; do
_mac=$(kdump_get_perm_addr $_dev)
_kdumpdev=$(kdump_setup_ifname $_dev)
_save_kdump_netifs "$_dev" "$_kdumpdev"
echo -n " ifname=$_kdumpdev:$_mac" >> ${initdir}/etc/cmdline.d/44team.conf
_slaves+="$_kdumpdev,"
done
echo " team=$_netdev:$(echo $_slaves | sed -e 's/,$//')" >> ${initdir}/etc/cmdline.d/44team.conf
#Buggy version teamdctl outputs to stderr!
#Try to use the latest version of teamd.
teamdctl "$_netdev" config dump > ${initdir}/tmp/$$-$_netdev.conf
if [ $? -ne 0 ]
then
derror "teamdctl failed."
exit 1
fi
inst_dir /etc/teamd
inst_simple ${initdir}/tmp/$$-$_netdev.conf "/etc/teamd/$_netdev.conf"
rm -f ${initdir}/tmp/$$-$_netdev.conf
}
kdump_setup_vlan() {
local _netdev=$1
local _phydev="$(awk '/^Device:/{print $2}' /proc/net/vlan/"$_netdev")"
local _netmac="$(kdump_get_mac_addr $_phydev)"
local _kdumpdev
#Just support vlan over bond and team
if kdump_is_bridge "$_phydev"; then
derror "Vlan over bridge is not supported!"
exit 1
elif kdump_is_bond "$_phydev"; then
kdump_setup_bond "$_phydev"
echo " vlan=$(kdump_setup_ifname $_netdev):$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf
else
_kdumpdev="$(kdump_setup_ifname $_phydev)"
echo " vlan=$(kdump_setup_ifname $_netdev):$_kdumpdev ifname=$_kdumpdev:$_netmac" > ${initdir}/etc/cmdline.d/43vlan.conf
fi
_save_kdump_netifs "$_phydev" "$_kdumpdev"
}
# find online znet device
# return ifname (_netdev)
# code reaped from the list_configured function of
# https://github.com/hreinecke/s390-tools/blob/master/zconf/znetconf
find_online_znet_device() {
local CCWGROUPBUS_DEVICEDIR="/sys/bus/ccwgroup/devices"
local NETWORK_DEVICES d ifname ONLINE
[ ! -d "$CCWGROUPBUS_DEVICEDIR" ] && return
NETWORK_DEVICES=$(find $CCWGROUPBUS_DEVICEDIR)
for d in $NETWORK_DEVICES
do
[ ! -f "$d/online" ] && continue
read ONLINE < $d/online
if [ $ONLINE -ne 1 ]; then
continue
fi
# determine interface name, if there (only for qeth and if
# device is online)
if [ -f $d/if_name ]
then
read ifname < $d/if_name
elif [ -d $d/net ]
then
ifname=$(ls $d/net/)
fi
[ -n "$ifname" ] && break
done
echo -n "$ifname"
}
# setup s390 znet cmdline
# $1: netdev name
kdump_setup_znet() {
local _options=""
local _netdev=$1
source_ifcfg_file $_netdev
[[ -z "$NETTYPE" ]] && return
[[ -z "$SUBCHANNELS" ]] && return
for i in $OPTIONS; do
_options=${_options},$i
done
echo rd.znet=${NETTYPE},${SUBCHANNELS}${_options} rd.znet_ifname=$(kdump_setup_ifname $_netdev):${SUBCHANNELS} > ${initdir}/etc/cmdline.d/30znet.conf
}
_get_nic_driver() {
ethtool -i "$1" | sed -n -E "s/driver: (.*)/\1/p"
}
_rename_hypver_netdev() {
local _udev_rule_dir
_udev_rule_dir=${initdir}/etc/udev/rules.d
mkdir -p "$_udev_rule_dir"
printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="hv_netvsc", ATTR{address}=="%s", ATTR{type}=="1", NAME="%s"\n' "$2" "$1" > "${_udev_rule_dir}/80-hv_netvsc-ifname.rules"
}
# Setup dracut to bringup a given network interface
kdump_setup_netdev() {
local _netdev=$1 _srcaddr=$2
local _static _proto _ip_conf _ip_opts _ifname_opts kdumpnic
local _netmac=$(kdump_get_mac_addr $_netdev)
local _znet_netdev
kdumpnic=$(kdump_setup_ifname $_netdev)
_znet_netdev=$(find_online_znet_device)
if [[ -n "$_znet_netdev" ]]; then
$(kdump_setup_znet "$_znet_netdev")
if [[ $? != 0 ]]; then
derror "Failed to set up znet"
exit 1
fi
fi
_static=$(kdump_static_ip $_netdev $_srcaddr $kdumpnic)
if [ -n "$_static" ]; then
_proto=none
elif is_ipv6_address $_srcaddr; then
_proto=auto6
else
_proto=dhcp
fi
_ip_conf="${initdir}/etc/cmdline.d/40ip.conf"
_ip_opts=" ip=${_static}$kdumpnic:${_proto}"
# dracut doesn't allow duplicated configuration for same NIC, even they're exactly the same.
# so we have to avoid adding duplicates
# We should also check /proc/cmdline for existing ip=xx arg.
# For example, iscsi boot will specify ip=xxx arg in cmdline.
if [ ! -f $_ip_conf ] || ! grep -q $_ip_opts $_ip_conf &&\
! grep -q "ip=[^[:space:]]*$_netdev" /proc/cmdline; then
echo "$_ip_opts" >> $_ip_conf
fi
if kdump_is_bridge "$_netdev"; then
kdump_setup_bridge "$_netdev"
elif kdump_is_bond "$_netdev"; then
kdump_setup_bond "$_netdev"
elif kdump_is_team "$_netdev"; then
kdump_setup_team "$_netdev"
elif kdump_is_vlan "$_netdev"; then
kdump_setup_vlan "$_netdev"
else
if [[ $(_get_nic_driver "$1") != hv_netvsc ]]; then
_ifname_opts=" ifname=$kdumpnic:$_netmac"
echo "$_ifname_opts" >> $_ip_conf
else
_rename_hypver_netdev "$kdumpnic" "$_netmac"
fi
fi
_save_kdump_netifs "$_netdev" "$_kdumpdev"
kdump_setup_dns "$_netdev"
if [ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]; then
# network-manager module needs this parameter
echo "rd.neednet" >> ${initdir}/etc/cmdline.d/50neednet.conf
fi
}
get_ip_route_field()
{
if `echo $1 | grep -q $2`; then
echo ${1##*$2} | cut -d ' ' -f1
fi
}
#Function:kdump_install_net
#$1: config values of net line in kdump.conf
#$2: srcaddr of network device
kdump_install_net() {
local _server _netdev _srcaddr _route _serv_tmp
local config_val="$1"
_server=$(get_remote_host $config_val)
if is_hostname $_server; then
_serv_tmp=`getent ahosts $_server | grep -v : | head -n 1`
if [ -z "$_serv_tmp" ]; then
_serv_tmp=`getent ahosts $_server | head -n 1`
fi
_server=`echo $_serv_tmp | cut -d' ' -f1`
fi
_route=`/sbin/ip -o route get to $_server 2>&1`
[ $? != 0 ] && echo "Bad kdump location: $config_val" && exit 1
#the field in the ip output changes if we go to another subnet
_srcaddr=$(get_ip_route_field "$_route" "src")
_netdev=$(get_ip_route_field "$_route" "dev")
kdump_setup_netdev "${_netdev}" "${_srcaddr}"
#save netdev used for kdump as cmdline
# Whoever calling kdump_install_net() is setting up the default gateway,
# ie. bootdev/kdumpnic. So don't override the setting if calling
# kdump_install_net() for another time. For example, after setting eth0 as
# the default gate way for network dump, eth1 in the fence kdump path will
# call kdump_install_net again and we don't want eth1 to be the default
# gateway.
if [ ! -f ${initdir}/etc/cmdline.d/60kdumpnic.conf ] &&
[ ! -f ${initdir}/etc/cmdline.d/70bootdev.conf ]; then
echo "kdumpnic=$(kdump_setup_ifname $_netdev)" > ${initdir}/etc/cmdline.d/60kdumpnic.conf
echo "bootdev=$(kdump_setup_ifname $_netdev)" > ${initdir}/etc/cmdline.d/70bootdev.conf
fi
}
# install etc/kdump/pre.d and /etc/kdump/post.d
kdump_install_pre_post_conf() {
if [ -d /etc/kdump/pre.d ]; then
for file in /etc/kdump/pre.d/*; do
if [ -x "$file" ]; then
dracut_install $file
elif [ $file != "/etc/kdump/pre.d/*" ]; then
echo "$file is not executable"
fi
done
fi
if [ -d /etc/kdump/post.d ]; then
for file in /etc/kdump/post.d/*; do
if [ -x "$file" ]; then
dracut_install $file
elif [ $file != "/etc/kdump/post.d/*" ]; then
echo "$file is not executable"
fi
done
fi
}
default_dump_target_install_conf()
{
local _target _fstype
local _mntpoint _save_path
is_user_configured_dump_target && return
_save_path=$(get_bind_mount_source $(get_save_path))
_target=$(get_target_from_path $_save_path)
_mntpoint=$(get_mntpoint_from_target $_target)
_fstype=$(get_fs_type_from_target $_target)
if is_fs_type_nfs $_fstype; then
kdump_install_net "$_target"
_fstype="nfs"
else
_target=$(kdump_get_persistent_dev $_target)
fi
echo "$_fstype $_target" >> ${initdir}/tmp/$$-kdump.conf
# don't touch the path under root mount
if [ "$_mntpoint" != "/" ]; then
_save_path=${_save_path##"$_mntpoint"}
fi
#erase the old path line, then insert the parsed path
sed -i "/^path/d" ${initdir}/tmp/$$-kdump.conf
echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf
}
#install kdump.conf and what user specifies in kdump.conf
kdump_install_conf() {
local _opt _val _pdev
sed -ne '/^#/!p' /etc/kdump.conf > ${initdir}/tmp/$$-kdump.conf
while read _opt _val;
do
# remove inline comments after the end of a directive.
case "$_opt" in
raw)
_pdev=$(persistent_policy="by-id" kdump_get_persistent_dev $_val)
sed -i -e "s#^$_opt[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf
;;
ext[234]|xfs|btrfs|minix)
_pdev=$(kdump_get_persistent_dev $_val)
sed -i -e "s#^$_opt[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf
;;
ssh|nfs)
kdump_install_net "$_val"
;;
dracut_args)
if [[ $(get_dracut_args_fstype "$_val") = nfs* ]] ; then
kdump_install_net "$(get_dracut_args_target "$_val")"
fi
;;
kdump_pre|kdump_post|extra_bins)
dracut_install $_val
;;
core_collector)
dracut_install "${_val%%[[:blank:]]*}"
;;
esac
done <<< "$(read_strip_comments /etc/kdump.conf)"
kdump_install_pre_post_conf
default_dump_target_install_conf
kdump_configure_fence_kdump "${initdir}/tmp/$$-kdump.conf"
inst "${initdir}/tmp/$$-kdump.conf" "/etc/kdump.conf"
rm -f ${initdir}/tmp/$$-kdump.conf
}
# Default sysctl parameters should suffice for kdump kernel.
# Remove custom configurations sysctl.conf & sysctl.d/*
remove_sysctl_conf() {
# As custom configurations like vm.min_free_kbytes can lead
# to OOM issues in kdump kernel, avoid them
rm -f "${initdir}/etc/sysctl.conf"
rm -rf "${initdir}/etc/sysctl.d"
rm -rf "${initdir}/run/sysctl.d"
rm -rf "${initdir}/usr/lib/sysctl.d"
}
kdump_iscsi_get_rec_val() {
local result
# The open-iscsi 742 release changed to using flat files in
# /var/lib/iscsi.
result=$(/sbin/iscsiadm --show -m session -r ${1} | grep "^${2} = ")
result=${result##* = }
echo $result
}
kdump_get_iscsi_initiator() {
local _initiator
local initiator_conf="/etc/iscsi/initiatorname.iscsi"
[ -f "$initiator_conf" ] || return 1
while read _initiator; do
[ -z "${_initiator%%#*}" ] && continue # Skip comment lines
case $_initiator in
InitiatorName=*)
initiator=${_initiator#InitiatorName=}
echo "rd.iscsi.initiator=${initiator}"
return 0;;
*) ;;
esac
done < ${initiator_conf}
return 1
}
# Figure out iBFT session according to session type
is_ibft() {
[ "$(kdump_iscsi_get_rec_val $1 "node.discovery_type")" = fw ]
}
kdump_setup_iscsi_device() {
local path=$1
local tgt_name; local tgt_ipaddr;
local username; local password; local userpwd_str;
local username_in; local password_in; local userpwd_in_str;
local netdev
local srcaddr
local idev
local netroot_str ; local initiator_str;
local netroot_conf="${initdir}/etc/cmdline.d/50iscsi.conf"
local initiator_conf="/etc/iscsi/initiatorname.iscsi"
dinfo "Found iscsi component $1"
# Check once before getting explicit values, so we can bail out early,
# e.g. in case of pure-hardware(all-offload) iscsi.
if ! /sbin/iscsiadm -m session -r ${path} &>/dev/null ; then
return 1
fi
if is_ibft ${path}; then
return
fi
# Remove software iscsi cmdline generated by 95iscsi,
# and let kdump regenerate here.
rm -f ${initdir}/etc/cmdline.d/95iscsi.conf
tgt_name=$(kdump_iscsi_get_rec_val ${path} "node.name")
tgt_ipaddr=$(kdump_iscsi_get_rec_val ${path} "node.conn\[0\].address")
# get and set username and password details
username=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username")
[ "$username" == "" ] && username=""
password=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password")
[ "$password" == "" ] && password=""
username_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.username_in")
[ -n "$username" ] && userpwd_str="$username:$password"
# get and set incoming username and password details
[ "$username_in" == "" ] && username_in=""
password_in=$(kdump_iscsi_get_rec_val ${path} "node.session.auth.password_in")
[ "$password_in" == "" ] && password_in=""
[ -n "$username_in" ] && userpwd_in_str=":$username_in:$password_in"
netdev=$(/sbin/ip route get to ${tgt_ipaddr} | \
sed 's|.*dev \(.*\).*|\1|g')
srcaddr=$(echo $netdev | awk '{ print $3; exit }')
netdev=$(echo $netdev | awk '{ print $1; exit }')
kdump_setup_netdev $netdev $srcaddr
# prepare netroot= command line
# FIXME: Do we need to parse and set other parameters like protocol, port
# iscsi_iface_name, netdev_name, LUN etc.
if is_ipv6_address $tgt_ipaddr; then
tgt_ipaddr="[$tgt_ipaddr]"
fi
netroot_str="netroot=iscsi:${userpwd_str}${userpwd_in_str}@$tgt_ipaddr::::$tgt_name"
[[ -f $netroot_conf ]] || touch $netroot_conf
# If netroot target does not exist already, append.
if ! grep -q $netroot_str $netroot_conf; then
echo $netroot_str >> $netroot_conf
dinfo "Appended $netroot_str to $netroot_conf"
fi
# Setup initator
initiator_str=$(kdump_get_iscsi_initiator)
[ $? -ne "0" ] && derror "Failed to get initiator name" && return 1
# If initiator details do not exist already, append.
if ! grep -q "$initiator_str" $netroot_conf; then
echo "$initiator_str" >> $netroot_conf
dinfo "Appended "$initiator_str" to $netroot_conf"
fi
}
kdump_check_iscsi_targets () {
# If our prerequisites are not met, fail anyways.
type -P iscsistart >/dev/null || return 1
kdump_check_setup_iscsi() {
local _dev
_dev=$1
[[ -L /sys/dev/block/$_dev ]] || return
cd "$(readlink -f /sys/dev/block/$_dev)"
until [[ -d sys || -d iscsi_session ]]; do
cd ..
done
[[ -d iscsi_session ]] && kdump_setup_iscsi_device "$PWD"
}
[[ $hostonly ]] || [[ $mount_needs ]] && {
for_each_host_dev_and_slaves_all kdump_check_setup_iscsi
}
}
# hostname -a is deprecated, do it by ourself
get_alias() {
local ips
local entries
local alias_set
ips=$(hostname -I)
for ip in $ips
do
# in /etc/hosts, alias can come at the 2nd column
entries=$(grep $ip /etc/hosts | awk '{ $1=""; print $0 }')
if [ $? -eq 0 ]; then
alias_set="$alias_set $entries"
fi
done
echo $alias_set
}
is_localhost() {
local hostnames=$(hostname -A)
local shortnames=$(hostname -A -s)
local aliasname=$(get_alias)
local nodename=$1
hostnames="$hostnames $shortnames $aliasname"
for name in ${hostnames}; do
if [ "$name" == "$nodename" ]; then
return 0
fi
done
return 1
}
# retrieves fence_kdump nodes from Pacemaker cluster configuration
get_pcs_fence_kdump_nodes() {
local nodes
# get cluster nodes from cluster cib, get interface and ip address
nodelist=`pcs cluster cib | xmllint --xpath "/cib/status/node_state/@uname" -`
# nodelist is formed as 'uname="node1" uname="node2" ... uname="nodeX"'
# we need to convert each to node1, node2 ... nodeX in each iteration
for node in ${nodelist}; do
# convert $node from 'uname="nodeX"' to 'nodeX'
eval $node
nodename=$uname
# Skip its own node name
if [ "$nodename" = `hostname` -o "$nodename" = `hostname -s` ]; then
continue
fi
nodes="$nodes $nodename"
done
echo $nodes
}
# retrieves fence_kdump args from config file
get_pcs_fence_kdump_args() {
if [ -f $FENCE_KDUMP_CONFIG_FILE ]; then
. $FENCE_KDUMP_CONFIG_FILE
echo $FENCE_KDUMP_OPTS
fi
}
get_generic_fence_kdump_nodes() {
local filtered
local nodes
nodes=$(get_option_value "fence_kdump_nodes")
for node in ${nodes}; do
# Skip its own node name
if is_localhost $node; then
continue
fi
filtered="$filtered $node"
done
echo $filtered
}
# setup fence_kdump in cluster
# setup proper network and install needed files
kdump_configure_fence_kdump () {
local kdump_cfg_file=$1
local nodes
local args
if is_generic_fence_kdump; then
nodes=$(get_generic_fence_kdump_nodes)
elif is_pcs_fence_kdump; then
nodes=$(get_pcs_fence_kdump_nodes)
# set appropriate options in kdump.conf
echo "fence_kdump_nodes $nodes" >> ${kdump_cfg_file}
args=$(get_pcs_fence_kdump_args)
if [ -n "$args" ]; then
echo "fence_kdump_args $args" >> ${kdump_cfg_file}
fi
else
# fence_kdump not configured
return 1
fi
# setup network for each node
for node in ${nodes}; do
kdump_install_net $node
done
dracut_install /etc/hosts
dracut_install /etc/nsswitch.conf
dracut_install $FENCE_KDUMP_SEND
}
# Install a random seed used to feed /dev/urandom
# By the time kdump service starts, /dev/uramdom is already fed by systemd
kdump_install_random_seed() {
local poolsize=`cat /proc/sys/kernel/random/poolsize`
if [ ! -d ${initdir}/var/lib/ ]; then
mkdir -p ${initdir}/var/lib/
fi
dd if=/dev/urandom of=${initdir}/var/lib/random-seed \
bs=$poolsize count=1 2> /dev/null
}
remove_cpu_online_rule() {
local file=${initdir}/usr/lib/udev/rules.d/40-redhat.rules
sed -i '/SUBSYSTEM=="cpu"/d' $file
}
kdump_install_systemd_conf() {
local failure_action=$(get_option_value "failure_action")
# Kdump turns out to require longer default systemd mount timeout
# than 1st kernel(90s by default), we use default 300s for kdump.
grep -r "^[[:space:]]*DefaultTimeoutStartSec=" ${initdir}/etc/systemd/system.conf* &>/dev/null
if [ $? -ne 0 ]; then
mkdir -p ${initdir}/etc/systemd/system.conf.d
echo "[Manager]" > ${initdir}/etc/systemd/system.conf.d/kdump.conf
echo "DefaultTimeoutStartSec=300s" >> ${initdir}/etc/systemd/system.conf.d/kdump.conf
fi
# Forward logs to console directly, and don't read Kmsg, this avoids
# unneccessary memory consumption and make console output more useful.
# Only do so for non fadump image.
mkdir -p ${initdir}/etc/systemd/journald.conf.d
echo "[Journal]" > ${initdir}/etc/systemd/journald.conf.d/kdump.conf
echo "Storage=volatile" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf
echo "ReadKMsg=no" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf
echo "ForwardToConsole=yes" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf
}
install() {
declare -A unique_netifs
local arch _netifs
kdump_module_init
kdump_install_conf
remove_sysctl_conf
# Onlining secondary cpus breaks kdump completely on KVM on Power hosts
# Though we use maxcpus=1 by default but 40-redhat.rules will bring up all
# possible cpus by default. (rhbz1270174 rhbz1266322)
# Thus before we get the kernel fix and the systemd rule fix let's remove
# the cpu online rule in kdump initramfs.
arch=$(uname -m)
if [[ "$arch" = "ppc64le" ]] || [[ "$arch" = "ppc64" ]]; then
remove_cpu_online_rule
fi
if is_ssh_dump_target; then
kdump_install_random_seed
fi
dracut_install -o /etc/adjtime /etc/localtime
inst "$moddir/monitor_dd_progress" "/kdumpscripts/monitor_dd_progress"
chmod +x ${initdir}/kdumpscripts/monitor_dd_progress
inst "/bin/dd" "/bin/dd"
inst "/bin/tail" "/bin/tail"
inst "/bin/date" "/bin/date"
inst "/bin/sync" "/bin/sync"
inst "/bin/cut" "/bin/cut"
inst "/bin/head" "/bin/head"
inst "/sbin/makedumpfile" "/sbin/makedumpfile"
inst "/sbin/vmcore-dmesg" "/sbin/vmcore-dmesg"
inst "/usr/bin/printf" "/sbin/printf"
inst "/usr/bin/logger" "/sbin/logger"
inst "/usr/bin/chmod" "/sbin/chmod"
inst "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh"
inst "/lib/kdump/kdump-lib-initramfs.sh" "/lib/kdump-lib-initramfs.sh"
inst "/lib/kdump/kdump-logger.sh" "/lib/kdump-logger.sh"
inst "$moddir/kdump.sh" "/usr/bin/kdump.sh"
inst "$moddir/kdump-capture.service" "$systemdsystemunitdir/kdump-capture.service"
systemctl -q --root "$initdir" add-wants initrd.target kdump-capture.service
inst "$moddir/kdump-error-handler.sh" "/usr/bin/kdump-error-handler.sh"
inst "$moddir/kdump-error-handler.service" "$systemdsystemunitdir/kdump-error-handler.service"
# Replace existing emergency service and emergency target
cp "$moddir/kdump-emergency.service" "$initdir/$systemdsystemunitdir/emergency.service"
cp "$moddir/kdump-emergency.target" "$initdir/$systemdsystemunitdir/emergency.target"
# Also redirect dracut-emergency to kdump error handler
ln_r "$systemdsystemunitdir/emergency.service" "$systemdsystemunitdir/dracut-emergency.service"
# Check for all the devices and if any device is iscsi, bring up iscsi
# target. Ideally all this should be pushed into dracut iscsi module
# at some point of time.
kdump_check_iscsi_targets
_netifs=$(_get_kdump_netifs)
if [[ -n "$_netifs" ]]; then
kdump_install_nm_netif_allowlist "$_netifs"
kdump_install_nic_driver "$_netifs"
fi
kdump_install_systemd_conf
# For the lvm type target under kdump, in /etc/lvm/lvm.conf we can
# safely replace "reserved_memory=XXXX"(default value is 8192) with
# "reserved_memory=1024" to lower memory pressure under kdump. We do
# it unconditionally here, if "/etc/lvm/lvm.conf" doesn't exist, it
# actually does nothing.
sed -i -e \
's/\(^[[:space:]]*reserved_memory[[:space:]]*=\)[[:space:]]*[[:digit:]]*/\1 1024/' \
${initdir}/etc/lvm/lvm.conf &>/dev/null
# Skip initrd-cleanup.service and initrd-parse-etc.service becasue we don't
# need to switch root. Instead of removing them, we use ConditionPathExists
# to check if /proc/vmcore exists to determine if we are in kdump.
sed -i '/\[Unit\]/a ConditionPathExists=!\/proc\/vmcore' \
"${initdir}/${systemdsystemunitdir}/initrd-cleanup.service" &> /dev/null
sed -i '/\[Unit\]/a ConditionPathExists=!\/proc\/vmcore' \
"${initdir}/${systemdsystemunitdir}/initrd-parse-etc.service" &> /dev/null
# Save more memory by dropping switch root capability
dracut_no_switch_root
}
modules.d/90kernel-network-modules/module-setup.sh 0000755 00000002614 15023162470 0016211 0 ustar 00 #!/bin/bash
# called by dracut
check() {
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
installkernel() {
# Include wired net drivers, excluding wireless
local _arch=$(uname -m)
local _net_symbols='eth_type_trans|register_virtio_device|usbnet_open'
local _unwanted_drivers='/(wireless|isdn|uwb|net/ethernet|net/phy|net/team)/'
local _net_drivers
if [ "$_arch" = "s390" -o "$_arch" = "s390x" ]; then
dracut_instmods -o -P ".*${_unwanted_drivers}.*" -s "$_net_symbols" "=drivers/s390/net"
fi
if [[ $hostonly_mode == 'strict' ]] && [[ -n ${hostonly_nics+x} ]]; then
for _nic in $hostonly_nics; do
_net_drivers=$(get_dev_module /sys/class/net/$_nic)
if ! [[ $_net_drivers ]]; then
derror "--hostonly-nics contains invalid NIC '$_nic'"
continue
fi
hostonly="" instmods $_net_drivers
done
return 0
fi
dracut_instmods -o -P ".*${_unwanted_drivers}.*" -s "$_net_symbols" "=drivers/net"
#instmods() will take care of hostonly
instmods \
=drivers/net/phy \
=drivers/net/team \
=drivers/net/ethernet \
ecb arc4 bridge stp llc ipv6 bonding 8021q ipvlan macvlan af_packet virtio_net xennet
hostonly="" instmods iscsi_ibft crc32c iscsi_boot_sysfs
}
# called by dracut
install() {
return 0
}
modules.d/98syslog/rsyslogd-stop.sh 0000755 00000000436 15023162470 0013332 0 ustar 00 #!/bin/sh
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
# Kills rsyslogd
if [ -f /var/run/syslogd.pid ]; then
read pid < /var/run/syslogd.pid
kill $pid
kill -0 $pid && kill -9 $pid
else
warn "rsyslogd-stop: Could not find a pid for rsyslogd. Won't kill it."
fi
modules.d/98syslog/syslog-cleanup.sh 0000755 00000000627 15023162470 0013450 0 ustar 00 #!/bin/sh
# Just cleans up a previously started syslogd
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
if [ -f /tmp/syslog.server ]; then
read syslogtype < /tmp/syslog.type
if command -v "${syslogtype}-stop" >/dev/null; then
${syslogtype}-stop
else
warn "syslog-cleanup: Could not find script to stop syslog of type \"$syslogtype\". Syslog will not be stopped."
fi
fi modules.d/98syslog/rsyslogd-start.sh 0000755 00000002321 15023162470 0013475 0 ustar 00 #!/bin/sh
# Triggered by initqueue/online and starts rsyslogd with bootparameters
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
# prevent starting again if already running
if [ -f /var/run/syslogd.pid ]; then
read pid < /var/run/syslogd.pid
kill -0 $pid && exit 0
fi
rsyslog_config() {
local server=$1
shift
local syslog_template=$1
shift
local filters=$*
local filter=
cat $syslog_template
(
# disable shell expansion / globbing
# since filters contain such characters
set -f
for filter in $filters; do
echo "${filter} @${server}"
done
)
#echo "*.* /tmp/syslog"
}
[ -f /tmp/syslog.type ] && read type < /tmp/syslog.type
[ -f /tmp/syslog.server ] && read server < /tmp/syslog.server
[ -f /tmp/syslog.filters ] && read filters < /tmp/syslog.filters
[ -z "$filters" ] && filters="kern.*"
[ -f /tmp/syslog.conf ] && read conf < /tmp/syslog.conf
[ -z "$conf" ] && conf="/etc/rsyslog.conf" && echo "$conf" > /tmp/syslog.conf
if [ $type == "rsyslogd" ]; then
template=/etc/templates/rsyslog.conf
if [ -n "$server" ]; then
rsyslog_config "$server" "$template" "$filters" > $conf
rsyslogd -c3
fi
fi
modules.d/98syslog/README 0000644 00000001501 15023162470 0011014 0 ustar 00 Syslog support for dracut
This module provides syslog functionality in the initrd.
This is especially interesting when complex configuration being
used to provide access to the device the rootfs resides on.
When this module is installed into the ramfs it is triggered by
the udev event from the nic being setup (online).
Then if syslog is configured it is started and will forward all
kernel messages to the given syslog server.
The syslog implementation is detected automatically by finding the
appropriate binary with the following order:
rsyslogd
syslogd
syslog-ng
Then if detected the syslog.conf is generated and syslog is started.
Bootparameters:
syslogserver=ip Where to syslog to
sysloglevel=level What level has to be logged
syslogtype=rsyslog|syslog|syslogng
Don't auto detect syslog but set it
modules.d/98syslog/rsyslog.conf 0000644 00000001464 15023162470 0012515 0 ustar 00 #rsyslog v3 config file
# if you experience problems, check
# http://www.rsyslog.com/troubleshoot for assistance
#### MODULES ####
$ModLoad imuxsock.so # provides support for local system logging (e.g. via logger command)
$ModLoad imklog.so # provides kernel logging support (previously done by rklogd)
#$ModLoad immark.so # provides --MARK-- message capability
# Provides UDP syslog reception
#$ModLoad imudp.so
#$UDPServerRun 514
# Provides TCP syslog reception
#$ModLoad imtcp.so
#$InputTCPServerRun 514
#### GLOBAL DIRECTIVES ####
# Use default timestamp format
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
# File syncing capability is disabled by default. This feature is usually not required,
# not useful and an extreme performance hit
#$ActionFileEnableSync on
#### RULES ####
modules.d/98syslog/parse-syslog-opts.sh 0000755 00000002202 15023162470 0014105 0 ustar 00 #!/bin/sh
# Parses the syslog commandline options
#
#Bootparameters:
#syslogserver=ip Where to syslog to
#sysloglevel=level What level has to be logged
#syslogtype=rsyslog|syslog|syslogng
# Don't auto detect syslog but set it
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
detect_syslog() {
syslogtype=""
if [ -e /sbin/rsyslogd ]; then
syslogtype="rsyslogd"
elif [ -e /sbin/syslogd ]; then
syslogtype="syslogd"
elif [ -e /sbin/syslog-ng ]; then
syslogtype="syslog-ng"
else
warn "Could not find any syslog binary although the syslogmodule is selected to be installed. Please check."
fi
echo "$syslogtype"
[ -n "$syslogtype" ]
}
syslogserver=$(getarg syslog.server -d syslog)
syslogfilters=$(getargs syslog.filter -d filter)
syslogtype=$(getarg syslog.type -d syslogtype)
[ -n "$syslogserver" ] && echo $syslogserver > /tmp/syslog.server
[ -n "$syslogfilters" ] && echo "$syslogfilters" > /tmp/syslog.filters
if [ -n "$syslogtype" ]; then
echo "$syslogtype" > /tmp/syslog.type
else
syslogtype=$(detect_syslog)
echo $syslogtype > /tmp/syslog.type
fi
modules.d/98syslog/module-setup.sh 0000755 00000002221 15023162470 0013116 0 ustar 00 #!/bin/bash
# called by dracut
check() {
# do not add this module by default
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
install() {
local _i
local _installs
if find_binary rsyslogd >/dev/null; then
_installs="rsyslogd"
inst_libdir_file rsyslog/lmnet.so rsyslog/imklog.so rsyslog/imuxsock.so rsyslog/imjournal.so
elif find_binary syslogd >/dev/null; then
_installs="syslogd"
elif find_binary syslog-ng >/dev/null; then
_installs="syslog-ng"
else
derror "Could not find any syslog binary although the syslogmodule" \
"is selected to be installed. Please check."
fi
if [ -n "$_installs" ]; then
inst_multiple cat $_installs
inst_hook cmdline 90 "$moddir/parse-syslog-opts.sh"
inst_hook cleanup 99 "$moddir/syslog-cleanup.sh"
inst_hook initqueue/online 70 "$moddir/rsyslogd-start.sh"
inst_simple "$moddir/rsyslogd-stop.sh" /sbin/rsyslogd-stop
mkdir -m 0755 -p ${initdir}/etc/templates
inst_simple "${moddir}/rsyslog.conf" /etc/templates/rsyslog.conf
fi
dracut_need_initqueue
}
modules.d/98dracut-systemd/dracut-cmdline-ask.sh 0000755 00000000642 15023162470 0015577 0 ustar 00 #!/bin/bash
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
getarg "rd.cmdline=ask" || exit 0
sleep 0.5
echo
sleep 0.5
echo
sleep 0.5
echo
echo
echo
echo
echo "Enter additional kernel command line parameter (end with ctrl-d or .)"
while read -e -p "> " line || [ -n "$line" ]; do
[[ "$line" == "." ]] && break
[[ "$line" ]] && printf -- "%s\n" "$line" >> /etc/cmdline.d/99-cmdline-ask.conf
done
exit 0
modules.d/98dracut-systemd/dracut-emergency.service 0000644 00000001251 15023162470 0016406 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=Dracut Emergency Shell
DefaultDependencies=no
After=systemd-vconsole-setup.service
Wants=systemd-vconsole-setup.service
Conflicts=shutdown.target emergency.target
[Service]
Environment=HOME=/
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
WorkingDirectory=/
ExecStart=-/bin/dracut-emergency
ExecStopPost=-/bin/rm -f -- /.console_lock
Type=oneshot
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
TasksMax=infinity
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/dracut-cmdline.service 0000644 00000001610 15023162470 0016042 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=dracut cmdline hook
Documentation=man:dracut-cmdline.service(8)
DefaultDependencies=no
Before=dracut-pre-udev.service
After=systemd-journald.socket
Wants=systemd-journald.socket
ConditionPathExists=/usr/lib/initrd-release
ConditionPathExistsGlob=|/etc/cmdline.d/*.conf
ConditionDirectoryNotEmpty=|/lib/dracut/hooks/cmdline
ConditionKernelCommandLine=|rd.break=cmdline
ConditionKernelCommandLine=|resume
ConditionKernelCommandLine=|noresume
Conflicts=shutdown.target emergency.target
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=-/bin/dracut-cmdline
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
KillMode=process
RemainAfterExit=yes
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/rootfs-generator.sh 0000755 00000010070 15023162470 0015424 0 ustar 00 #!/bin/sh
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
generator_wait_for_dev()
{
local _name
local _timeout
_name="$(str_replace "$1" '/' '\x2f')"
_timeout=$(getarg rd.timeout)
_timeout=${_timeout:-0}
if ! [ -e "$hookdir/initqueue/finished/devexists-${_name}.sh" ]; then
# If a LUKS device needs unlocking via systemd in the initrd, assume
# it's for the root device. In that case, don't block on it if it's
# after remote-fs-pre.target since the initqueue is ordered before it so
# it will never actually show up (think Tang-pinned rootfs).
cat > "$hookdir/initqueue/finished/devexists-${_name}.sh" << EOF
if ! grep -q After=remote-fs-pre.target /run/systemd/generator/systemd-cryptsetup@*.service 2>/dev/null; then
[ -e "$1" ]
fi
EOF
{
printf '[ -e "%s" ] || ' $1
printf 'warn "\"%s\" does not exist"\n' $1
} >> "$hookdir/emergency/80-${_name}.sh"
fi
_name=$(dev_unit_name "$1")
if ! [ -L "$GENERATOR_DIR"/initrd.target.wants/${_name}.device ]; then
[ -d "$GENERATOR_DIR"/initrd.target.wants ] || mkdir -p "$GENERATOR_DIR"/initrd.target.wants
ln -s ../${_name}.device "$GENERATOR_DIR"/initrd.target.wants/${_name}.device
fi
if ! [ -f "$GENERATOR_DIR"/${_name}.device.d/timeout.conf ]; then
mkdir -p "$GENERATOR_DIR"/${_name}.device.d
{
echo "[Unit]"
echo "JobTimeoutSec=$_timeout"
echo "JobRunningTimeoutSec=$_timeout"
} > "$GENERATOR_DIR"/${_name}.device.d/timeout.conf
fi
}
generator_mount_rootfs()
{
local _type=$2
local _flags=$3
local _name
[ -z "$1" ] && return 0
_name=$(dev_unit_name "$1")
[ -d "$GENERATOR_DIR" ] || mkdir -p "$GENERATOR_DIR"
if ! [ -f "$GENERATOR_DIR"/sysroot.mount ]; then
{
echo "[Unit]"
echo "Before=initrd-root-fs.target"
echo "Requires=systemd-fsck@${_name}.service"
echo "After=systemd-fsck@${_name}.service"
echo "[Mount]"
echo "Where=/sysroot"
echo "What=$1"
echo "Options=${_flags}"
echo "Type=${_type}"
} > "$GENERATOR_DIR"/sysroot.mount
fi
if ! [ -L "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount ]; then
[ -d "$GENERATOR_DIR"/initrd-root-fs.target.requires ] || mkdir -p "$GENERATOR_DIR"/initrd-root-fs.target.requires
ln -s ../sysroot.mount "$GENERATOR_DIR"/initrd-root-fs.target.requires/sysroot.mount
fi
}
generator_fsck_after_pre_mount()
{
local _name
[ -z "$1" ] && return 0
_name=$(dev_unit_name "$1")
[ -d /run/systemd/generator/systemd-fsck@${_name}.service.d ] || mkdir -p /run/systemd/generator/systemd-fsck@${_name}.service.d
if ! [ -f /run/systemd/generator/systemd-fsck@${_name}.service.d/after-pre-mount.conf ]; then
{
echo "[Unit]"
echo "After=dracut-pre-mount.service"
} > /run/systemd/generator/systemd-fsck@${_name}.service.d/after-pre-mount.conf
fi
}
root=$(getarg root=)
case "$root" in
block:LABEL=*|LABEL=*)
root="${root#block:}"
root="$(echo $root | sed 's,/,\\x2f,g')"
root="block:/dev/disk/by-label/${root#LABEL=}"
rootok=1 ;;
block:UUID=*|UUID=*)
root="${root#block:}"
root="block:/dev/disk/by-uuid/${root#UUID=}"
rootok=1 ;;
block:PARTUUID=*|PARTUUID=*)
root="${root#block:}"
root="block:/dev/disk/by-partuuid/${root#PARTUUID=}"
rootok=1 ;;
block:PARTLABEL=*|PARTLABEL=*)
root="${root#block:}"
root="block:/dev/disk/by-partlabel/${root#PARTLABEL=}"
rootok=1 ;;
/dev/nfs) # ignore legacy /dev/nfs
;;
/dev/*)
root="block:${root}"
rootok=1 ;;
esac
GENERATOR_DIR="$1"
if [ "$rootok" = "1" ]; then
generator_wait_for_dev "${root#block:}" "$RDRETRY"
generator_fsck_after_pre_mount "${root#block:}"
strstr "$(cat /proc/cmdline)" 'root=' || generator_mount_rootfs "${root#block:}" "$(getarg rootfstype=)" "$(getarg rootflags=)"
fi
exit 0
modules.d/98dracut-systemd/dracut-mount.sh 0000755 00000002034 15023162470 0014547 0 ustar 00 #!/bin/sh
export DRACUT_SYSTEMD=1
if [ -f /dracut-state.sh ]; then
. /dracut-state.sh 2>/dev/null
fi
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
source_conf /etc/conf.d
make_trace_mem "hook mount" '1:shortmem' '2+:mem' '3+:slab'
getarg 'rd.break=mount' -d 'rdbreak=mount' && emergency_shell -n mount "Break mount"
# mount scripts actually try to mount the root filesystem, and may
# be sourced any number of times. As soon as one suceeds, no more are sourced.
i=0
while :; do
if ismounted "$NEWROOT"; then
usable_root "$NEWROOT" && break;
umount "$NEWROOT"
fi
for f in $hookdir/mount/*.sh; do
[ -f "$f" ] && . "$f"
if ismounted "$NEWROOT"; then
usable_root "$NEWROOT" && break;
warn "$NEWROOT has no proper rootfs layout, ignoring and removing offending mount hook"
umount "$NEWROOT"
rm -f -- "$f"
fi
done
i=$(($i+1))
[ $i -gt 20 ] && emergency_shell "Can't mount root filesystem"
done
export -p > /dracut-state.sh
exit 0
modules.d/98dracut-systemd/dracut-initqueue.service.8 0000644 00000003016 15023162470 0016607 0 ustar 00 '\" t
.\" Title: dracut-initqueue.service
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 10/09/2018
.\" Manual: dracut
.\" Source: dracut
.\" Language: English
.\"
.TH "DRACUT\-INITQUEUE\&." "8" "10/09/2018" "dracut" "dracut"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
dracut-initqueue.service \- runs the dracut main loop to find the real root
.SH "SYNOPSIS"
.sp
dracut\-initqueue\&.service
.SH "DESCRIPTION"
.sp
This service runs all the main loop of dracut in the initramfs to find the real root\&.
.SH "AUTHORS"
.sp
Harald Hoyer
.SH "SEE ALSO"
.sp
\fBdracut\&.bootup\fR(7) \fBdracut\fR(8)
modules.d/98dracut-systemd/emergency.service 0000644 00000001264 15023162470 0015132 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=Emergency Shell
DefaultDependencies=no
After=systemd-vconsole-setup.service
Wants=systemd-vconsole-setup.service
Conflicts=shutdown.target
Before=shutdown.target
[Service]
Environment=HOME=/
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
WorkingDirectory=/
ExecStart=/bin/dracut-emergency
ExecStopPost=-/usr/bin/systemctl --fail --no-block default
Type=idle
StandardInput=tty-force
StandardOutput=inherit
StandardError=inherit
KillMode=process
IgnoreSIGPIPE=no
TasksMax=infinity
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/dracut-mount.service.8 0000644 00000002773 15023162470 0015752 0 ustar 00 '\" t
.\" Title: dracut-mount.service
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 10/09/2018
.\" Manual: dracut
.\" Source: dracut
.\" Language: English
.\"
.TH "DRACUT\-MOUNT\&.SERV" "8" "10/09/2018" "dracut" "dracut"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
dracut-mount.service \- runs the dracut hooks after /sysroot is mounted
.SH "SYNOPSIS"
.sp
dracut\-mount\&.service
.SH "DESCRIPTION"
.sp
This service runs all dracut hooks after the real root is mounted on /sysroot\&.
.SH "AUTHORS"
.sp
Harald Hoyer
.SH "SEE ALSO"
.sp
\fBdracut\&.bootup\fR(7) \fBdracut\fR(8)
modules.d/98dracut-systemd/dracut-mount.service 0000644 00000001431 15023162470 0015572 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=dracut mount hook
Documentation=man:dracut-mount.service(8)
After=initrd-root-fs.target initrd-parse-etc.service
After=dracut-initqueue.service dracut-pre-mount.service
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/lib/dracut/hooks/mount
ConditionKernelCommandLine=|rd.break=mount
DefaultDependencies=no
Conflicts=shutdown.target emergency.target
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=-/bin/dracut-mount
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
KillMode=process
RemainAfterExit=yes
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/dracut-pre-mount.service 0000644 00000001466 15023162470 0016366 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=dracut pre-mount hook
Documentation=man:dracut-pre-mount.service(8)
DefaultDependencies=no
Before=initrd-root-fs.target sysroot.mount systemd-fsck-root.service
After=dracut-initqueue.service cryptsetup.target
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-mount
ConditionKernelCommandLine=|rd.break=pre-mount
Conflicts=shutdown.target emergency.target
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=-/bin/dracut-pre-mount
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
KillMode=process
RemainAfterExit=yes
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/dracut-pre-trigger.service.8 0000644 00000003016 15023162470 0017026 0 ustar 00 '\" t
.\" Title: dracut-pre-trigger.service
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 10/09/2018
.\" Manual: dracut
.\" Source: dracut
.\" Language: English
.\"
.TH "DRACUT\-PRE\-TRIGGER" "8" "10/09/2018" "dracut" "dracut"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
dracut-pre-trigger.service \- runs the dracut hooks before udevd is triggered
.SH "SYNOPSIS"
.sp
dracut\-pre\-trigger\&.service
.SH "DESCRIPTION"
.sp
This service runs all dracut hooks before udevd is triggered in the initramfs\&.
.SH "AUTHORS"
.sp
Harald Hoyer
.SH "SEE ALSO"
.sp
\fBdracut\&.bootup\fR(7) \fBdracut\fR(8)
modules.d/98dracut-systemd/dracut-cmdline.sh 0000755 00000005133 15023162470 0015023 0 ustar 00 #!/bin/sh
if [ -f /dracut-state.sh ]; then
. /dracut-state.sh 2>/dev/null
fi
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
[ -f /usr/lib/initrd-release ] && . /usr/lib/initrd-release
[ -n "$VERSION" ] && info "dracut-$VERSION"
if ! getargbool 1 'rd.hostonly'; then
[ -f /etc/cmdline.d/99-cmdline-ask.conf ] && mv /etc/cmdline.d/99-cmdline-ask.conf /tmp/99-cmdline-ask.conf
remove_hostonly_files
[ -f /tmp/99-cmdline-ask.conf ] && mv /tmp/99-cmdline-ask.conf /etc/cmdline.d/99-cmdline-ask.conf
fi
info "Using kernel command line parameters:" $(getcmdline)
getargbool 0 rd.udev.log-priority=info -d rd.udev.info -d -n -y rdudevinfo && echo 'udev_log="info"' >> /etc/udev/udev.conf
getargbool 0 rd.udev.log-priority=debug -d rd.udev.debug -d -n -y rdudevdebug && echo 'udev_log="debug"' >> /etc/udev/udev.conf
source_conf /etc/conf.d
# Get the "root=" parameter from the kernel command line, but differentiate
# between the case where it was set to the empty string and the case where it
# wasn't specified at all.
if ! root="$(getarg root=)"; then
root_unset='UNSET'
fi
rflags="$(getarg rootflags=)"
getargbool 0 ro && rflags="${rflags},ro"
getargbool 0 rw && rflags="${rflags},rw"
rflags="${rflags#,}"
fstype="$(getarg rootfstype=)"
if [ -z "$fstype" ]; then
fstype="auto"
fi
export root
export rflags
export fstype
make_trace_mem "hook cmdline" '1+:mem' '1+:iomem' '3+:slab'
# run scriptlets to parse the command line
getarg 'rd.break=cmdline' -d 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline"
source_hook cmdline
[ -f /lib/dracut/parse-resume.sh ] && . /lib/dracut/parse-resume.sh
case "${root}${root_unset}" in
block:LABEL=*|LABEL=*)
root="${root#block:}"
root="$(echo $root | sed 's,/,\\x2f,g')"
root="block:/dev/disk/by-label/${root#LABEL=}"
rootok=1 ;;
block:UUID=*|UUID=*)
root="${root#block:}"
root="block:/dev/disk/by-uuid/${root#UUID=}"
rootok=1 ;;
block:PARTUUID=*|PARTUUID=*)
root="${root#block:}"
root="block:/dev/disk/by-partuuid/${root#PARTUUID=}"
rootok=1 ;;
block:PARTLABEL=*|PARTLABEL=*)
root="${root#block:}"
root="block:/dev/disk/by-partlabel/${root#PARTLABEL=}"
rootok=1 ;;
/dev/*)
root="block:${root}"
rootok=1 ;;
UNSET|gpt-auto)
# systemd's gpt-auto-generator handles this case.
rootok=1 ;;
esac
[ -z "${root}${root_unset}" ] && die "Empty root= argument"
[ -z "$rootok" ] && die "Don't know how to handle 'root=$root'"
export root rflags fstype netroot NEWROOT
export -p > /dracut-state.sh
exit 0
modules.d/98dracut-systemd/dracut-cmdline-ask.service 0000644 00000001517 15023162470 0016624 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=dracut ask for additional cmdline parameters
DefaultDependencies=no
Before=dracut-cmdline.service
After=systemd-journald.socket
After=systemd-vconsole-setup.service
Requires=systemd-vconsole-setup.service
Wants=systemd-journald.socket
ConditionPathExists=/usr/lib/initrd-release
ConditionKernelCommandLine=|rd.cmdline=ask
ConditionPathExistsGlob=|/etc/cmdline.d/*.conf
Conflicts=shutdown.target emergency.target
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=-/bin/dracut-cmdline-ask
StandardInput=tty
StandardOutput=inherit
StandardError=inherit
RemainAfterExit=yes
KillMode=process
IgnoreSIGPIPE=no
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/dracut-pre-pivot.service.8 0000644 00000003005 15023162470 0016522 0 ustar 00 '\" t
.\" Title: dracut-pre-pivot.service
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 10/09/2018
.\" Manual: dracut
.\" Source: dracut
.\" Language: English
.\"
.TH "DRACUT\-PRE\-PIVOT\&" "8" "10/09/2018" "dracut" "dracut"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
dracut-pre-pivot.service \- runs the dracut hooks before switching root
.SH "SYNOPSIS"
.sp
dracut\-pre\-pivot\&.service
.SH "DESCRIPTION"
.sp
This service runs all dracut hooks before the system switched to the real root\&.
.SH "AUTHORS"
.sp
Harald Hoyer
.SH "SEE ALSO"
.sp
\fBdracut\&.bootup\fR(7) \fBdracut\fR(8)
modules.d/98dracut-systemd/dracut-pre-mount.sh 0000755 00000000766 15023162470 0015345 0 ustar 00 #!/bin/sh
export DRACUT_SYSTEMD=1
if [ -f /dracut-state.sh ]; then
. /dracut-state.sh 2>/dev/null
fi
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
source_conf /etc/conf.d
make_trace_mem "hook pre-mount" '1:shortmem' '2+:mem' '3+:slab'
# pre pivot scripts are sourced just before we doing cleanup and switch over
# to the new root.
getarg 'rd.break=pre-mount' 'rdbreak=pre-mount' && emergency_shell -n pre-mount "Break pre-mount"
source_hook pre-mount
export -p > /dracut-state.sh
exit 0
modules.d/98dracut-systemd/dracut-shutdown.service.8.asc 0000644 00000003530 15023162470 0017220 0 ustar 00 DRACUT-SHUTDOWN.SERVICE(8)
===========================
:doctype: manpage
:man source: dracut
:man manual: dracut
NAME
----
dracut-shutdown.service - unpack the initramfs to /run/initramfs
SYNOPSIS
--------
dracut-shutdown.service
DESCRIPTION
-----------
This service unpacks the initramfs image to /run/initramfs.
systemd pivots into /run/initramfs at shutdown, so the root filesystem
can be safely unmounted.
The following steps are executed during a shutdown:
* systemd switches to the shutdown.target
* systemd starts /lib/systemd/system/shutdown.target.wants/dracut-shutdown.service
* dracut-shutdown.service executes /usr/lib/dracut/dracut-initramfs-restore which unpacks the initramfs to /run/initramfs
* systemd finishes shutdown.target
* systemd kills all processes
* systemd tries to unmount everything and mounts the remaining read-only
* systemd checks, if there is a /run/initramfs/shutdown executable
* if yes, it does a pivot_root to /run/initramfs and executes ./shutdown. The old root is then mounted on /oldroot. /usr/lib/dracut/modules.d/99shutdown/shutdown.sh is the shutdown executable.
* shutdown will try to umount every /oldroot mount and calls the various shutdown hooks from the dracut modules
This ensures, that all devices are disassembled and unmounted cleanly.
To debug the shutdown process, you can get a shell in the shutdown procedure
by injecting "rd.break=pre-shutdown rd.shell" or "rd.break=shutdown rd.shell".
----
# mkdir -p /run/initramfs/etc/cmdline.d
# echo "rd.break=pre-shutdown rd.shell" > /run/initramfs/etc/cmdline.d/debug.conf
# touch /run/initramfs/.need_shutdown
----
In case the unpack of the initramfs fails, dracut-shutdown-onfailure.service
executes to make sure switch root doesn't happen, since it would result in
switching to an incomplete initramfs.
AUTHORS
-------
Harald Hoyer
SEE ALSO
--------
*dracut*(8)
modules.d/98dracut-systemd/dracut-mount.service.8.asc 0000644 00000000640 15023162470 0016506 0 ustar 00 DRACUT-MOUNT.SERVICE(8)
=======================
:doctype: manpage
:man source: dracut
:man manual: dracut
NAME
----
dracut-mount.service - runs the dracut hooks after /sysroot is mounted
SYNOPSIS
--------
dracut-mount.service
DESCRIPTION
-----------
This service runs all dracut hooks after the real root is mounted on /sysroot.
AUTHORS
-------
Harald Hoyer
SEE ALSO
--------
*dracut.bootup*(7) *dracut*(8)
modules.d/98dracut-systemd/dracut-shutdown.service 0000644 00000000670 15023162470 0016307 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=Restore /run/initramfs on shutdown
Documentation=man:dracut-shutdown.service(8)
After=local-fs.target boot.mount boot.automount
Wants=local-fs.target
ConditionPathExists=!/run/initramfs/bin/sh
OnFailure=dracut-shutdown-onfailure.service
[Service]
RemainAfterExit=yes
Type=oneshot
ExecStart=/bin/true
ExecStop=/usr/lib/dracut/dracut-initramfs-restore
modules.d/98dracut-systemd/dracut-pre-udev.service 0000644 00000001741 15023162470 0016163 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=dracut pre-udev hook
Documentation=man:dracut-pre-udev.service(8)
DefaultDependencies=no
Before=systemd-udevd.service dracut-pre-trigger.service
After=dracut-cmdline.service
Wants=dracut-cmdline.service
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-udev
ConditionKernelCommandLine=|rd.break=pre-udev
ConditionKernelCommandLine=|rd.driver.blacklist
ConditionKernelCommandLine=|rd.driver.pre
ConditionKernelCommandLine=|rd.driver.post
ConditionPathExistsGlob=|/etc/cmdline.d/*.conf
Conflicts=shutdown.target emergency.target
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=-/bin/dracut-pre-udev
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
KillMode=process
RemainAfterExit=yes
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/dracut-pre-mount.service.8 0000644 00000003012 15023162470 0016521 0 ustar 00 '\" t
.\" Title: dracut-pre-mount.service
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 10/09/2018
.\" Manual: dracut
.\" Source: dracut
.\" Language: English
.\"
.TH "DRACUT\-PRE\-MOUNT\&" "8" "10/09/2018" "dracut" "dracut"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
dracut-pre-mount.service \- runs the dracut hooks before /sysroot is mounted
.SH "SYNOPSIS"
.sp
dracut\-pre\-mount\&.service
.SH "DESCRIPTION"
.sp
This service runs all dracut hooks before the real root is mounted on /sysroot\&.
.SH "AUTHORS"
.sp
Harald Hoyer
.SH "SEE ALSO"
.sp
\fBdracut\&.bootup\fR(7) \fBdracut\fR(8)
modules.d/98dracut-systemd/dracut-pre-pivot.service 0000644 00000002145 15023162470 0016360 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=dracut pre-pivot and cleanup hook
Documentation=man:dracut-pre-pivot.service(8)
DefaultDependencies=no
After=initrd.target initrd-parse-etc.service sysroot.mount
After=dracut-initqueue.service dracut-pre-mount.service dracut-mount.service
Before=initrd-cleanup.service
Wants=remote-fs.target
After=remote-fs.target
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-pivot
ConditionDirectoryNotEmpty=|/lib/dracut/hooks/cleanup
ConditionKernelCommandLine=|rd.break=pre-pivot
ConditionKernelCommandLine=|rd.break=cleanup
ConditionKernelCommandLine=|rd.break
ConditionPathExists=|/dev/root
ConditionPathExists=|/dev/nfs
Conflicts=shutdown.target emergency.target
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=-/bin/dracut-pre-pivot
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
KillMode=process
RemainAfterExit=yes
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/dracut-pre-trigger.sh 0000755 00000000723 15023162470 0015637 0 ustar 00 #!/bin/sh
export DRACUT_SYSTEMD=1
if [ -f /dracut-state.sh ]; then
. /dracut-state.sh 2>/dev/null
fi
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
source_conf /etc/conf.d
make_trace_mem "hook pre-trigger" '1:shortmem' '2+:mem' '3+:slab'
source_hook pre-trigger
getarg 'rd.break=pre-trigger' 'rdbreak=pre-trigger' && emergency_shell -n pre-trigger "Break pre-trigger"
udevadm control --reload >/dev/null 2>&1 || :
export -p > /dracut-state.sh
exit 0
modules.d/98dracut-systemd/dracut-cmdline.service.8.asc 0000644 00000000672 15023162470 0016764 0 ustar 00 DRACUT-CMDLINE.SERVICE(8)
=========================
:doctype: manpage
:man source: dracut
:man manual: dracut
NAME
----
dracut-cmdline.service - runs the dracut hooks to parse the kernel command line
SYNOPSIS
--------
dracut-cmdline.service
DESCRIPTION
-----------
This service runs all the dracut hooks to parse the kernel command line in
the initramfs.
AUTHORS
-------
Harald Hoyer
SEE ALSO
--------
*dracut.bootup*(7) *dracut*(8)
modules.d/98dracut-systemd/dracut-initqueue.sh 0000755 00000004143 15023162470 0015420 0 ustar 00 #!/bin/sh
export DRACUT_SYSTEMD=1
if [ -f /dracut-state.sh ]; then
. /dracut-state.sh 2>/dev/null
fi
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
source_conf /etc/conf.d
make_trace_mem "hook initqueue" '1:shortmem' '2+:mem' '3+:slab'
getarg 'rd.break=initqueue' -d 'rdbreak=initqueue' && emergency_shell -n initqueue "Break before initqueue"
RDRETRY=$(getarg rd.retry -d 'rd_retry=')
RDRETRY=${RDRETRY:-180}
RDRETRY=$(($RDRETRY*2))
export RDRETRY
main_loop=0
export main_loop
while :; do
check_finished && break
udevadm settle --exit-if-exists=$hookdir/initqueue/work
check_finished && break
if [ -f $hookdir/initqueue/work ]; then
rm -f -- "$hookdir/initqueue/work"
fi
for job in $hookdir/initqueue/*.sh; do
[ -e "$job" ] || break
job=$job . $job
check_finished && break 2
done
udevadm settle --timeout=0 >/dev/null 2>&1 || continue
for job in $hookdir/initqueue/settled/*.sh; do
[ -e "$job" ] || break
job=$job . $job
check_finished && break 2
done
udevadm settle --timeout=0 >/dev/null 2>&1 || continue
# no more udev jobs and queues empty.
sleep 0.5
for i in /run/systemd/ask-password/ask.*; do
[ -e "$i" ] && continue 2
done
if [ $main_loop -gt $((2*$RDRETRY/3)) ]; then
warn "dracut-initqueue timeout - starting timeout scripts"
for job in $hookdir/initqueue/timeout/*.sh; do
[ -e "$job" ] || break
job=$job . $job
udevadm settle --timeout=0 >/dev/null 2>&1 || main_loop=0
[ -f $hookdir/initqueue/work ] && main_loop=0
[ $main_loop -eq 0 ] && break
done
fi
main_loop=$(($main_loop+1))
if [ $main_loop -gt $RDRETRY ]; then
if ! [ -f /sysroot/etc/fstab ] || ! [ -e /sysroot/sbin/init ] ; then
emergency_shell "Could not boot."
fi
warn "Not all disks have been found."
warn "You might want to regenerate your initramfs."
break
fi
done
unset job
unset queuetriggered
unset main_loop
unset RDRETRY
export -p > /dracut-state.sh
exit 0
modules.d/98dracut-systemd/dracut-shutdown.service.8 0000644 00000007345 15023162470 0016463 0 ustar 00 '\" t
.\" Title: dracut-shutdown.service
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 04/06/2024
.\" Manual: dracut
.\" Source: dracut
.\" Language: English
.\"
.TH "DRACUT\-SHUTDOWN\&.S" "8" "04/06/2024" "dracut" "dracut"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
dracut-shutdown.service \- unpack the initramfs to /run/initramfs
.SH "SYNOPSIS"
.sp
dracut\-shutdown\&.service
.SH "DESCRIPTION"
.sp
This service unpacks the initramfs image to /run/initramfs\&. systemd pivots into /run/initramfs at shutdown, so the root filesystem can be safely unmounted\&.
.sp
The following steps are executed during a shutdown:
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
systemd switches to the shutdown\&.target
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
systemd starts /lib/systemd/system/shutdown\&.target\&.wants/dracut\-shutdown\&.service
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
dracut\-shutdown\&.service executes /usr/lib/dracut/dracut\-initramfs\-restore which unpacks the initramfs to /run/initramfs
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
systemd finishes shutdown\&.target
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
systemd kills all processes
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
systemd tries to unmount everything and mounts the remaining read\-only
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
systemd checks, if there is a /run/initramfs/shutdown executable
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
if yes, it does a pivot_root to /run/initramfs and executes \&./shutdown\&. The old root is then mounted on /oldroot\&. /usr/lib/dracut/modules\&.d/99shutdown/shutdown\&.sh is the shutdown executable\&.
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
shutdown will try to umount every /oldroot mount and calls the various shutdown hooks from the dracut modules
.RE
.sp
This ensures, that all devices are disassembled and unmounted cleanly\&.
.sp
To debug the shutdown process, you can get a shell in the shutdown procedure by injecting "rd\&.break=pre\-shutdown rd\&.shell" or "rd\&.break=shutdown rd\&.shell"\&.
.sp
.if n \{\
.RS 4
.\}
.nf
# mkdir \-p /run/initramfs/etc/cmdline\&.d
# echo "rd\&.break=pre\-shutdown rd\&.shell" > /run/initramfs/etc/cmdline\&.d/debug\&.conf
# touch /run/initramfs/\&.need_shutdown
.fi
.if n \{\
.RE
.\}
.sp
In case the unpack of the initramfs fails, dracut\-shutdown\-onfailure\&.service executes to make sure switch root doesn\(cqt happen, since it would result in switching to an incomplete initramfs\&.
.SH "AUTHORS"
.sp
Harald Hoyer
.SH "SEE ALSO"
.sp
\fBdracut\fR(8)
modules.d/98dracut-systemd/dracut-cmdline.service.8 0000644 00000003023 15023162470 0016210 0 ustar 00 '\" t
.\" Title: dracut-cmdline.service
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 10/09/2018
.\" Manual: dracut
.\" Source: dracut
.\" Language: English
.\"
.TH "DRACUT\-CMDLINE\&.SE" "8" "10/09/2018" "dracut" "dracut"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
dracut-cmdline.service \- runs the dracut hooks to parse the kernel command line
.SH "SYNOPSIS"
.sp
dracut\-cmdline\&.service
.SH "DESCRIPTION"
.sp
This service runs all the dracut hooks to parse the kernel command line in the initramfs\&.
.SH "AUTHORS"
.sp
Harald Hoyer
.SH "SEE ALSO"
.sp
\fBdracut\&.bootup\fR(7) \fBdracut\fR(8)
modules.d/98dracut-systemd/dracut-initqueue.service.8.asc 0000644 00000000667 15023162470 0017365 0 ustar 00 DRACUT-INITQUEUE.SERVICE(8)
===========================
:doctype: manpage
:man source: dracut
:man manual: dracut
NAME
----
dracut-initqueue.service - runs the dracut main loop to find the real root
SYNOPSIS
--------
dracut-initqueue.service
DESCRIPTION
-----------
This service runs all the main loop of dracut in the initramfs to find the real root.
AUTHORS
-------
Harald Hoyer
SEE ALSO
--------
*dracut.bootup*(7) *dracut*(8)
modules.d/98dracut-systemd/dracut-emergency.sh 0000755 00000002546 15023162470 0015373 0 ustar 00 #!/bin/sh
export DRACUT_SYSTEMD=1
if [ -f /dracut-state.sh ]; then
. /dracut-state.sh 2>/dev/null
fi
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
source_conf /etc/conf.d
type plymouth >/dev/null 2>&1 && plymouth quit
export _rdshell_name="dracut" action="Boot" hook="emergency"
_emergency_action=$(getarg rd.emergency)
if getargbool 1 rd.shell -d -y rdshell || getarg rd.break -d rdbreak; then
FSTXT="/run/dracut/fsck/fsck_help_$fstype.txt"
source_hook "$hook"
echo
rdsosreport
echo
echo
echo 'Entering emergency mode. Exit the shell to continue.'
echo 'Type "journalctl" to view system logs.'
echo 'You might want to save "/run/initramfs/rdsosreport.txt" to a USB stick or /boot'
echo 'after mounting them and attach it to a bug report.'
echo
echo
[ -f "$FSTXT" ] && cat "$FSTXT"
[ -f /etc/profile ] && . /etc/profile
[ -z "$PS1" ] && export PS1="$_name:\${PWD}# "
exec sh -i -l
else
export hook="shutdown-emergency"
warn "$action has failed. To debug this issue add \"rd.shell rd.debug\" to the kernel command line."
source_hook "$hook"
[ -z "$_emergency_action" ] && _emergency_action=halt
fi
/bin/rm -f -- /.console_lock
case "$_emergency_action" in
reboot)
reboot || exit 1;;
poweroff)
poweroff || exit 1;;
halt)
halt || exit 1;;
esac
exit 0
modules.d/98dracut-systemd/dracut-pre-udev.service.8 0000644 00000003001 15023162470 0016320 0 ustar 00 '\" t
.\" Title: dracut-pre-udev.service
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot
.\" Date: 10/09/2018
.\" Manual: dracut
.\" Source: dracut
.\" Language: English
.\"
.TH "DRACUT\-PRE\-UDEV\&." "8" "10/09/2018" "dracut" "dracut"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
dracut-pre-udev.service \- runs the dracut hooks before udevd is started
.SH "SYNOPSIS"
.sp
dracut\-pre\-udev\&.service
.SH "DESCRIPTION"
.sp
This service runs all dracut hooks before udevd is started in the initramfs\&.
.SH "AUTHORS"
.sp
Harald Hoyer
.SH "SEE ALSO"
.sp
\fBdracut\&.bootup\fR(7) \fBdracut\fR(8)
modules.d/98dracut-systemd/dracut-pre-mount.service.8.asc 0000644 00000000662 15023162470 0017276 0 ustar 00 DRACUT-PRE-MOUNT.SERVICE(8)
===========================
:doctype: manpage
:man source: dracut
:man manual: dracut
NAME
----
dracut-pre-mount.service - runs the dracut hooks before /sysroot is mounted
SYNOPSIS
--------
dracut-pre-mount.service
DESCRIPTION
-----------
This service runs all dracut hooks before the real root is mounted on /sysroot.
AUTHORS
-------
Harald Hoyer
SEE ALSO
--------
*dracut.bootup*(7) *dracut*(8)
modules.d/98dracut-systemd/dracut-pre-udev.service.8.asc 0000644 00000000650 15023162470 0017074 0 ustar 00 DRACUT-PRE-UDEV.SERVICE(8)
==========================
:doctype: manpage
:man source: dracut
:man manual: dracut
NAME
----
dracut-pre-udev.service - runs the dracut hooks before udevd is started
SYNOPSIS
--------
dracut-pre-udev.service
DESCRIPTION
-----------
This service runs all dracut hooks before udevd is started in the initramfs.
AUTHORS
-------
Harald Hoyer
SEE ALSO
--------
*dracut.bootup*(7) *dracut*(8)
modules.d/98dracut-systemd/dracut-shutdown-onfailure.service 0000644 00000000465 15023162470 0020273 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=Service executing upon dracut-shutdown failure to perform cleanup
Documentation=man:dracut-shutdown.service(8)
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=-/bin/rm /run/initramfs/shutdown
StandardError=null
modules.d/98dracut-systemd/dracut-pre-trigger.service 0000644 00000001622 15023162470 0016661 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=dracut pre-trigger hook
Documentation=man:dracut-pre-trigger.service(8)
DefaultDependencies=no
Before=systemd-udev-trigger.service dracut-initqueue.service
After=dracut-pre-udev.service systemd-udevd.service systemd-tmpfiles-setup-dev.service
Wants=dracut-pre-udev.service systemd-udevd.service
ConditionPathExists=/usr/lib/initrd-release
ConditionDirectoryNotEmpty=|/lib/dracut/hooks/pre-trigger
ConditionKernelCommandLine=|rd.break=pre-trigger
Conflicts=shutdown.target emergency.target
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=-/bin/dracut-pre-trigger
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
KillMode=process
RemainAfterExit=yes
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/dracut-pre-udev.sh 0000755 00000002605 15023162470 0015140 0 ustar 00 #!/bin/sh
export DRACUT_SYSTEMD=1
if [ -f /dracut-state.sh ]; then
. /dracut-state.sh 2>/dev/null
fi
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
source_conf /etc/conf.d
make_trace_mem "hook pre-udev" '1:shortmem' '2+:mem' '3+:slab'
# pre pivot scripts are sourced just before we doing cleanup and switch over
# to the new root.
getarg 'rd.break=pre-udev' 'rdbreak=pre-udev' && emergency_shell -n pre-udev "Break pre-udev"
source_hook pre-udev
_modprobe_d=/etc/modprobe.d
if [ -d /usr/lib/modprobe.d ] ; then
_modprobe_d=/usr/lib/modprobe.d
elif [ -d /lib/modprobe.d ] ; then
_modprobe_d=/lib/modprobe.d
elif [ ! -d $_modprobe_d ] ; then
mkdir -p $_modprobe_d
fi
for i in $(getargs rd.driver.pre -d rdloaddriver=); do
(
IFS=,
for p in $i; do
modprobe $p 2>&1 | vinfo
done
)
done
[ -d /etc/modprobe.d ] || mkdir -p /etc/modprobe.d
for i in $(getargs rd.driver.blacklist -d rdblacklist=); do
(
IFS=,
for p in $i; do
echo "blacklist $p" >> $_modprobe_d/initramfsblacklist.conf
done
)
done
for p in $(getargs rd.driver.post -d rdinsmodpost=); do
echo "blacklist $p" >> $_modprobe_d/initramfsblacklist.conf
_do_insmodpost=1
done
[ -n "$_do_insmodpost" ] && initqueue --settled --unique --onetime insmodpost.sh
unset _do_insmodpost _modprobe_d
unset i
export -p > /dracut-state.sh
exit 0
modules.d/98dracut-systemd/dracut-pre-trigger.service.8.asc 0000644 00000000670 15023162470 0017576 0 ustar 00 DRACUT-PRE-TRIGGER.SERVICE(8)
=============================
:doctype: manpage
:man source: dracut
:man manual: dracut
NAME
----
dracut-pre-trigger.service - runs the dracut hooks before udevd is triggered
SYNOPSIS
--------
dracut-pre-trigger.service
DESCRIPTION
-----------
This service runs all dracut hooks before udevd is triggered in the initramfs.
AUTHORS
-------
Harald Hoyer
SEE ALSO
--------
*dracut.bootup*(7) *dracut*(8)
modules.d/98dracut-systemd/dracut-initqueue.service 0000644 00000001465 15023162470 0016447 0 ustar 00 # This file is part of dracut.
#
# See dracut.bootup(7) for details
[Unit]
Description=dracut initqueue hook
Documentation=man:dracut-initqueue.service(8)
DefaultDependencies=no
Before=remote-fs-pre.target
Wants=remote-fs-pre.target
After=systemd-udev-trigger.service
Wants=systemd-udev-trigger.service
ConditionPathExists=/usr/lib/initrd-release
ConditionPathExists=|/lib/dracut/need-initqueue
ConditionKernelCommandLine=|rd.break=initqueue
Conflicts=shutdown.target emergency.target
[Service]
Environment=DRACUT_SYSTEMD=1
Environment=NEWROOT=/sysroot
Type=oneshot
ExecStart=-/bin/dracut-initqueue
StandardInput=null
StandardOutput=syslog
StandardError=syslog+console
KillMode=process
RemainAfterExit=yes
# Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash
# terminates cleanly.
KillSignal=SIGHUP
modules.d/98dracut-systemd/dracut-pre-pivot.service.8.asc 0000644 00000000655 15023162470 0017277 0 ustar 00 DRACUT-PRE-PIVOT.SERVICE(8)
===========================
:doctype: manpage
:man source: dracut
:man manual: dracut
NAME
----
dracut-pre-pivot.service - runs the dracut hooks before switching root
SYNOPSIS
--------
dracut-pre-pivot.service
DESCRIPTION
-----------
This service runs all dracut hooks before the system switched to the real root.
AUTHORS
-------
Harald Hoyer
SEE ALSO
--------
*dracut.bootup*(7) *dracut*(8)
modules.d/98dracut-systemd/dracut-tmpfiles.conf 0000644 00000000207 15023162470 0015540 0 ustar 00 d /run/initramfs 0755 root root -
d /run/initramfs/log 0755 root root -
L /var/log - - - - ../run/initramfs/log
modules.d/98dracut-systemd/dracut-pre-pivot.sh 0000755 00000001577 15023162470 0015345 0 ustar 00 #!/bin/sh
export DRACUT_SYSTEMD=1
if [ -f /dracut-state.sh ]; then
. /dracut-state.sh 2>/dev/null
fi
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
source_conf /etc/conf.d
make_trace_mem "hook pre-pivot" '1:shortmem' '2+:mem' '3+:slab'
# pre pivot scripts are sourced just before we doing cleanup and switch over
# to the new root.
getarg 'rd.break=pre-pivot' 'rdbreak=pre-pivot' && emergency_shell -n pre-pivot "Break pre-pivot"
source_hook pre-pivot
# pre pivot cleanup scripts are sourced just before we switch over to the new root.
getarg 'rd.break=cleanup' 'rdbreak=cleanup' && emergency_shell -n cleanup "Break cleanup"
source_hook cleanup
_bv=$(getarg rd.break -d rdbreak) && [ -z "$_bv" ] &&
emergency_shell -n switch_root "Break before switch_root"
unset _bv
# remove helper symlink
[ -h /dev/root ] && rm -f -- /dev/root
[ -h /dev/nfs ] && rm -f -- /dev/nfs
exit 0
modules.d/98dracut-systemd/module-setup.sh 0000755 00000004030 15023162470 0014546 0 ustar 00 #!/bin/bash
# called by dracut
check() {
[[ $mount_needs ]] && return 1
if ! dracut_module_included "systemd-initrd"; then
derror "dracut-systemd needs systemd-initrd in the initramfs"
return 1
fi
return 0
}
# called by dracut
depends() {
echo "systemd-initrd"
return 0
}
installkernel() {
return 0
}
# called by dracut
install() {
local _mods
inst_script "$moddir/dracut-emergency.sh" /bin/dracut-emergency
inst_simple "$moddir/emergency.service" ${systemdsystemunitdir}/emergency.service
inst_simple "$moddir/dracut-emergency.service" ${systemdsystemunitdir}/dracut-emergency.service
inst_simple "$moddir/emergency.service" ${systemdsystemunitdir}/rescue.service
ln_r "${systemdsystemunitdir}/initrd.target" "${systemdsystemunitdir}/default.target"
inst_script "$moddir/dracut-cmdline.sh" /bin/dracut-cmdline
inst_script "$moddir/dracut-cmdline-ask.sh" /bin/dracut-cmdline-ask
inst_script "$moddir/dracut-pre-udev.sh" /bin/dracut-pre-udev
inst_script "$moddir/dracut-pre-trigger.sh" /bin/dracut-pre-trigger
inst_script "$moddir/dracut-initqueue.sh" /bin/dracut-initqueue
inst_script "$moddir/dracut-pre-mount.sh" /bin/dracut-pre-mount
inst_script "$moddir/dracut-mount.sh" /bin/dracut-mount
inst_script "$moddir/dracut-pre-pivot.sh" /bin/dracut-pre-pivot
inst_script "$moddir/rootfs-generator.sh" $systemdutildir/system-generators/dracut-rootfs-generator
mkdir -p "${initdir}/$systemdsystemunitdir/initrd.target.wants"
for i in \
dracut-cmdline.service \
dracut-cmdline-ask.service \
dracut-initqueue.service \
dracut-mount.service \
dracut-pre-mount.service \
dracut-pre-pivot.service \
dracut-pre-trigger.service \
dracut-pre-udev.service \
; do
inst_simple "$moddir/${i}" "$systemdsystemunitdir/${i}"
systemctl -q --root "$initdir" add-wants initrd.target "$i"
done
inst_simple "$moddir/dracut-tmpfiles.conf" "$tmpfilesdir/dracut-tmpfiles.conf"
}
modules.d/30convertfs/convertfs.sh 0000755 00000013623 15023162470 0013167 0 ustar 00 #!/bin/bash
ROOT="$1"
if [[ ! -d "$ROOT" ]]; then
echo "Usage: $0 "
exit 1
fi
if [[ "$ROOT" -ef / ]]; then
echo "Can't convert the running system."
echo "Please boot with 'rd.convertfs' on the kernel command line,"
echo "to update with the help of the initramfs,"
echo "or run this script from a rescue system."
exit 1
fi
while [[ "$ROOT" != "${ROOT%/}" ]]; do
ROOT=${ROOT%/}
done
if [ ! -L $ROOT/var/run -a -e $ROOT/var/run ]; then
echo "Converting /var/run to symlink"
mv -f $ROOT/var/run $ROOT/var/run.runmove~
ln -sfn ../run $ROOT/var/run
fi
if [ ! -L $ROOT/var/lock -a -e $ROOT/var/lock ]; then
echo "Converting /var/lock to symlink"
mv -f $ROOT/var/lock $ROOT/var/lock.lockmove~
ln -sfn ../run/lock $ROOT/var/lock
fi
needconvert() {
for dir in "$ROOT/bin" "$ROOT/sbin" "$ROOT/lib" "$ROOT/lib64"; do
if [[ -e "$dir" ]]; then
[[ -L "$dir" ]] || return 0
fi
done
return 1
}
if ! [ -e "$ROOT/usr/bin" ]; then
echo "$ROOT/usr/bin does not exist!"
echo "Make sure, the kernel command line has enough information"
echo "to mount /usr (man dracut.cmdline)"
exit 1
fi
if ! needconvert; then
echo "Your system is already converted."
exit 0
fi
testfile="$ROOT/.usrmovecheck$$"
rm -f -- "$testfile"
> "$testfile"
if [[ ! -e "$testfile" ]]; then
echo "Cannot write to $ROOT/"
exit 1
fi
rm -f -- "$testfile"
testfile="$ROOT/usr/.usrmovecheck$$"
rm -f -- "$testfile"
> "$testfile"
if [[ ! -e "$testfile" ]]; then
echo "Cannot write to $ROOT/usr/"
exit 1
fi
rm -f -- "$testfile"
find_mount() {
local dev mnt etc wanted_dev
wanted_dev="$(readlink -e -q $1)"
while read dev mnt etc || [ -n "$dev" ]; do
[ "$dev" = "$wanted_dev" ] && echo "$dev" && return 0
done < /proc/mounts
return 1
}
# usage: ismounted
# usage: ismounted /dev/
if command -v findmnt >/dev/null; then
ismounted() {
findmnt "$1" > /dev/null 2>&1
}
else
ismounted() {
if [ -b "$1" ]; then
find_mount "$1" > /dev/null && return 0
return 1
fi
while read a m a || [ -n "$m" ]; do
[ "$m" = "$1" ] && return 0
done < /proc/mounts
return 1
}
fi
# clean up after ourselves no matter how we die.
cleanup() {
echo "Something failed. Move back to the original state"
for dir in "$ROOT/bin" "$ROOT/sbin" "$ROOT/lib" "$ROOT/lib64" \
"$ROOT/usr/bin" "$ROOT/usr/sbin" "$ROOT/usr/lib" \
"$ROOT/usr/lib64"; do
[[ -d "${dir}.usrmove-new" ]] && rm -fr -- "${dir}.usrmove-new"
if [[ -d "${dir}.usrmove-old" ]]; then
mv "$dir" "${dir}.del~"
mv "${dir}.usrmove-old" "$dir"
rm -fr -- "${dir}.del~"
fi
done
}
trap 'ret=$?; [[ $ret -ne 0 ]] && cleanup;exit $ret;' EXIT
trap 'exit 1;' SIGINT
ismounted "$ROOT/usr" || CP_HARDLINK="-l"
set -e
# merge / and /usr in new dir in /usr
for dir in bin sbin lib lib64; do
rm -rf -- "$ROOT/usr/${dir}.usrmove-new"
[[ -L "$ROOT/$dir" ]] && continue
[[ -d "$ROOT/$dir" ]] || continue
echo "Make a copy of \`$ROOT/usr/$dir'."
[[ -d "$ROOT/usr/$dir" ]] \
&& cp -ax -l "$ROOT/usr/$dir" "$ROOT/usr/${dir}.usrmove-new"
echo "Merge the copy with \`$ROOT/$dir'."
[[ -d "$ROOT/usr/${dir}.usrmove-new" ]] \
|| mkdir -p "$ROOT/usr/${dir}.usrmove-new"
cp -axT $CP_HARDLINK --backup --suffix=.usrmove~ "$ROOT/$dir" "$ROOT/usr/${dir}.usrmove-new"
echo "Clean up duplicates in \`$ROOT/usr/$dir'."
# delete all symlinks that have been backed up
find "$ROOT/usr/${dir}.usrmove-new" -type l -name '*.usrmove~' -delete || :
# replace symlink with backed up binary
find "$ROOT/usr/${dir}.usrmove-new" \
-name '*.usrmove~' \
-type f \
-exec bash -c 'p="{}";o=${p%%%%.usrmove~};
[[ -L "$o" ]] && mv -f "$p" "$o"' ';' || :
done
# switch over merged dirs in /usr
for dir in bin sbin lib lib64; do
[[ -d "$ROOT/usr/${dir}.usrmove-new" ]] || continue
echo "Switch to new \`$ROOT/usr/$dir'."
rm -fr -- "$ROOT/usr/${dir}.usrmove-old"
mv "$ROOT/usr/$dir" "$ROOT/usr/${dir}.usrmove-old"
mv "$ROOT/usr/${dir}.usrmove-new" "$ROOT/usr/$dir"
done
# replace dirs in / with links to /usr
for dir in bin sbin lib lib64; do
[[ -L "$ROOT/$dir" ]] && continue
[[ -d "$ROOT/$dir" ]] || continue
echo "Create \`$ROOT/$dir' symlink."
rm -fr -- "$ROOT/${dir}.usrmove-old" || :
mv "$ROOT/$dir" "$ROOT/${dir}.usrmove-old"
ln -sfn usr/$dir "$ROOT/$dir"
done
echo "Clean up backup files."
# everything seems to work; cleanup
for dir in bin sbin lib lib64; do
# if we get killed in the middle of "rm -rf", ensure not to leave
# an incomplete directory, which is moved back by cleanup()
[[ -d "$ROOT/usr/${dir}.usrmove-old" ]] \
&& mv "$ROOT/usr/${dir}.usrmove-old" "$ROOT/usr/${dir}.usrmove-old~"
[[ -d "$ROOT/${dir}.usrmove-old" ]] \
&& mv "$ROOT/${dir}.usrmove-old" "$ROOT/${dir}.usrmove-old~"
done
for dir in bin sbin lib lib64; do
[[ -d "$ROOT/usr/${dir}.usrmove-old~" ]] \
&& rm -rf -- "$ROOT/usr/${dir}.usrmove-old~" || :
[[ -d "$ROOT/${dir}.usrmove-old~" ]] \
&& rm -rf -- "$ROOT/${dir}.usrmove-old~" || :
done
for dir in lib lib64; do
[[ -d "$ROOT/$dir" ]] || continue
for lib in "$ROOT"/usr/${dir}/lib*.so*.usrmove~; do
[[ -f $lib ]] || continue
mv $lib ${lib/.so/_so}
done
done
set +e
echo "Run ldconfig."
ldconfig -r "$ROOT"
. $ROOT/etc/selinux/config
if [ -n "$(command -v setfiles)" ] && [ "$SELINUX" != "disabled" ] && [ -f /etc/selinux/${SELINUXTYPE}/contexts/files/file_contexts ]; then
echo "Fixing SELinux labels"
setfiles -r $ROOT -p /etc/selinux/${SELINUXTYPE}/contexts/files/file_contexts $ROOT/sbin $ROOT/bin $ROOT/lib $ROOT/lib64 $ROOT/usr/lib $ROOT/usr/lib64 $ROOT/etc/ld.so.cache $ROOT/var/cache/ldconfig || :
fi
echo "Done."
exit 0
modules.d/30convertfs/do-convertfs.sh 0000755 00000000302 15023162470 0013555 0 ustar 00 #!/bin/bash
if getargbool 0 rd.convertfs; then
if getargbool 0 rd.debug; then
bash -x convertfs "$NEWROOT" 2>&1 | vinfo
else
convertfs "$NEWROOT" 2>&1 | vinfo
fi
fi
modules.d/30convertfs/module-setup.sh 0000755 00000000520 15023162470 0013571 0 ustar 00 #!/bin/bash
# called by dracut
check() {
[[ $mount_needs ]] && return 1
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
install() {
inst_multiple bash find ldconfig mv rm cp ln
inst_hook pre-pivot 99 "$moddir/do-convertfs.sh"
inst_script "$moddir/convertfs.sh" /usr/bin/convertfs
}
modules.d/90dm/11-dm.rules 0000644 00000000216 15023162470 0011101 0 ustar 00 SUBSYSTEM!="block", GOTO="dm_end"
KERNEL!="dm-[0-9]*", GOTO="dm_end"
ACTION!="add|change", GOTO="dm_end"
OPTIONS+="db_persist"
LABEL="dm_end"
modules.d/90dm/dm-pre-udev.sh 0000755 00000000146 15023162470 0011674 0 ustar 00 #!/bin/sh
strstr "$(cat /proc/misc)" device-mapper || modprobe dm_mod
modprobe dm_mirror 2>/dev/null
modules.d/90dm/dm-shutdown.sh 0000755 00000002325 15023162470 0012021 0 ustar 00 #!/bin/sh
_remove_dm() {
local dev=$1
local s
local devname
for s in /sys/block/${dev}/holders/dm-* ; do
[ -e ${s} ] || continue
_remove_dm ${s##*/}
done
# multipath devices might have MD devices on top,
# which are removed after this script. So do not
# remove those to avoid spurious errors
case $(cat /sys/block/${dev}/dm/uuid) in
mpath-*)
return 0
;;
*)
devname=$(cat /sys/block/${dev}/dm/name)
dmsetup -v --noudevsync remove "$devname" || return $?
;;
esac
return 0
}
_do_dm_shutdown() {
local ret=0
local final=$1
local dev
info "Disassembling device-mapper devices"
for dev in /sys/block/dm-* ; do
[ -e ${dev} ] || continue
if [ "x$final" != "x" ]; then
_remove_dm ${dev##*/} || ret=$?
else
_remove_dm ${dev##*/} >/dev/null 2>&1 || ret=$?
fi
done
if [ "x$final" != "x" ]; then
info "dmsetup ls --tree"
dmsetup ls --tree 2>&1 | vinfo
fi
return $ret
}
if command -v dmsetup >/dev/null &&
[ "x$(dmsetup status)" != "xNo devices found" ]; then
_do_dm_shutdown $1
else
:
fi
modules.d/90dm/59-persistent-storage-dm.rules 0000644 00000001235 15023162470 0014757 0 ustar 00 SUBSYSTEM!="block", GOTO="dm_end"
ACTION!="add|change", GOTO="dm_end"
# Also don't process disks that are slated to be a multipath device
ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="dm_end"
KERNEL!="dm-[0-9]*", GOTO="dm_end"
ACTION=="add", GOTO="dm_end"
IMPORT{program}="/sbin/dmsetup info -c --nameprefixes --unquoted --rows --noheadings -o name,uuid,suspended,readonly,major,minor,open,tables_loaded,names_using_dev -j%M -m%m"
ENV{DM_NAME}!="?*", GOTO="dm_end"
ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="dm_end"
ENV{DM_UUID}=="CRYPT-TEMP-?*", GOTO="dm_end"
ENV{DM_UUID}!="?*", ENV{DM_NAME}=="temporary-cryptsetup-?*", GOTO="dm_end"
IMPORT BLKID
LABEL="dm_end"
modules.d/90dm/module-setup.sh 0000755 00000001755 15023162470 0012201 0 ustar 00 #!/bin/bash
# called by dracut
check() {
require_binaries dmsetup || return 1
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
installkernel() {
instmods =drivers/md dm_mod dm-cache dm-cache-mq dm-cache-cleaner
}
# called by dracut
install() {
modinfo -k $kernel dm_mod >/dev/null 2>&1 && \
inst_hook pre-udev 30 "$moddir/dm-pre-udev.sh"
inst_multiple dmsetup
inst_multiple -o dmeventd
inst_libdir_file "libdevmapper-event.so*"
inst_rules 10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
# Gentoo ebuild for LVM2 prior to 2.02.63-r1 doesn't install above rules
# files, but provides the one below:
inst_rules 64-device-mapper.rules
# debian udev rules
inst_rules 60-persistent-storage-dm.rules 55-dm.rules
inst_rules "$moddir/11-dm.rules"
inst_rules "$moddir/59-persistent-storage-dm.rules"
prepare_udev_rules 59-persistent-storage-dm.rules
inst_hook shutdown 25 "$moddir/dm-shutdown.sh"
}
modules.d/50plymouth/plymouth-newroot.sh 0000755 00000000161 15023162470 0014375 0 ustar 00 #!/bin/sh
if type plymouth >/dev/null 2>&1 && [ -z "$DRACUT_SYSTEMD" ]; then
plymouth --newroot=$NEWROOT
fi
modules.d/50plymouth/plymouth-pretrigger.sh 0000755 00000002231 15023162470 0015052 0 ustar 00 #!/bin/sh
if type plymouthd >/dev/null 2>&1 && [ -z "$DRACUT_SYSTEMD" ]; then
if getargbool 1 plymouth.enable && getargbool 1 rd.plymouth -d -n rd_NO_PLYMOUTH; then
# first trigger graphics subsystem
udevadm trigger --action=add --attr-match=class=0x030000 >/dev/null 2>&1
# first trigger graphics and tty subsystem
udevadm trigger --action=add \
--subsystem-match=graphics \
--subsystem-match=drm \
--subsystem-match=tty \
--subsystem-match=acpi \
>/dev/null 2>&1
udevadm settle --timeout=180 2>&1 | vinfo
info "Starting plymouth daemon"
mkdir -m 0755 /run/plymouth
read consoledev rest < /sys/class/tty/console/active
consoledev=${consoledev:-tty0}
[ -x /lib/udev/console_init -a -e "/dev/$consoledev" ] && /lib/udev/console_init "/dev/$consoledev"
plymouthd --attach-to-session --pid-file /run/plymouth/pid
plymouth --show-splash 2>&1 | vinfo
# reset tty after plymouth messed with it
[ -x /lib/udev/console_init -a -e "/dev/$consoledev" ] && /lib/udev/console_init "/dev/$consoledev"
fi
fi
modules.d/50plymouth/plymouth-populate-initrd.sh 0000755 00000002656 15023162470 0016033 0 ustar 00 #!/bin/bash
PLYMOUTH_LOGO_FILE="/usr/share/pixmaps/system-logo-white.png"
PLYMOUTH_THEME=$(plymouth-set-default-theme)
inst_multiple plymouthd plymouth \
/etc/system-release
test -e "${PLYMOUTH_LOGO_FILE}" && inst_simple "${PLYMOUTH_LOGO_FILE}"
mkdir -m 0755 -p "${initdir}/usr/share/plymouth"
inst_libdir_file "plymouth/text.so" "plymouth/details.so"
if [[ $hostonly ]]; then
inst_multiple \
"/usr/share/plymouth/themes/details/details.plymouth" \
"/usr/share/plymouth/themes/text/text.plymouth" \
if [[ -d /usr/share/plymouth/themes/${PLYMOUTH_THEME} ]]; then
for x in "/usr/share/plymouth/themes/${PLYMOUTH_THEME}"/* ; do
[[ -f "$x" ]] || break
inst $x
done
fi
if [ -L /usr/share/plymouth/themes/default.plymouth ]; then
inst /usr/share/plymouth/themes/default.plymouth
# Install plugin for this theme
PLYMOUTH_PLUGIN=$(grep "^ModuleName=" /usr/share/plymouth/themes/default.plymouth | while read a b c || [ -n "$b" ]; do echo $b; done;)
inst_libdir_file "plymouth/${PLYMOUTH_PLUGIN}.so"
fi
else
for x in /usr/share/plymouth/themes/{text,details}/* ; do
[[ -f "$x" ]] || continue
THEME_DIR=$(dirname "$x")
mkdir -m 0755 -p "${initdir}/$THEME_DIR"
inst_multiple "$x"
done
(
cd ${initdir}/usr/share/plymouth/themes;
ln -s text/text.plymouth default.plymouth 2>&1;
)
fi
modules.d/50plymouth/plymouth-emergency.sh 0000755 00000000063 15023162470 0014657 0 ustar 00 #!/bin/sh
plymouth --hide-splash 2>/dev/null || :
modules.d/50plymouth/module-setup.sh 0000755 00000002334 15023162470 0013450 0 ustar 00 #!/bin/bash
pkglib_dir() {
local _dirs="/usr/lib/plymouth /usr/libexec/plymouth/"
if find_binary dpkg-architecture &>/dev/null; then
_dirs+=" /usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH)/plymouth"
fi
for _dir in $_dirs; do
if [ -x $_dir/plymouth-populate-initrd ]; then
echo $_dir
return
fi
done
}
# called by dracut
check() {
[[ "$mount_needs" ]] && return 1
[ -z $(pkglib_dir) ] && return 1
require_binaries plymouthd plymouth plymouth-set-default-theme
}
# called by dracut
depends() {
echo drm
}
# called by dracut
install() {
PKGLIBDIR=$(pkglib_dir)
if grep -q nash ${PKGLIBDIR}/plymouth-populate-initrd \
|| [ ! -x ${PKGLIBDIR}/plymouth-populate-initrd ]; then
. "$moddir"/plymouth-populate-initrd.sh
else
PLYMOUTH_POPULATE_SOURCE_FUNCTIONS="$dracutfunctions" \
${PKGLIBDIR}/plymouth-populate-initrd -t "$initdir"
fi
inst_hook emergency 50 "$moddir"/plymouth-emergency.sh
inst_multiple readlink
if ! dracut_module_included "systemd"; then
inst_hook pre-trigger 10 "$moddir"/plymouth-pretrigger.sh
inst_hook pre-pivot 90 "$moddir"/plymouth-newroot.sh
fi
}
modules.d/98selinux/selinux-loadpolicy.sh 0000755 00000004302 15023162470 0014470 0 ustar 00 #!/bin/sh
# FIXME: load selinux policy. this should really be done after we switchroot
rd_load_policy()
{
# If SELinux is disabled exit now
getarg "selinux=0" > /dev/null && return 0
SELINUX="enforcing"
[ -e "$NEWROOT/etc/selinux/config" ] && . "$NEWROOT/etc/selinux/config"
# Check whether SELinux is in permissive mode
permissive=0
getarg "enforcing=0" > /dev/null
if [ $? -eq 0 -o "$SELINUX" = "permissive" ]; then
permissive=1
fi
# Attempt to load SELinux Policy
if [ -x "$NEWROOT/usr/sbin/load_policy" -o -x "$NEWROOT/sbin/load_policy" ]; then
local ret=0
local out
info "Loading SELinux policy"
mount -o bind /sys $NEWROOT/sys
# load_policy does mount /proc and /sys/fs/selinux in
# libselinux,selinux_init_load_policy()
if [ -x "$NEWROOT/sbin/load_policy" ]; then
out=$(LANG=C chroot "$NEWROOT" /sbin/load_policy -i 2>&1)
ret=$?
info $out
else
out=$(LANG=C chroot "$NEWROOT" /usr/sbin/load_policy -i 2>&1)
ret=$?
info $out
fi
umount $NEWROOT/sys/fs/selinux
umount $NEWROOT/sys
if [ "$SELINUX" = "disabled" ]; then
return 0;
fi
if [ $ret -eq 0 -o $ret -eq 2 ]; then
# If machine requires a relabel, force to permissive mode
[ -e "$NEWROOT"/.autorelabel ] && LANG=C /usr/sbin/setenforce 0
mount --rbind /dev "$NEWROOT/dev"
LANG=C chroot "$NEWROOT" /sbin/restorecon -R /dev
umount -R "$NEWROOT/dev"
return 0
fi
warn "Initial SELinux policy load failed."
if [ $ret -eq 3 -o $permissive -eq 0 ]; then
warn "Machine in enforcing mode."
warn "Not continuing"
emergency_shell -n selinux
exit 1
fi
return 0
elif [ $permissive -eq 0 -a "$SELINUX" != "disabled" ]; then
warn "Machine in enforcing mode and cannot execute load_policy."
warn "To disable selinux, add selinux=0 to the kernel command line."
warn "Not continuing"
emergency_shell -n selinux
exit 1
fi
}
rd_load_policy
modules.d/98selinux/module-setup.sh 0000755 00000000345 15023162470 0013272 0 ustar 00 #!/bin/bash
# called by dracut
check() {
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
install() {
inst_hook pre-pivot 50 "$moddir/selinux-loadpolicy.sh"
inst_multiple setenforce
}
modules.d/01systemd-initrd/module-setup.sh 0000755 00000003451 15023162470 0014543 0 ustar 00 #!/bin/bash
# called by dracut
check() {
[[ $mount_needs ]] && return 1
if ! dracut_module_included "systemd"; then
derror "systemd-initrd needs systemd in the initramfs"
return 1
fi
return 0
}
# called by dracut
depends() {
echo "systemd"
}
installkernel() {
return 0
}
# called by dracut
install() {
local _mods
inst_multiple -o \
$systemdsystemunitdir/initrd.target \
$systemdsystemunitdir/initrd-fs.target \
$systemdsystemunitdir/initrd-root-device.target \
$systemdsystemunitdir/initrd-root-fs.target \
$systemdsystemunitdir/initrd-switch-root.target \
$systemdsystemunitdir/initrd-switch-root.service \
$systemdsystemunitdir/initrd-cleanup.service \
$systemdsystemunitdir/initrd-udevadm-cleanup-db.service \
$systemdsystemunitdir/initrd-parse-etc.service
systemctl -q --root "$initdir" set-default initrd.target
local VERSION=""
local PRETTY_NAME=""
if [ -e /etc/os-release ]; then
. /etc/os-release
[[ -n ${VERSION} ]] && VERSION+=" "
[[ -n ${PRETTY_NAME} ]] && PRETTY_NAME+=" "
fi
NAME=dracut
ID=dracut
VERSION+="dracut-$DRACUT_VERSION"
PRETTY_NAME+="dracut-$DRACUT_VERSION (Initramfs)"
VERSION_ID=$DRACUT_VERSION
ANSI_COLOR="0;34"
{
echo NAME=\"$NAME\"
echo VERSION=\"$VERSION\"
echo ID=$ID
echo VERSION_ID=$VERSION_ID
echo PRETTY_NAME=\"$PRETTY_NAME\"
echo ANSI_COLOR=\"$ANSI_COLOR\"
} > $initdir/usr/lib/initrd-release
echo dracut-$DRACUT_VERSION > $initdir/lib/dracut/dracut-$DRACUT_VERSION
ln -sf ../usr/lib/initrd-release $initdir/etc/initrd-release
ln -sf initrd-release $initdir/usr/lib/os-release
ln -sf initrd-release $initdir/etc/os-release
}
modules.d/80lvmmerge/lvmmerge.sh 0000755 00000006017 15023162470 0012605 0 ustar 00 #!/bin/bash
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
do_merge() {
sed -i -e 's/\(^[[:space:]]*\)locking_type[[:space:]]*=[[:space:]]*[[:digit:]]/\1locking_type = 1/' \
/etc/lvm/lvm.conf
systemctl --no-block stop sysroot.mount
swapoff -a
umount -R /sysroot
for tag in $(getargs rd.lvm.mergetags); do
lvm vgs --noheadings -o vg_name | \
while read -r vg || [[ -n $vg ]]; do
unset LVS
declare -a LVS
lvs=$(lvm lvs --noheadings -o lv_name "$vg")
for lv in $lvs; do
lvm lvchange -an "$vg/$lv"
tags=$(trim "$(lvm lvs --noheadings -o lv_tags "$vg/$lv")")
strstr ",${tags}," ",${tag}," || continue
if ! lvm lvs --noheadings -o lv_name "${vg}/${lv}_dracutsnap" &>/dev/null; then
info "Creating backup ${lv}_dracutsnap of ${vg}/${lv}"
lvm lvcreate -pr -s "${vg}/${lv}" --name "${lv}_dracutsnap"
fi
lvm lvchange --addtag "$tag" "${vg}/${lv}_dracutsnap"
info "Merging back ${vg}/${lv} to the original LV"
lvm lvconvert --merge "${vg}/${lv}"
LVS+=($lv)
done
systemctl --no-block stop sysroot.mount
udevadm settle
for ((i=0; i < 100; i++)); do
lvm vgchange -an "$vg" && break
sleep 0.5
done
udevadm settle
lvm vgchange -ay "$vg"
udevadm settle
for lv in "${LVS[@]}"; do
info "Renaming ${lv}_dracutsnap backup to ${vg}/${lv}"
lvm lvrename "$vg" "${lv}_dracutsnap" "${lv}"
done
udevadm settle
done
done
systemctl --no-block reset-failed systemd-fsck-root
systemctl --no-block start systemd-fsck-root
systemctl --no-block reset-failed sysroot.mount
systemctl --no-block start sysroot.mount
for ((i=0; i < 100; i++)); do
[[ -d /sysroot/dev ]] && break
sleep 0.5
systemctl --no-block start sysroot.mount
done
if [[ -d /sysroot/restoredev ]]; then
(
if cd /sysroot/restoredev; then
# restore devices and partitions
for i in *; do
target=$(systemd-escape -pu "$i")
if ! [[ -b $target ]]; then
warn "Not restoring $target, as the device does not exist"
continue
fi
# Just in case
umount "$target" &> /dev/null
info "Restoring $target"
dd if="$i" of="$target" |& vinfo
done
fi
)
mount -o remount,rw /sysroot
rm -fr /sysroot/restoredev
fi
info "Rebooting"
reboot
}
if getarg rd.lvm.mergetags; then
do_merge
fi
modules.d/80lvmmerge/README.md 0000644 00000004055 15023162470 0011707 0 ustar 00 # lvmmerge - dracut module
## Preparation
- ensure that the lvm thin pool is big enough
- backup any (most likely /boot and /boot/efi) device with:
```
# mkdir /restoredev
# dev=; umount $dev; dd if="$dev" of=/restoredev/$(systemd-escape -p "$dev"); mount $dev
```
- backup the MBR
```
# dev=; dd if="$dev" of=/restoredev/$(systemd-escape -p "$dev") bs=446 count=1
# ls -l /dev/disk/by-path/virtio-pci-0000\:00\:07.0
lrwxrwxrwx. 1 root root 9 Jul 24 04:27 /dev/disk/by-path/virtio-pci-0000:00:07.0 -> ../../vda
```
- backup some partitions
```
# dev=/dev/disk/by-path/virtio-pci-0000:00:07.0
# dd if="$dev" of=/restoredev/$(systemd-escape -p "$dev") bs=446 count=1
# umount /boot/efi
# dev=/dev/disk/by-partuuid/687177a8-86b3-4e37-a328-91d20db9563c
# dd if="$dev" of=/restoredev/$(systemd-escape -p "$dev")
# umount /boot
# dev=/dev/disk/by-partuuid/4fdf99e9-4f28-4207-a26f-c76546824eaf
# dd if="$dev" of=/restoredev/$(systemd-escape -p "$dev")
```
Final /restoredev
```
# ls -al /restoredev/
total 1253380
drwx------. 2 root root 250 Jul 24 04:38 .
dr-xr-xr-x. 18 root root 242 Jul 24 04:32 ..
-rw-------. 1 root root 209715200 Jul 24 04:34 dev-disk-by\x2dpartuuid-4fdf99e9\x2d4f28\x2d4207\x2da26f\x2dc76546824eaf
-rw-------. 1 root root 1073741824 Jul 24 04:34 dev-disk-by\x2dpartuuid-687177a8\x2d86b3\x2d4e37\x2da328\x2d91d20db9563c
-rw-------. 1 root root 446 Jul 24 04:38 dev-disk-by\x2dpath-virtio\x2dpci\x2d0000:00:07.0
```
- make a thin snapshot
```
# lvm lvcreate -pr -s rhel/root --name reset
```
- mark the snapshot with a tag
```
# lvm lvchange --addtag reset rhel/reset
```
- remove /restoredev
```
# rm -fr /restoredev
```
## Operation
If a boot entry with ```rd.lvm.mergetags=``` is selected and there are LVs with ``````
dracut will
- make a copy of the snapshot
- merge it back to the original
- rename the copy back to the name of the snapshot
- if /restordev appears in the root, then it will restore the images
found in that directory. This can be used to restore /boot and /boot/efi and the
MBR of the boot device
modules.d/80lvmmerge/module-setup.sh 0000755 00000000650 15023162470 0013407 0 ustar 00 #!/bin/bash
# called by dracut
check() {
# No point trying to support lvm if the binaries are missing
require_binaries lvm dd swapoff || return 1
return 255
}
# called by dracut
depends() {
echo lvm dracut-systemd systemd
return 0
}
installkernel() {
hostonly="" instmods dm-snapshot
}
# called by dracut
install() {
inst_multiple dd swapoff
inst_hook cleanup 01 "$moddir/lvmmerge.sh"
}
modules.d/90kernel-modules/parse-kernel.sh 0000755 00000001631 15023162470 0014465 0 ustar 00 #!/bin/sh
_modprobe_d=/etc/modprobe.d
if [ -d /usr/lib/modprobe.d ] ; then
_modprobe_d=/usr/lib/modprobe.d
elif [ -d /lib/modprobe.d ] ; then
_modprobe_d=/lib/modprobe.d
elif [ ! -d $_modprobe_d ] ; then
mkdir -p $_modprobe_d
fi
for i in $(getargs rd.driver.pre -d rdloaddriver=); do
(
IFS=,
for p in $i; do
modprobe $p 2>&1 | vinfo
done
)
done
[ -d /etc/modprobe.d ] || mkdir -p /etc/modprobe.d
for i in $(getargs rd.driver.blacklist -d rdblacklist=); do
(
IFS=,
for p in $i; do
echo "blacklist $p" >> $_modprobe_d/initramfsblacklist.conf
done
)
done
for p in $(getargs rd.driver.post -d rdinsmodpost=); do
echo "blacklist $p" >> $_modprobe_d/initramfsblacklist.conf
_do_insmodpost=1
done
[ -n "$_do_insmodpost" ] && initqueue --settled --unique --onetime insmodpost.sh
unset _do_insmodpost _modprobe_d
modules.d/90kernel-modules/insmodpost.sh 0000755 00000000301 15023162470 0014265 0 ustar 00 #!/bin/sh
. /lib/dracut-lib.sh
for modlist in $(getargs rd.driver.post -d rdinsmodpost=); do
(
IFS=,
for m in $modlist; do
modprobe $m
done
)
done
modules.d/90kernel-modules/module-setup.sh 0000755 00000007351 15023162470 0014525 0 ustar 00 #!/bin/bash
# called by dracut
installkernel() {
local _blockfuncs='ahci_platform_get_resources|ata_scsi_ioctl|scsi_add_host|blk_cleanup_queue|register_mtd_blktrans|scsi_esp_register|register_virtio_device|usb_stor_disconnect|mmc_add_host|sdhci_add_host|scsi_add_host_with_dma'
find_kernel_modules_external () {
local _OLDIFS
local external_pattern="^/"
[[ -f "$srcmods/modules.dep" ]] || return 0
_OLDIFS=$IFS
IFS=:
while read a rest; do
[[ $a =~ $external_pattern ]] || continue
printf "%s\n" "$a"
done < "$srcmods/modules.dep"
IFS=$_OLDIFS
}
is_block_dev() {
[ -e /sys/dev/block/$1 ] && return 0
return 1
}
install_block_modules () {
hostonly='' instmods sr_mod sd_mod scsi_dh ata_piix
instmods \
scsi_dh_rdac scsi_dh_emc scsi_dh_alua \
=ide nvme vmd nfit \
virtio_blk
dracut_instmods -o -s "${_blockfuncs}" "=drivers"
}
if [[ -z $drivers ]]; then
hostonly='' instmods \
hid_generic unix \
ehci-hcd ehci-pci ehci-platform \
ohci-hcd ohci-pci \
uhci-hcd \
xhci-hcd xhci-pci xhci-plat-hcd \
"=drivers/pinctrl" \
${NULL}
hostonly=$(optional_hostonly) instmods \
"=drivers/hid" \
"=drivers/tty/serial" \
"=drivers/input/serio" \
"=drivers/input/keyboard" \
"=drivers/usb/storage" \
"=drivers/pci/host" \
${NULL}
instmods \
yenta_socket \
atkbd i8042 usbhid firewire-ohci pcmcia hv-vmbus \
virtio virtio_ring virtio_pci virtio_scsi pci_hyperv \
"=drivers/pcmcia"
if [[ "$(uname -m)" == arm* || "$(uname -m)" == aarch64 ]]; then
# arm/aarch64 specific modules
_blockfuncs+='|dw_mc_probe|dw_mci_pltfm_register'
instmods \
"=drivers/clk" \
"=drivers/dma" \
"=drivers/extcon" \
"=drivers/gpio" \
"=drivers/hwspinlock" \
"=drivers/i2c/busses" \
"=drivers/mfd" \
"=drivers/mmc/core" \
"=drivers/phy" \
"=drivers/power" \
"=drivers/regulator" \
"=drivers/rpmsg" \
"=drivers/rtc" \
"=drivers/soc" \
"=drivers/usb/chipidea" \
"=drivers/usb/dwc2" \
"=drivers/usb/dwc3" \
"=drivers/usb/host" \
"=drivers/usb/misc" \
"=drivers/usb/musb" \
"=drivers/usb/phy" \
"=drivers/scsi/hisi_sas" \
${NULL}
fi
find_kernel_modules_external | instmods
if ! [[ $hostonly ]] || for_each_host_dev_and_slaves is_block_dev; then
install_block_modules
fi
# if not on hostonly mode, install all known filesystems,
# if the required list is not set via the filesystems variable
if ! [[ $hostonly ]]; then
if [[ -z $filesystems ]]; then
dracut_instmods -o -P ".*/(kernel/fs/nfs|kernel/fs/nfsd|kernel/fs/lockd)/.*" '=fs'
fi
elif [[ "${host_fs_types[*]}" ]]; then
hostonly='' instmods "${host_fs_types[@]}"
fi
fi
:
}
# called by dracut
install() {
inst_multiple -o /lib/modprobe.d/*.conf
[[ $hostonly ]] && inst_multiple -H -o /etc/modprobe.d/*.conf /etc/modprobe.conf
if ! dracut_module_included "systemd"; then
inst_hook cmdline 01 "$moddir/parse-kernel.sh"
fi
inst_simple "$moddir/insmodpost.sh" /sbin/insmodpost.sh
}
modules.d/98ecryptfs/ecryptfs-mount.sh 0000755 00000005266 15023162470 0014025 0 ustar 00 #!/bin/sh
# Licensed under the GPLv2
#
# Copyright (C) 2011 Politecnico di Torino, Italy
# TORSEC group -- http://security.polito.it
# Roberto Sassu
ECRYPTFSCONFIG="${NEWROOT}/etc/sysconfig/ecryptfs"
ECRYPTFSKEYTYPE="encrypted"
ECRYPTFSKEYDESC="1000100010001000"
ECRYPTFSKEYID=""
ECRYPTFSSRCDIR="/secret"
ECRYPTFS_EXTRA_MOUNT_OPTS=""
load_ecryptfs_key()
{
# override the eCryptfs key path name from the 'ecryptfskey=' parameter in the kernel
# command line
ECRYPTFSKEYARG=$(getarg ecryptfskey=)
[ $? -eq 0 ] && \
ECRYPTFSKEY=${ECRYPTFSKEYARG}
# set the default value
[ -z "${ECRYPTFSKEY}" ] && \
ECRYPTFSKEY="/etc/keys/ecryptfs-trusted.blob";
# set the eCryptfs key path name
ECRYPTFSKEYPATH="${NEWROOT}${ECRYPTFSKEY}"
# check for eCryptfs encrypted key's existence
if [ ! -f "${ECRYPTFSKEYPATH}" ]; then
if [ "${RD_DEBUG}" = "yes" ]; then
info "eCryptfs: key file not found: ${ECRYPTFSKEYPATH}"
fi
return 1
fi
# read the eCryptfs encrypted key blob
KEYBLOB=$(cat ${ECRYPTFSKEYPATH})
# load the eCryptfs encrypted key blob
ECRYPTFSKEYID=$(keyctl add ${ECRYPTFSKEYTYPE} ${ECRYPTFSKEYDESC} "load ${KEYBLOB}" @u)
[ $? -eq 0 ] || {
info "eCryptfs: failed to load the eCryptfs key: ${ECRYPTFSKEYDESC}";
return 1;
}
return 0
}
unload_ecryptfs_key()
{
# unlink the eCryptfs encrypted key
keyctl unlink ${ECRYPTFSKEYID} @u || {
info "eCryptfs: failed to unlink the eCryptfs key: ${ECRYPTFSKEYDESC}";
return 1;
}
return 0
}
mount_ecryptfs()
{
# read the configuration from the config file
[ -f "${ECRYPTFSCONFIG}" ] && \
. ${ECRYPTFSCONFIG}
# load the eCryptfs encrypted key
load_ecryptfs_key || return 1
# set the default value for ECRYPTFSDSTDIR
[ -z "${ECRYPTFSDSTDIR}" ] && \
ECRYPTFSDSTDIR=${ECRYPTFSSRCDIR}
# set the eCryptfs filesystem mount point
ECRYPTFSSRCMNT="${NEWROOT}${ECRYPTFSSRCDIR}"
ECRYPTFSDSTMNT="${NEWROOT}${ECRYPTFSDSTDIR}"
# build the mount options variable
ECRYPTFS_MOUNT_OPTS="ecryptfs_sig=${ECRYPTFSKEYDESC}"
[ ! -z "${ECRYPTFS_EXTRA_MOUNT_OPTS}" ] && \
ECRYPTFS_MOUNT_OPTS="${ECRYPTFS_MOUNT_OPTS},${ECRYPTFS_EXTRA_MOUNT_OPTS}"
# mount the eCryptfs filesystem
info "Mounting the configured eCryptfs filesystem"
mount -i -t ecryptfs -o${ECRYPTFS_MOUNT_OPTS} ${ECRYPTFSSRCMNT} ${ECRYPTFSDSTMNT} >/dev/null || {
info "eCryptfs: mount of the eCryptfs filesystem failed";
return 1;
}
# unload the eCryptfs encrypted key
unload_ecryptfs_key || return 1
return 0
}
mount_ecryptfs
modules.d/98ecryptfs/README 0000644 00000004447 15023162470 0011347 0 ustar 00 # Directions for creating the encrypted key that will be used to mount an
# eCryptfs filesystem
# Create the eCryptfs key (encrypted key type)
#
# The encrypted key type supports two formats: the 'default' format allows
# to generate a random symmetric key of the length specified, the 'ecryptfs'
# format generates an authentication token for the eCryptfs filesystem,
# which contains a randomly generated key. Two requirements for the latter
# format is that the key description must contain exactly 16 hexadecimal
# characters and that the encrypted key length must be equal to 64.
$ keyctl add encrypted 1000100010001000 "new ecryptfs trusted:kmk-trusted 64" @u
782117972
# Save the encrypted key
$ su -c 'keyctl pipe `keyctl search @u encrypted 1000100010001000` > /etc/keys/ecryptfs-trusted.blob'
# The eCryptfs key path name can be set in one of the following ways (specified in
# the order in which the variable is overwritten):
1) use the default value:
--------------------------------------------------------------------------
ECRYPTFSKEY="/etc/keys/ecryptfs-trusted.blob"
--------------------------------------------------------------------------
2) create the configuration file '/etc/sysconfig/ecryptfs' and set the ECRYPTFSKEY
variable;
3) specify the eCryptfs key path name in the 'ecryptfskey=' parameter of the kernel command
line.
# The configuration file '/etc/sysconfig/ecryptfs' is also used to specify
# more options for mounting the eCryptfs filesystem:
ECRYPTFSSRCDIR: existent directory in the lower root filesystem;
ECRYPTFSDSTDIR: mount point directory for the eCryptfs filesystem (the directory must be
created in the root filesystem before rebooting the platform);
ECRYPTFS_EXTRA_MOUNT_OPTS: extra mount options for the eCryptfs filesystem (the 'ecryptfs_sig'
option is automatically added by the dracut script).
# Example of the configuration file:
----------- '/etc/sysconfig/ecryptfs' (with default values) -----------
ECRYPTFS_KEY="/etc/keys/ecryptfs-trusted.blob"
ECRYPTFSSRCDIR="/secret"
ECRYPTFSDSTDIR="${ECRYPTFSSRCDIR}"
ECRYPTFS_EXTRA_MOUNT_OPTS=""
-----------------------------------------------------------------------
# If the variable ECRYPTFSDSTDIR is not specified in the configuration file,
# its value will be equal to that of ECRYPTFSSRCDIR.
modules.d/98ecryptfs/module-setup.sh 0000755 00000000424 15023162470 0013440 0 ustar 00 #!/bin/bash
# called by dracut
check() {
return 255
}
# called by dracut
depends() {
echo masterkey
return 0
}
# called by dracut
installkernel() {
instmods ecryptfs
}
# called by dracut
install() {
inst_hook pre-pivot 63 "$moddir/ecryptfs-mount.sh"
}
modules.d/95virtfs/parse-virtfs.sh 0000755 00000000135 15023162470 0013114 0 ustar 00 #!/bin/sh
if [ "${root%%:*}" = "virtfs" ] ; then
modprobe 9pnet_virtio
rootok=1
fi
modules.d/95virtfs/mount-virtfs.sh 0000755 00000003507 15023162470 0013152 0 ustar 00 #!/bin/sh
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
filter_rootopts() {
rootopts=$1
# strip ro and rw options
local OLDIFS="$IFS"
IFS=,
set -- $rootopts
IFS="$OLDIFS"
local v
while [ $# -gt 0 ]; do
case $1 in
rw|ro);;
defaults);;
*)
v="$v,${1}";;
esac
shift
done
rootopts=${v#,}
echo $rootopts
}
mount_root() {
local _ret
rootfs="9p"
rflags="trans=virtio,version=9p2000.L"
modprobe 9pnet_virtio
mount -t ${rootfs} -o "$rflags",ro "${root#virtfs:}" "$NEWROOT"
rootopts=
if getargbool 1 rd.fstab -n rd_NO_FSTAB \
&& ! getarg rootflags \
&& [ -f "$NEWROOT/etc/fstab" ] \
&& ! [ -L "$NEWROOT/etc/fstab" ]; then
# if $NEWROOT/etc/fstab contains special mount options for
# the root filesystem,
# remount it with the proper options
rootopts="defaults"
while read dev mp fs opts rest || [ -n "$dev" ]; do
# skip comments
[ "${dev%%#*}" != "$dev" ] && continue
if [ "$mp" = "/" ]; then
rootopts=$opts
break
fi
done < "$NEWROOT/etc/fstab"
rootopts=$(filter_rootopts $rootopts)
fi
# we want rootflags (rflags) to take precedence so prepend rootopts to
# them; rflags is guaranteed to not be empty
rflags="${rootopts:+"${rootopts},"}${rflags}"
umount "$NEWROOT"
info "Remounting ${root#virtfs:} with -o ${rflags}"
mount -t ${rootfs} -o "$rflags" "${root#virtfs:}" "$NEWROOT" 2>&1 | vinfo
[ -f "$NEWROOT"/forcefsck ] && rm -f -- "$NEWROOT"/forcefsck 2>/dev/null
[ -f "$NEWROOT"/.autofsck ] && rm -f -- "$NEWROOT"/.autofsck 2>/dev/null
}
if [ -n "$root" -a -z "${root%%virtfs:*}" ]; then
mount_root
fi
:
modules.d/95virtfs/module-setup.sh 0000755 00000001712 15023162470 0013114 0 ustar 00 #!/bin/bash
# called by dracut
check() {
[[ $hostonly ]] || [[ $mount_needs ]] && {
for fs in "${host_fs_types[@]}"; do
[[ "$fs" == "9p" ]] && return 0
done
return 255
}
if type -P systemd-detect-virt >/dev/null 2>&1; then
vm=$(systemd-detect-virt --vm >/dev/null 2>&1)
(($? != 0)) && return 255
[[ $vm = "qemu" ]] && return 0
[[ $vm = "kvm" ]] && return 0
[[ $vm = "bochs" ]] && return 0
fi
for i in /sys/class/dmi/id/*_vendor; do
[[ -f $i ]] || continue
read vendor < $i
[[ "$vendor" == "QEMU" ]] && return 0
[[ "$vendor" == "Bochs" ]] && return 0
done
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
installkernel() {
instmods 9p 9pnet_virtio virtio_pci
}
# called by dracut
install() {
inst_hook cmdline 95 "$moddir/parse-virtfs.sh"
inst_hook mount 99 "$moddir/mount-virtfs.sh"
}
modules.d/00warpclock/warpclock.sh 0000644 00000000227 15023162470 0013105 0 ustar 00 #!/bin/sh
if test -e /etc/adjtime ; then
while read line ; do
if test "$line" = LOCAL ; then
hwclock --systz
fi
done < /etc/adjtime
fi
modules.d/00warpclock/module-setup.sh 0000644 00000001226 15023162470 0013543 0 ustar 00 #!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
# called by dracut
check() {
# hwclock does not exist on S390(x), bail out silently then
local _arch=$(uname -m)
[ "$_arch" = "s390" -o "$_arch" = "s390x" ] && return 1
[ -e /etc/localtime -a -e /etc/adjtime ] || return 1
require_binaries /sbin/hwclock || return 1
return 255
}
# called by dracut
depends() {
return 0
}
# called by dracut
install() {
inst /usr/share/zoneinfo/UTC
inst /etc/localtime
inst /etc/adjtime
inst_hook pre-trigger 00 "$moddir/warpclock.sh"
inst /sbin/hwclock
}
modules.d/99base/parse-root-opts.sh 0000755 00000000366 15023162470 0013154 0 ustar 00 #!/bin/sh
root=$(getarg root=)
rflags="$(getarg rootflags=)"
getargbool 0 ro && rflags="${rflags},ro"
getargbool 0 rw && rflags="${rflags},rw"
rflags="${rflags#,}"
fstype="$(getarg rootfstype=)"
if [ -z "$fstype" ]; then
fstype="auto"
fi
modules.d/99base/rdsosreport.sh 0000755 00000002502 15023162470 0012456 0 ustar 00 #!/bin/sh
echo 'Generating "/run/initramfs/rdsosreport.txt"'
[ -d /run/initramfs ] || mkdir -p /run/initramfs
exec >/run/initramfs/rdsosreport.txt 2>&1
PWFILTER='s/\(ftp:\/\/.*\):.*@/\1:*******@/g;s/\(cifs:\/\/.*\):.*@/\1:*******@/g;s/cifspass=[^ ]*/cifspass=*******/g;s/iscsi:.*@/iscsi:******@/g;s/rd.iscsi.password=[^ ]*/rd.iscsi.password=******/g;s/rd.iscsi.in.password=[^ ]*/rd.iscsi.in.password=******/g'
set -x
cat /lib/dracut/dracut-*
cat /proc/cmdline | sed -e "$PWFILTER"
[ -f /etc/cmdline ] && cat /etc/cmdline | sed -e "$PWFILTER"
for _i in /etc/cmdline.d/*.conf; do
[ -f "$_i" ] || break
echo $_i
cat $_i | sed -e "$PWFILTER"
done
cat /proc/self/mountinfo
cat /proc/mounts
blkid
blkid -o udev
ls -l /dev/disk/by*
for _i in /etc/conf.d/*.conf; do
[ -f "$_i" ] || break
echo $_i
cat $_i | sed -e "$PWFILTER"
done
if command -v lvm >/dev/null 2>/dev/null; then
lvm pvdisplay
lvm vgdisplay
lvm lvdisplay
fi
command -v dmsetup >/dev/null 2>/dev/null && dmsetup ls --tree
cat /proc/mdstat
command -v ip >/dev/null 2>/dev/null && ip addr
if command -v journalctl >/dev/null 2>/dev/null; then
journalctl -ab --no-pager -o short-monotonic | sed -e "$PWFILTER"
else
dmesg | sed -e "$PWFILTER"
[ -f /run/initramfs/init.log ] && cat /run/initramfs/init.log | sed -e "$PWFILTER"
fi
modules.d/99base/initqueue.sh 0000755 00000002213 15023162470 0012077 0 ustar 00 #!/bin/sh
#
# Licensed under the GPLv2+
#
# Copyright 2008-2010, Red Hat, Inc.
# Harald Hoyer
PATH=/usr/sbin:/usr/bin:/sbin:/bin
type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh
while [ $# -gt 0 ]; do
case "$1" in
--onetime)
onetime="yes";;
--online)
qname="/online";;
--settled)
qname="/settled";;
--finished)
qname="/finished";;
--timeout)
qname="/timeout";;
--unique)
unique="yes";;
--name)
name="$2";shift;;
--env)
env="$2"; shift;;
*)
break;;
esac
shift
done
if [ -z "$unique" ]; then
job="${name}$$"
else
job="${name:-$1}"
job=${job##*/}
fi
exe=$1
shift
[ -x "$exe" ] || exe=$(command -v $exe)
if [ -z "$exe" ] ; then
echo "Invalid command"
exit 1
fi
{
[ -n "$onetime" ] && echo '[ -e "$job" ] && rm -f -- "$job"'
[ -n "$env" ] && echo "$env"
echo "$exe" "$@"
} > "/tmp/$$-${job}.sh"
mv -f "/tmp/$$-${job}.sh" "$hookdir/initqueue${qname}/${job}.sh"
[ -z "$qname" ] && >> $hookdir/initqueue/work
exit 0
modules.d/99base/dracut-lib.sh 0000755 00000101730 15023162470 0012121 0 ustar 00 #!/bin/sh
export DRACUT_SYSTEMD
export NEWROOT
if [ -n "$NEWROOT" ]; then
[ -d $NEWROOT ] || mkdir -p -m 0755 $NEWROOT
fi
if ! [ -d /run/initramfs ]; then
mkdir -p -m 0755 /run/initramfs/log
ln -sfn /run/initramfs/log /var/log
fi
[ -d /run/lock ] || mkdir -p -m 0755 /run/lock
[ -d /run/log ] || mkdir -p -m 0755 /run/log
debug_off() {
set +x
}
debug_on() {
[ "$RD_DEBUG" = "yes" ] && set -x
}
# returns OK if $1 contains literal string $2 (and isn't empty)
strstr() {
[ "${1##*"$2"*}" != "$1" ]
}
# returns OK if $1 matches (completely) glob pattern $2
# An empty $1 will not be considered matched, even if $2 is * which technically
# matches; as it would match anything, it's not an interesting case.
strglob() {
[ -n "$1" -a -z "${1##$2}" ]
}
# returns OK if $1 contains (anywhere) a match of glob pattern $2
# An empty $1 will not be considered matched, even if $2 is * which technically
# matches; as it would match anything, it's not an interesting case.
strglobin() {
[ -n "$1" -a -z "${1##*$2*}" ]
}
# 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" ]
}
trim() {
local var="$*"
var="${var#"${var%%[![:space:]]*}"}" # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}" # remove trailing whitespace characters
printf "%s" "$var"
}
if [ -z "$DRACUT_SYSTEMD" ]; then
warn() {
check_quiet
echo "<28>dracut Warning: $*" > /dev/kmsg
echo "dracut Warning: $*" >&2
}
info() {
check_quiet
echo "<30>dracut: $*" > /dev/kmsg
[ "$DRACUT_QUIET" != "yes" ] && \
echo "dracut: $*" >&2
}
else
warn() {
echo "Warning: $*" >&2
}
info() {
echo "$*"
}
fi
vwarn() {
while read line || [ -n "$line" ]; do
warn $line;
done
}
vinfo() {
while read line || [ -n "$line" ]; do
info $line;
done
}
# replaces all occurrences of 'search' in 'str' with 'replacement'
#
# str_replace str search replacement
#
# example:
# str_replace ' one two three ' ' ' '_'
str_replace() {
local in="$1"; local s="$2"; local r="$3"
local out=''
while strstr "${in}" "$s"; do
chop="${in%%"$s"*}"
out="${out}${chop}$r"
in="${in#*"$s"}"
done
echo "${out}${in}"
}
killall_proc_mountpoint() {
local _pid
local _t
local _killed=0
for _pid in /proc/*; do
_pid=${_pid##/proc/}
case $_pid in
*[!0-9]*) continue;;
esac
[ -e "/proc/$_pid/exe" ] || continue
[ -e "/proc/$_pid/root" ] || continue
if strstr "$(ls -l -- "/proc/$_pid" "/proc/$_pid/fd" 2>/dev/null)" "$1" ; then
kill -9 "$_pid"
_killed=1
fi
done
return $_killed
}
getcmdline() {
local _line
local _i
local CMDLINE_ETC_D
local CMDLINE_ETC
local CMDLINE_PROC
unset _line
if [ -e /etc/cmdline ]; then
while read -r _line || [ -n "$_line" ]; do
CMDLINE_ETC="$CMDLINE_ETC $_line";
done ", we want the exact match
if [ "$_o" = "$1" ]; then
_val="1";
unset _doecho
fi
continue
fi
if [ "${_o#*=}" = "$_o" ]; then
# if cmdline argument has no "=", we assume "=1"
_val="1";
unset _doecho
continue
fi
_val="${_o#*=}"
_doecho=1
fi
done
if [ -n "$_val" ]; then
[ "x$_doecho" != "x" ] && echo "$_val";
return 0;
fi
return 1;
}
getarg() {
debug_off
local _deprecated _newoption
while [ $# -gt 0 ]; do
case $1 in
-d) _deprecated=1; shift;;
-y) if _dogetarg $2 >/dev/null; then
if [ "$_deprecated" = "1" ]; then
[ -n "$_newoption" ] && warn "Kernel command line option '$2' is deprecated, use '$_newoption' instead." || warn "Option '$2' is deprecated."
fi
echo 1
debug_on
return 0
fi
_deprecated=0
shift 2;;
-n) if _dogetarg $2 >/dev/null; then
echo 0;
if [ "$_deprecated" = "1" ]; then
[ -n "$_newoption" ] && warn "Kernel command line option '$2' is deprecated, use '$_newoption=0' instead." || warn "Option '$2' is deprecated."
fi
debug_on
return 1
fi
_deprecated=0
shift 2;;
*) if [ -z "$_newoption" ]; then
_newoption="$1"
fi
if _dogetarg $1; then
if [ "$_deprecated" = "1" ]; then
[ -n "$_newoption" ] && warn "Kernel command line option '$1' is deprecated, use '$_newoption' instead." || warn "Option '$1' is deprecated."
fi
debug_on
return 0;
fi
_deprecated=0
shift;;
esac
done
debug_on
return 1
}
# getargbool
# False if "getarg " returns "0", "no", or "off".
# True if getarg returns any other non-empty string.
# If not found, assumes - usually 0 for false, 1 for true.
# example: getargbool 0 rd.info
# true: rd.info, rd.info=1, rd.info=xxx
# false: rd.info=0, rd.info=off, rd.info not present (default val is 0)
getargbool() {
local _b
unset _b
local _default
_default="$1"; shift
_b=$(getarg "$@")
[ $? -ne 0 -a -z "$_b" ] && _b="$_default"
if [ -n "$_b" ]; then
[ $_b = "0" ] && return 1
[ $_b = "no" ] && return 1
[ $_b = "off" ] && return 1
fi
return 0
}
isdigit() {
case "$1" in
*[!0-9]*|"") return 1;;
esac
return 0
}
# getargnum
# Will echo the arg if it's in range [minval - maxval].
# If it's not set or it's not valid, will set it .
# Note all values are required to be >= 0 here.
# should be with [minval -maxval].
getargnum() {
local _b
unset _b
local _default _min _max
_default="$1"; shift
_min="$1"; shift
_max="$1"; shift
_b=$(getarg "$1")
[ $? -ne 0 -a -z "$_b" ] && _b=$_default
if [ -n "$_b" ]; then
isdigit "$_b" && _b=$(($_b)) && \
[ $_b -ge $_min ] && [ $_b -le $_max ] && echo $_b && return
fi
echo $_default
}
_dogetargs() {
debug_off
local _o _found _key
unset _o
unset _found
CMDLINE=$(getcmdline)
_key="$1"
set --
for _o in $CMDLINE; do
if [ "$_o" = "$_key" ]; then
_found=1;
elif [ "${_o%%=*}" = "${_key%=}" ]; then
[ -n "${_o%%=*}" ] && set -- "$@" "${_o#*=}";
_found=1;
fi
done
if [ -n "$_found" ]; then
[ $# -gt 0 ] && printf '%s' "$*"
return 0
fi
return 1;
}
getargs() {
debug_off
local _val _i _args _gfound _deprecated
unset _val
unset _gfound
_newoption="$1"
_args="$@"
set --
for _i in $_args; do
if [ "$_i" = "-d" ]; then
_deprecated=1
continue
fi
_val="$(_dogetargs $_i)"
if [ $? -eq 0 ]; then
if [ "$_deprecated" = "1" ]; then
[ -n "$_newoption" ] && warn "Option '$_i' is deprecated, use '$_newoption' instead." || warn "Option $_i is deprecated!"
fi
_gfound=1
fi
[ -n "$_val" ] && set -- "$@" "$_val"
_deprecated=0
done
if [ -n "$_gfound" ]; then
if [ $# -gt 0 ]; then
printf '%s' "$*"
fi
debug_on
return 0
fi
debug_on
return 1;
}
# Prints value of given option. If option is a flag and it's present,
# it just returns 0. Otherwise 1 is returned.
# $1 = options separated by commas
# $2 = option we are interested in
#
# Example:
# $1 = cipher=aes-cbc-essiv:sha256,hash=sha256,verify
# $2 = hash
# Output:
# sha256
getoptcomma() {
local line=",$1,"; local opt="$2"; local tmp
case "${line}" in
*,${opt}=*,*)
tmp="${line#*,${opt}=}"
echo "${tmp%%,*}"
return 0
;;
*,${opt},*) return 0;;
esac
return 1
}
# Splits given string 'str' with separator 'sep' into variables 'var1', 'var2',
# 'varN'. If number of fields is less than number of variables, remaining are
# not set. If number of fields is greater than number of variables, the last
# variable takes remaining fields. In short - it acts similary to 'read'.
#
# splitsep sep str var1 var2 varN
#
# example:
# splitsep ':' 'foo:bar:baz' v1 v2
# in result:
# v1='foo', v2='bar:baz'
#
# TODO: ':' inside fields.
splitsep() {
debug_off
local sep="$1"; local str="$2"; shift 2
local tmp
while [ -n "$str" -a "$#" -gt 1 ]; do
tmp="${str%%$sep*}"
eval "$1='${tmp}'"
str="${str#"$tmp"}"
str="${str#$sep}"
shift
done
[ -n "$str" -a -n "$1" ] && eval "$1='$str'"
debug_on
return 0
}
setdebug() {
[ -f /usr/lib/initrd-release ] || return
if [ -z "$RD_DEBUG" ]; then
if [ -e /proc/cmdline ]; then
RD_DEBUG=no
if getargbool 0 rd.debug -d -y rdinitdebug -d -y rdnetdebug; then
RD_DEBUG=yes
[ -n "$BASH" ] && \
export PS4='${BASH_SOURCE}@${LINENO}(${FUNCNAME[0]}): ';
fi
fi
export RD_DEBUG
fi
debug_on
}
setdebug
source_all() {
local f
local _dir
_dir=$1; shift
[ "$_dir" ] && [ -d "/$_dir" ] || return
for f in "/$_dir"/*.sh; do [ -e "$f" ] && . "$f" "$@"; done
}
hookdir=/lib/dracut/hooks
export hookdir
source_hook() {
local _dir
_dir=$1; shift
source_all "/lib/dracut/hooks/$_dir" "$@"
}
check_finished() {
local f
for f in $hookdir/initqueue/finished/*.sh; do
[ "$f" = "$hookdir/initqueue/finished/*.sh" ] && return 0
{ [ -e "$f" ] && ( . "$f" ) ; } || return 1
done
return 0
}
source_conf() {
local f
[ "$1" ] && [ -d "/$1" ] || return
for f in "/$1"/*.conf; do [ -e "$f" ] && . "$f"; done
}
die() {
{
echo "<24>dracut: FATAL: $*";
echo "<24>dracut: Refusing to continue";
} > /dev/kmsg
{
echo "warn dracut: FATAL: \"$*\"";
echo "warn dracut: Refusing to continue";
} >> $hookdir/emergency/01-die.sh
[ -d /run/initramfs ] || mkdir -p -- /run/initramfs
> /run/initramfs/.die
if getargbool 0 "rd.shell"; then
emergency_shell
else
source_hook "shutdown-emergency"
fi
if [ -n "$DRACUT_SYSTEMD" ]; then
systemctl --no-block --force halt
fi
exit 1
}
check_quiet() {
if [ -z "$DRACUT_QUIET" ]; then
DRACUT_QUIET="yes"
getargbool 0 rd.info -d -y rdinfo && DRACUT_QUIET="no"
getargbool 0 rd.debug -d -y rdinitdebug && DRACUT_QUIET="no"
getarg quiet || DRACUT_QUIET="yes"
a=$(getarg loglevel=)
[ -n "$a" ] && [ $a -ge 28 ] && DRACUT_QUIET="yes"
export DRACUT_QUIET
fi
}
check_occurances() {
# Count the number of times the character $ch occurs in $str
# Return 0 if the count matches the expected number, 1 otherwise
local str="$1"
local ch="$2"
local expected="$3"
local count=0
while [ "${str#*$ch}" != "${str}" ]; do
str="${str#*$ch}"
count=$(( $count + 1 ))
done
[ $count -eq $expected ]
}
incol2() {
debug_off
local dummy check;
local file="$1";
local str="$2";
[ -z "$file" ] && return 1;
[ -z "$str" ] && return 1;
while read dummy check restofline || [ -n "$check" ]; do
if [ "$check" = "$str" ]; then
debug_on
return 0
fi
done < $file
debug_on
return 1
}
udevsettle() {
[ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version | { read v _ ; echo $v ; })
if [ $UDEVVERSION -ge 143 ]; then
udevadm settle --exit-if-exists=$hookdir/initqueue/work $settle_exit_if_exists
else
udevadm settle --timeout=30
fi
}
udevproperty() {
[ -z "$UDEVVERSION" ] && export UDEVVERSION=$(udevadm --version | { read v _ ; echo $v ; })
if [ $UDEVVERSION -ge 143 ]; then
for i in "$@"; do udevadm control --property=$i; done
else
for i in "$@"; do udevadm control --env=$i; done
fi
}
find_mount() {
local dev mnt etc wanted_dev
wanted_dev="$(readlink -e -q $1)"
while read dev mnt etc || [ -n "$dev" ]; do
[ "$dev" = "$wanted_dev" ] && echo "$dev" && return 0
done < /proc/mounts
return 1
}
# usage: ismounted
# usage: ismounted /dev/
if command -v findmnt >/dev/null; then
ismounted() {
findmnt "$1" > /dev/null 2>&1
}
else
ismounted() {
if [ -b "$1" ]; then
find_mount "$1" > /dev/null && return 0
return 1
fi
while read a m a || [ -n "$m" ]; do
[ "$m" = "$1" ] && return 0
done < /proc/mounts
return 1
}
fi
# root=nfs:[:][:]
# root=nfs4:[:][:]
nfsroot_to_var() {
# strip nfs[4]:
local arg="$@:"
nfs="${arg%%:*}"
arg="${arg##$nfs:}"
# check if we have a server
if strstr "$arg" ':/' ; then
server="${arg%%:/*}"
arg="/${arg##*:/}"
fi
path="${arg%%:*}"
# rest are options
options="${arg##$path}"
# strip leading ":"
options="${options##:}"
# strip ":"
options="${options%%:}"
# Does it really start with '/'?
[ -n "${path%%/*}" ] && path="error";
#Fix kernel legacy style separating path and options with ','
if [ "$path" != "${path#*,}" ] ; then
options=${path#*,}
path=${path%%,*}
fi
}
# Create udev rule match for a device with its device name, or the udev property
# ID_FS_UUID or ID_FS_LABEL
#
# example:
# udevmatch LABEL=boot
# prints:
# ENV{ID_FS_LABEL}="boot"
#
# TODO: symlinks
udevmatch() {
case "$1" in
UUID=????????-????-????-????-????????????|LABEL=*|PARTLABEL=*|PARTUUID=????????-????-????-????-????????????)
printf 'ENV{ID_FS_%s}=="%s"' "${1%%=*}" "${1#*=}"
;;
UUID=*)
printf 'ENV{ID_FS_UUID}=="%s*"' "${1#*=}"
;;
PARTUUID=*)
printf 'ENV{ID_FS_PARTUUID}=="%s*"' "${1#*=}"
;;
/dev/?*) printf -- 'KERNEL=="%s"' "${1#/dev/}" ;;
*) return 255 ;;
esac
}
# Prints unique path for potential file inside specified directory. It consists
# of specified directory, prefix and number at the end which is incremented
# until non-existing file is found.
#
# funiq dir prefix
#
# example:
# # ls /mnt
# cdrom0 cdrom1
#
# # funiq /mnt cdrom
# /mnt/cdrom2
funiq() {
local dir="$1"; local prefix="$2"
local i=0
[ -d "${dir}" ] || return 1
while [ -e "${dir}/${prefix}$i" ]; do
i=$(($i+1)) || return 1
done
echo "${dir}/${prefix}$i"
}
# Creates unique directory and prints its path. It's using funiq to generate
# path.
#
# mkuniqdir subdir new_dir_name
mkuniqdir() {
local dir="$1"; local prefix="$2"
local retdir; local retdir_new
[ -d "${dir}" ] || mkdir -m 0755 -p "${dir}" || return 1
retdir=$(funiq "${dir}" "${prefix}") || return 1
until mkdir -m 0755 "${retdir}" 2>/dev/null; do
retdir_new=$(funiq "${dir}" "${prefix}") || return 1
[ "$retdir_new" = "$retdir" ] && return 1
retdir="$retdir_new"
done
echo "${retdir}"
}
# Copy the contents of SRC into DEST, merging the contents of existing
# directories (kinda like rsync, or cpio -p).
# Creates DEST if it doesn't exist. Overwrites files with the same names.
#
# copytree SRC DEST
copytree() {
local src="$1" dest="$2"
mkdir -p "$dest"; dest=$(readlink -e -q "$dest")
( cd "$src"; cp -af . -t "$dest" )
}
# Evaluates command for UUIDs either given as arguments for this function or all
# listed in /dev/disk/by-uuid. UUIDs doesn't have to be fully specified. If
# beginning is given it is expanded to all matching UUIDs. To pass full UUID to
# your command use '$___' as a place holder. Remember to escape '$'!
#
# foreach_uuid_until [ -p prefix ] command UUIDs
#
# prefix - string to put just before $___
# command - command to be evaluated
# UUIDs - list of UUIDs separated by space
#
# The function returns after *first successful evaluation* of the given command
# with status 0. If evaluation fails for every UUID function returns with
# status 1.
#
# Example:
# foreach_uuid_until "mount -U \$___ /mnt; echo OK; umount /mnt" \
# "01234 f512 a235567f-12a3-c123-a1b1-01234567abcb"
foreach_uuid_until() (
cd /dev/disk/by-uuid
[ "$1" = -p ] && local prefix="$2" && shift 2
local cmd="$1"; shift; local uuids_list="$*"
local uuid; local full_uuid; local ___
[ -n "${cmd}" ] || return 1
for uuid in ${uuids_list:-*}; do
for full_uuid in ${uuid}*; do
[ -e "${full_uuid}" ] || continue
___="${prefix}${full_uuid}"
eval ${cmd} && return 0
done
done
return 1
)
# Get kernel name for given device. Device may be the name too (then the same
# is returned), a symlink (full path), UUID (prefixed with "UUID=") or label
# (prefixed with "LABEL="). If just a beginning of the UUID is specified or
# even an empty, function prints all device names which UUIDs match - every in
# single line.
#
# NOTICE: The name starts with "/dev/".
#
# Example:
# devnames UUID=123
# May print:
# /dev/dm-1
# /dev/sdb1
# /dev/sdf3
devnames() {
local dev="$1"; local d; local names
case "$dev" in
UUID=*)
dev="$(foreach_uuid_until '! blkid -U $___' "${dev#UUID=}")" \
&& return 255
[ -z "$dev" ] && return 255
;;
LABEL=*) dev="$(blkid -L "${dev#LABEL=}")" || return 255 ;;
/dev/?*) ;;
*) return 255 ;;
esac
for d in $dev; do
names="$names
$(readlink -e -q "$d")" || return 255
done
echo "${names#
}"
}
usable_root() {
local _i
[ -d "$1" ] || return 1
for _i in "$1"/usr/lib*/ld-*.so "$1"/lib*/ld-*.so; do
[ -e "$_i" ] && return 0
done
for _i in proc sys dev; do
[ -e "$1"/$_i ] || return 1
done
return 0
}
inst_hook() {
local _hookname _unique _name _job _exe
while [ $# -gt 0 ]; do
case "$1" in
--hook)
_hookname="/$2";shift;;
--unique)
_unique="yes";;
--name)
_name="$2";shift;;
*)
break;;
esac
shift
done
if [ -z "$_unique" ]; then
_job="${_name}$$"
else
_job="${_name:-$1}"
_job=${_job##*/}
fi
_exe=$1
shift
[ -x "$_exe" ] || _exe=$(command -v $_exe)
if [ -n "$onetime" ]; then
{
echo '[ -e "$_job" ] && rm -f -- "$_job"'
echo "$_exe $@"
} > "/tmp/$$-${_job}.sh"
else
echo "$_exe $@" > "/tmp/$$-${_job}.sh"
fi
mv -f "/tmp/$$-${_job}.sh" "$hookdir/${_hookname}/${_job}.sh"
}
# inst_mount_hook