summaryrefslogtreecommitdiffstats
path: root/modules.d/99base
diff options
context:
space:
mode:
Diffstat (limited to 'modules.d/99base')
-rwxr-xr-xmodules.d/99base/dracut-dev-lib.sh139
-rwxr-xr-xmodules.d/99base/dracut-lib.sh1178
-rwxr-xr-xmodules.d/99base/init.sh399
-rwxr-xr-xmodules.d/99base/initqueue.sh72
-rwxr-xr-xmodules.d/99base/loginit.sh23
-rwxr-xr-xmodules.d/99base/module-setup.sh146
-rwxr-xr-xmodules.d/99base/parse-root-opts.sh14
-rwxr-xr-xmodules.d/99base/rdsosreport.sh61
8 files changed, 2032 insertions, 0 deletions
diff --git a/modules.d/99base/dracut-dev-lib.sh b/modules.d/99base/dracut-dev-lib.sh
new file mode 100755
index 0000000..5779508
--- /dev/null
+++ b/modules.d/99base/dracut-dev-lib.sh
@@ -0,0 +1,139 @@
+#!/bin/sh
+
+# 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 [ "${in##*"$s"*}" != "$in" ]; do
+ chop="${in%%"$s"*}"
+ out="${out}${chop}$r"
+ in="${in#*"$s"}"
+ done
+ printf -- '%s' "${out}${in}"
+}
+
+# get a systemd-compatible unit name from a path
+# (mimics unit_name_from_path_instance())
+dev_unit_name() {
+ local dev="$1"
+
+ if command -v systemd-escape > /dev/null; then
+ systemd-escape -p -- "$dev"
+ return $?
+ fi
+
+ if [ "$dev" = "/" -o -z "$dev" ]; then
+ printf -- "-"
+ return 0
+ fi
+
+ dev="${1%%/}"
+ dev="${dev##/}"
+ # shellcheck disable=SC1003
+ dev="$(str_replace "$dev" '\' '\x5c')"
+ dev="$(str_replace "$dev" '-' '\x2d')"
+ if [ "${dev##.}" != "$dev" ]; then
+ dev="\x2e${dev##.}"
+ fi
+ dev="$(str_replace "$dev" '/' '-')"
+
+ printf -- "%s" "$dev"
+}
+
+# set_systemd_timeout_for_dev [-n] <dev> [<timeout>]
+# Set 'rd.timeout' as the systemd timeout for <dev>
+set_systemd_timeout_for_dev() {
+ local _name
+ local _needreload
+ local _noreload
+ local _timeout
+
+ [ -z "$DRACUT_SYSTEMD" ] && return 0
+
+ if [ "$1" = "-n" ]; then
+ _noreload=1
+ shift
+ fi
+
+ if [ -n "$2" ]; then
+ _timeout="$2"
+ else
+ _timeout=$(getarg rd.timeout)
+ fi
+
+ _timeout=${_timeout:-0}
+
+ _name=$(dev_unit_name "$1")
+ if ! [ -L "${PREFIX}/etc/systemd/system/initrd.target.wants/${_name}.device" ]; then
+ [ -d "${PREFIX}"/etc/systemd/system/initrd.target.wants ] || mkdir -p "${PREFIX}"/etc/systemd/system/initrd.target.wants
+ ln -s ../"${_name}".device "${PREFIX}/etc/systemd/system/initrd.target.wants/${_name}.device"
+ type mark_hostonly > /dev/null 2>&1 && mark_hostonly /etc/systemd/system/initrd.target.wants/"${_name}".device
+ _needreload=1
+ fi
+
+ if ! [ -f "${PREFIX}/etc/systemd/system/${_name}.device.d/timeout.conf" ]; then
+ mkdir -p "${PREFIX}/etc/systemd/system/${_name}.device.d"
+ {
+ echo "[Unit]"
+ echo "JobTimeoutSec=$_timeout"
+ echo "JobRunningTimeoutSec=$_timeout"
+ } > "${PREFIX}/etc/systemd/system/${_name}.device.d/timeout.conf"
+ type mark_hostonly > /dev/null 2>&1 && mark_hostonly /etc/systemd/system/"${_name}".device.d/timeout.conf
+ _needreload=1
+ fi
+
+ if [ -z "$PREFIX" ] && [ "$_needreload" = 1 ] && [ -z "$_noreload" ]; then
+ /sbin/initqueue --onetime --unique --name daemon-reload systemctl daemon-reload
+ fi
+}
+
+# wait_for_dev <dev> [<timeout>]
+#
+# Installs a initqueue-finished script,
+# which will cause the main loop only to exit,
+# if the device <dev> is recognized by the system.
+wait_for_dev() {
+ local _name
+ local _noreload
+
+ if [ "$1" = "-n" ]; then
+ _noreload=-n
+ shift
+ fi
+
+ _name="$(str_replace "$1" '/' '\x2f')"
+
+ type mark_hostonly > /dev/null 2>&1 && mark_hostonly "$hookdir/initqueue/finished/devexists-${_name}.sh"
+
+ [ -e "${PREFIX}$hookdir/initqueue/finished/devexists-${_name}.sh" ] && return 0
+
+ printf '[ -e "%s" ]\n' "$1" \
+ >> "${PREFIX}$hookdir/initqueue/finished/devexists-${_name}.sh"
+ {
+ printf '[ -e "%s" ] || ' "$1"
+ printf 'warn "\"%s\" does not exist"\n' "$1"
+ } >> "${PREFIX}$hookdir/emergency/80-${_name}.sh"
+
+ set_systemd_timeout_for_dev $_noreload "$@"
+}
+
+cancel_wait_for_dev() {
+ local _name
+ _name="$(str_replace "$1" '/' '\x2f')"
+ rm -f -- "$hookdir/initqueue/finished/devexists-${_name}.sh"
+ rm -f -- "$hookdir/emergency/80-${_name}.sh"
+ if [ -n "$DRACUT_SYSTEMD" ]; then
+ _name=$(dev_unit_name "$1")
+ rm -f -- "${PREFIX}/etc/systemd/system/initrd.target.wants/${_name}.device"
+ rm -f -- "${PREFIX}/etc/systemd/system/${_name}.device.d/timeout.conf"
+ /sbin/initqueue --onetime --unique --name daemon-reload systemctl daemon-reload
+ fi
+}
diff --git a/modules.d/99base/dracut-lib.sh b/modules.d/99base/dracut-lib.sh
new file mode 100755
index 0000000..39609d8
--- /dev/null
+++ b/modules.d/99base/dracut-lib.sh
@@ -0,0 +1,1178 @@
+#!/bin/sh
+
+type wait_for_dev > /dev/null 2>&1 || . /lib/dracut-dev-lib.sh
+
+export DRACUT_SYSTEMD
+export NEWROOT
+if [ -n "$NEWROOT" ]; then
+ [ -d "$NEWROOT" ] || mkdir -p -m 0755 "$NEWROOT"
+fi
+
+# shellcheck disable=SC2153
+if [ -z "$PREFIX" ]; then
+ 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
+fi
+
+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() {
+ # shellcheck disable=SC2295
+ [ -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() {
+ # shellcheck disable=SC2295
+ [ -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
+ if [ "$DRACUT_QUIET" != "yes" ]; then
+ echo "dracut: $*" >&2
+ fi
+ }
+
+else
+
+ warn() {
+ echo "Warning: $*" >&2
+ }
+
+ info() {
+ echo "$*"
+ }
+
+fi
+
+vwarn() {
+ while read -r line || [ -n "$line" ]; do
+ warn "$line"
+ done
+}
+
+vinfo() {
+ while read -r line || [ -n "$line" ]; do
+ info "$line"
+ done
+}
+
+killall_proc_mountpoint() {
+ local _pid
+ 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 < /etc/cmdline
+ fi
+ for _i in /etc/cmdline.d/*.conf; do
+ [ -e "$_i" ] || continue
+ while read -r _line || [ -n "$_line" ]; do
+ CMDLINE_ETC_D="$CMDLINE_ETC_D $_line"
+ done < "$_i"
+ done
+ if [ -e /proc/cmdline ]; then
+ while read -r _line || [ -n "$_line" ]; do
+ CMDLINE_PROC="$CMDLINE_PROC $_line"
+ done < /proc/cmdline
+ fi
+ CMDLINE="$CMDLINE_ETC_D $CMDLINE_ETC $CMDLINE_PROC"
+ printf "%s" "$CMDLINE"
+}
+
+getarg() {
+ debug_off
+ local _deprecated _newoption
+ CMDLINE=$(getcmdline)
+ export CMDLINE
+ while [ $# -gt 0 ]; do
+ case $1 in
+ -d)
+ _deprecated=1
+ shift
+ ;;
+ -y)
+ if dracut-getarg "$2" > /dev/null; then
+ if [ "$_deprecated" = "1" ]; then
+ if [ -n "$_newoption" ]; then
+ warn "Kernel command line option '$2' is deprecated, use '$_newoption' instead."
+ else
+ warn "Option '$2' is deprecated."
+ fi
+ fi
+ echo 1
+ debug_on
+ return 0
+ fi
+ _deprecated=0
+ shift 2
+ ;;
+ -n)
+ if dracut-getarg "$2" > /dev/null; then
+ echo 0
+ if [ "$_deprecated" = "1" ]; then
+ if [ -n "$_newoption" ]; then
+ warn "Kernel command line option '$2' is deprecated, use '$_newoption=0' instead."
+ else
+ warn "Option '$2' is deprecated."
+ fi
+ fi
+ debug_on
+ return 1
+ fi
+ _deprecated=0
+ shift 2
+ ;;
+ *)
+ if [ -z "$_newoption" ]; then
+ _newoption="$1"
+ fi
+ if dracut-getarg "$1"; then
+ if [ "$_deprecated" = "1" ]; then
+ if [ -n "$_newoption" ]; then
+ warn "Kernel command line option '$1' is deprecated, use '$_newoption' instead."
+ else
+ warn "Option '$1' is deprecated."
+ fi
+ fi
+ debug_on
+ return 0
+ fi
+ _deprecated=0
+ shift
+ ;;
+ esac
+ done
+ debug_on
+ return 1
+}
+
+# getargbool <defaultval> <args...>
+# False if "getarg <args...>" returns "0", "no", or "off".
+# True if getarg returns any other non-empty string.
+# If not found, assumes <defaultval> - 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 "$@") || _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 <defaultval> <minval> <maxval> <arg>
+# Will echo the arg if it's in range [minval - maxval].
+# If it's not set or it's not valid, will set it <defaultval>.
+# Note all values are required to be >= 0 here.
+# <defaultval> 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") || _b=${_b:-"$_default"}
+ if [ -n "$_b" ]; then
+ isdigit "$_b" && _b=$((_b)) \
+ && [ $_b -ge "$_min" ] && [ $_b -le "$_max" ] && echo $_b && return
+ fi
+ echo "$_default"
+}
+
+getargs() {
+ debug_off
+ CMDLINE=$(getcmdline)
+ export CMDLINE
+ local _val _i _gfound _deprecated
+ unset _val
+ unset _gfound
+ _newoption="$1"
+ for _i in "$@"; do
+ if [ "$_i" = "-d" ]; then
+ _deprecated=1
+ continue
+ fi
+
+ if _val="$(dracut-getargs "$_i")"; then
+ if [ "$_deprecated" = "1" ]; then
+ if [ -n "$_newoption" ]; then
+ warn "Option '$_i' is deprecated, use '$_newoption' instead."
+ else
+ warn "Option $_i is deprecated!"
+ fi
+ fi
+ if [ -n "$_val" ]; then
+ printf '%s\n' "$_val"
+ fi
+ _gfound=1
+ fi
+ _deprecated=0
+ done
+ if [ -n "$_gfound" ]; then
+ 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 similarly 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
+ if [ -e "$f" ]; then
+ # shellcheck disable=SC1090
+ # shellcheck disable=SC2240
+ . "$f" "$@"
+ fi
+ done
+}
+
+hookdir=/lib/dracut/hooks
+export hookdir
+
+source_hook() {
+ local _dir
+ _dir=$1
+ shift
+ source_all "/lib/dracut/hooks/$_dir" "$@"
+}
+
+check_finished() {
+ local f rc=0
+ for f in "$hookdir"/initqueue/finished/*.sh; do
+ [ "$f" = "$hookdir/initqueue/finished/*.sh" ] && return 0
+ # shellcheck disable=SC1090
+ if [ -e "$f" ] && (. "$f"); then
+ rm -f "$f"
+ else
+ rc=1
+ fi
+ done
+ return $rc
+}
+
+source_conf() {
+ local f
+ [ "$1" ] && [ -d "/$1" ] || return
+ # shellcheck disable=SC1090
+ 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 check
+ local file="$1"
+ local str="$2"
+
+ [ -z "$file" ] && return 1
+ [ -z "$str" ] && return 1
+
+ while read -r _ check _ || [ -n "$check" ]; do
+ if [ "$check" = "$str" ]; then
+ debug_on
+ return 0
+ fi
+ done < "$file"
+ debug_on
+ return 1
+}
+
+udevsettle() {
+ # shellcheck disable=SC2086
+ udevadm settle --exit-if-exists=$hookdir/initqueue/work $settle_exit_if_exists
+}
+
+udevproperty() {
+ for i in "$@"; do
+ udevadm control --property="$i"
+ done
+}
+
+find_mount() {
+ local dev wanted_dev
+ wanted_dev="$(readlink -e -q "$1")"
+ while read -r dev _ || [ -n "$dev" ]; do
+ [ "$dev" = "$wanted_dev" ] && echo "$dev" && return 0
+ done < /proc/mounts
+ return 1
+}
+
+# usage: ismounted <mountpoint>
+# usage: ismounted /dev/<device>
+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 -r _ m _ || [ -n "$m" ]; do
+ [ "$m" = "$1" ] && return 0
+ done < /proc/mounts
+ return 1
+ }
+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
+}
+
+label_uuid_to_dev() {
+ local _dev
+ _dev="${1#block:}"
+ case "$_dev" in
+ LABEL=*)
+ echo "/dev/disk/by-label/$(echo "${_dev#LABEL=}" | sed 's,/,\\x2f,g;s, ,\\x20,g')"
+ ;;
+ PARTLABEL=*)
+ echo "/dev/disk/by-partlabel/$(echo "${_dev#PARTLABEL=}" | sed 's,/,\\x2f,g;s, ,\\x20,g')"
+ ;;
+ UUID=*)
+ echo "/dev/disk/by-uuid/${_dev#UUID=}"
+ ;;
+ PARTUUID=*)
+ echo "/dev/disk/by-partuuid/${_dev#PARTUUID=}"
+ ;;
+ *)
+ echo "$_dev"
+ ;;
+ 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"
+ [ -d "$src" ] || return 1
+ mkdir -p "$dest" || return 1
+ dest=$(readlink -e -q "$dest") || return 1
+ (
+ cd "$src" || exit 1
+ 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 || return 1
+
+ [ "$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
+ # shellcheck disable=SC2034
+ ___="${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=*)
+ # shellcheck disable=SC2016
+ 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
+ {
+ # shellcheck disable=SC2016
+ 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 <mountpoint> <prio> <name> <script>
+#
+# Install a mount hook with priority <prio>,
+# which executes <script> as soon as <mountpoint> is mounted.
+inst_mount_hook() {
+ local _prio="$2" _jobname="$3" _script="$4"
+ local _hookname
+ _hookname="mount-$(str_replace "$1" '/' '\\x2f')"
+ [ -d "$hookdir/${_hookname}" ] || mkdir -p "$hookdir/${_hookname}"
+ inst_hook --hook "$_hookname" --unique --name "${_prio}-${_jobname}" "$_script"
+}
+
+# wait_for_mount <mountpoint>
+#
+# Installs a initqueue-finished script,
+# which will cause the main loop only to exit,
+# if <mountpoint> is mounted.
+wait_for_mount() {
+ local _name
+ _name="$(str_replace "$1" '/' '\\x2f')"
+ printf '. /lib/dracut-lib.sh\nismounted "%s"\n' "$1" \
+ >> "$hookdir/initqueue/finished/ismounted-${_name}.sh"
+ {
+ printf 'ismounted "%s" || ' "$1"
+ printf 'warn "\"%s\" is not mounted"\n' "$1"
+ } >> "$hookdir/emergency/90-${_name}.sh"
+}
+
+killproc() {
+ debug_off
+ local _exe
+ _exe="$(command -v "$1")"
+ local _sig="$2"
+ local _i
+ [ -x "$_exe" ] || return 1
+ for _i in /proc/[0-9]*; do
+ [ "$_i" = "/proc/1" ] && continue
+ if [ -e "$_i"/_exe ] && [ "$_i/_exe" -ef "$_exe" ]; then
+ kill "$_sig" "${_i##*/}"
+ fi
+ done
+ debug_on
+}
+
+need_shutdown() {
+ : > /run/initramfs/.need_shutdown
+}
+
+wait_for_loginit() {
+ [ "$RD_DEBUG" = "yes" ] || return
+ [ -e /run/initramfs/loginit.pipe ] || return
+ debug_off
+ echo "DRACUT_LOG_END"
+ exec 0<> /dev/console 1<> /dev/console 2<> /dev/console
+ # wait for loginit
+ i=0
+ while [ $i -lt 10 ]; do
+ if [ ! -e /run/initramfs/loginit.pipe ]; then
+ j=$(jobs)
+ [ -z "$j" ] && break
+ [ -z "${j##*Running*}" ] || break
+ fi
+ sleep 0.1
+ i=$((i + 1))
+ done
+
+ if [ $i -eq 10 ]; then
+ kill %1 > /dev/null 2>&1
+ kill "$(while read -r line || [ -n "$line" ]; do echo "$line"; done < /run/initramfs/loginit.pid)"
+ fi
+
+ setdebug
+ rm -f -- /run/initramfs/loginit.pipe /run/initramfs/loginit.pid
+}
+
+# pidof version for root
+if ! command -v pidof > /dev/null 2> /dev/null; then
+ pidof() {
+ debug_off
+ local _cmd
+ local _exe
+ local _rl
+ local _ret=1
+ local i
+ _cmd="$1"
+ if [ -z "$_cmd" ]; then
+ debug_on
+ return 1
+ fi
+ _exe=$(command -v "$1")
+ for i in /proc/*/exe; do
+ [ -e "$i" ] || continue
+ if [ -n "$_exe" ]; then
+ [ "$i" -ef "$_exe" ] || continue
+ else
+ _rl=$(readlink -f "$i")
+ [ "${_rl%/"$_cmd"}" != "$_rl" ] || continue
+ fi
+ i=${i%/exe}
+ echo "${i##/proc/}"
+ _ret=0
+ done
+ debug_on
+ return $_ret
+ }
+fi
+
+_emergency_shell() {
+ local _name="$1"
+ if [ -n "$DRACUT_SYSTEMD" ]; then
+ : > /.console_lock
+ echo "PS1=\"$_name:\\\${PWD}# \"" > /etc/profile
+ systemctl start dracut-emergency.service
+ rm -f -- /etc/profile
+ rm -f -- /.console_lock
+ else
+ debug_off
+ source_hook "$hook"
+ echo
+ /sbin/rdsosreport
+ 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.'
+ if ! RD_DEBUG='' getargbool 0 rd.debug -d -y rdinitdebug -d -y rdnetdebug; then
+ echo
+ echo 'To get more debug information in the report,'
+ echo 'reboot with "rd.debug" added to the kernel command line.'
+ fi
+ echo
+ echo 'Dropping to debug shell.'
+ echo
+ export PS1="$_name:\${PWD}# "
+ [ -e /.profile ] || : > /.profile
+
+ _ctty="$(RD_DEBUG='' getarg rd.ctty=)" && _ctty="/dev/${_ctty##*/}"
+ if [ -z "$_ctty" ]; then
+ _ctty=console
+ while [ -f /sys/class/tty/$_ctty/active ]; do
+ read -r _ctty < /sys/class/tty/$_ctty/active
+ _ctty=${_ctty##* } # last one in the list
+ done
+ _ctty=/dev/$_ctty
+ fi
+ [ -c "$_ctty" ] || _ctty=/dev/tty1
+ case "$(/usr/bin/setsid --help 2>&1)" in *--ctty*) CTTY="--ctty" ;; esac
+ setsid $CTTY /bin/sh -i -l 0<> $_ctty 1<> $_ctty 2<> $_ctty
+ fi
+}
+
+emergency_shell() {
+ local _ctty
+ set +e
+ local _rdshell_name="dracut" action="Boot" hook="emergency"
+ local _emergency_action
+
+ if [ "$1" = "-n" ]; then
+ _rdshell_name=$2
+ shift 2
+ elif [ "$1" = "--shutdown" ]; then
+ _rdshell_name=$2
+ action="Shutdown"
+ hook="shutdown-emergency"
+ shift 2
+ fi
+
+ echo
+ echo
+ warn "$*"
+ echo
+
+ _emergency_action=$(getarg rd.emergency)
+ [ -z "$_emergency_action" ] \
+ && [ -e /run/initramfs/.die ] \
+ && _emergency_action=halt
+
+ if getargbool 1 rd.shell -d -y rdshell || getarg rd.break -d rdbreak; then
+ _emergency_shell "$_rdshell_name"
+ else
+ source_hook "$hook"
+ warn "$action has failed. To debug this issue add \"rd.shell rd.debug\" to the kernel command line."
+ [ -z "$_emergency_action" ] && _emergency_action=halt
+ fi
+
+ case "$_emergency_action" in
+ reboot)
+ reboot || exit 1
+ ;;
+ poweroff)
+ poweroff || exit 1
+ ;;
+ halt)
+ halt || exit 1
+ ;;
+ esac
+}
+
+# Retain the values of these variables but ensure that they are unexported
+# This is a POSIX-compliant equivalent of bash's "export -n"
+export_n() {
+ local var
+ local val
+ for var in "$@"; do
+ eval val=\$$var
+ unset $var
+ [ -n "$val" ] && eval "$var=\"$val\""
+ done
+}
+
+# returns OK if list1 contains all elements of list2, i.e. checks if list2 is a
+# sublist of list1. An order and a duplication doesn't matter.
+#
+# $1 = separator
+# $2 = list1
+# $3 = list2
+# $4 = ignore values, separated by $1
+listlist() {
+ local _sep="$1"
+ local _list="${_sep}${2}${_sep}"
+ local _sublist="$3"
+ [ -n "$4" ] && local _iglist="${_sep}${4}${_sep}"
+ local IFS="$_sep"
+ local _v
+
+ [ "$_list" = "$_sublist" ] && return 0
+
+ for _v in $_sublist; do
+ if [ -n "$_v" ] && ! ([ -n "$_iglist" ] && strstr "$_iglist" "$_v"); then
+ strstr "$_list" "$_v" || return 1
+ fi
+ done
+
+ return 0
+}
+
+# returns OK if both lists contain the same values. An order and a duplication
+# doesn't matter.
+#
+# $1 = separator
+# $2 = list1
+# $3 = list2
+# $4 = ignore values, separated by $1
+are_lists_eq() {
+ listlist "$1" "$2" "$3" "$4" && listlist "$1" "$3" "$2" "$4"
+}
+
+setmemdebug() {
+ if [ -z "$DEBUG_MEM_LEVEL" ]; then
+ DEBUG_MEM_LEVEL=$(getargnum 0 0 5 rd.memdebug)
+ export DEBUG_MEM_LEVEL
+ fi
+}
+
+setmemdebug
+
+# parameters: func log_level prefix msg [trace_level:trace]...
+make_trace_mem() {
+ local log_level prefix msg msg_printed
+ local trace trace_level trace_in_higher_levels insert_trace
+
+ msg=$1
+ shift
+
+ prefix='[debug_mem]'
+ log_level=$DEBUG_MEM_LEVEL
+
+ if [ -z "$log_level" ] || [ "$log_level" -le 0 ]; then
+ return
+ fi
+
+ # FIXME? useless echo?
+ # shellcheck disable=SC2116
+ msg=$(echo "$msg")
+
+ msg_printed=0
+ while [ $# -gt 0 ]; do
+ trace=${1%%:*}
+ trace_level=${trace%%+}
+ [ "$trace" != "$trace_level" ] && trace_in_higher_levels="yes"
+ trace=${1##*:}
+
+ if [ -z "$trace_level" ]; then
+ trace_level=0
+ fi
+
+ insert_trace=0
+ if [ -n "$trace_in_higher_levels" ]; then
+ if [ "$log_level" -ge "$trace_level" ]; then
+ insert_trace=1
+ fi
+ else
+ if [ "$log_level" -eq "$trace_level" ]; then
+ insert_trace=1
+ fi
+ fi
+
+ if [ $insert_trace -eq 1 ]; then
+ if [ $msg_printed -eq 0 ]; then
+ echo "$prefix $msg"
+ msg_printed=1
+ fi
+ show_memstats "$trace"
+ fi
+ shift
+ done
+}
+
+# parameters: type
+show_memstats() {
+ case $1 in
+ shortmem)
+ while read -r line || [ -n "$line" ]; do
+ str_starts "$line" "MemFree" \
+ || str_starts "$line" "Cached" \
+ || str_starts "$line" "Slab" \
+ || continue
+ echo "$line"
+ done < /proc/meminfo
+ ;;
+ mem)
+ cat /proc/meminfo
+ ;;
+ slab)
+ cat /proc/slabinfo
+ ;;
+ iomem)
+ cat /proc/iomem
+ ;;
+ esac
+}
+
+remove_hostonly_files() {
+ rm -fr /etc/cmdline /etc/cmdline.d/*.conf "$hookdir/initqueue/finished"
+ if [ -f /lib/dracut/hostonly-files ]; then
+ while read -r line || [ -n "$line" ]; do
+ [ -e "$line" ] || [ -h "$line" ] || continue
+ rm -f "$line"
+ done < /lib/dracut/hostonly-files
+ fi
+}
+
+# parameter: kernel_module [filesystem_name]
+# returns OK if kernel_module is loaded
+# modprobe fails if /lib/modules is not available (--no-kernel use case)
+load_fstype() {
+ local - fs _fs="${2:-$1}"
+ set +x
+ while read -r d fs || [ "$d" ]; do
+ [ "${fs:-$d}" = "$_fs" ] && return 0
+ done < /proc/filesystems
+ modprobe "$1"
+}
+
+# parameter: size of live image
+# calls emergency shell if ram size is too small for the image
+check_live_ram() {
+ minmem=$(getarg rd.minmem)
+ minmem=${minmem:-1024}
+ imgsize=$1
+ memsize=$(($(sed -n 's/MemTotal: *\([[:digit:]]*\).*/\1/p' /proc/meminfo) / 1024))
+
+ if [ -z "$imgsize" ]; then
+ warn "Image size could not be determined"
+ return 0
+ fi
+
+ if [ $((memsize - imgsize)) -lt "$minmem" ]; then
+ sed -i "N;/and attach it to a bug report./s/echo$/echo\n\
+ echo \n\
+ echo 'Warning!!!'\n\
+ echo 'The memory size of your system is too small for this live image.'\n\
+ echo 'Expect killed processes due to out of memory conditions.'\n\
+ echo \n/" /usr/bin/dracut-emergency
+
+ emergency_shell
+ fi
+}
diff --git a/modules.d/99base/init.sh b/modules.d/99base/init.sh
new file mode 100755
index 0000000..285059e
--- /dev/null
+++ b/modules.d/99base/init.sh
@@ -0,0 +1,399 @@
+#!/bin/sh
+#
+# Licensed under the GPLv2
+#
+# Copyright 2008-2010, Red Hat, Inc.
+# Harald Hoyer <harald@redhat.com>
+# Jeremy Katz <katzj@redhat.com>
+
+export -p > /tmp/export.orig
+
+NEWROOT="/sysroot"
+[ -d $NEWROOT ] || mkdir -p -m 0755 $NEWROOT
+
+OLDPATH=$PATH
+PATH=/usr/sbin:/usr/bin:/sbin:/bin
+export PATH
+
+# mount some important things
+if [ ! -d /proc/self ]; then
+ if ! mount -t proc -o nosuid,noexec,nodev proc /proc > /dev/null; then
+ echo "Cannot mount proc on /proc! Compile the kernel with CONFIG_PROC_FS!"
+ exit 1
+ fi
+fi
+
+if [ ! -d /sys/kernel ]; then
+ if ! mount -t sysfs -o nosuid,noexec,nodev sysfs /sys > /dev/null; then
+ echo "Cannot mount sysfs on /sys! Compile the kernel with CONFIG_SYSFS!"
+ exit 1
+ fi
+fi
+
+RD_DEBUG=""
+. /lib/dracut-lib.sh
+
+setdebug
+
+if ! ismounted /dev; then
+ mount -t devtmpfs -o mode=0755,noexec,nosuid,strictatime devtmpfs /dev > /dev/null
+fi
+
+if ! ismounted /dev; then
+ echo "Cannot mount devtmpfs on /dev! Compile the kernel with CONFIG_DEVTMPFS!"
+ exit 1
+fi
+
+# prepare the /dev directory
+[ ! -h /dev/fd ] && ln -s /proc/self/fd /dev/fd > /dev/null 2>&1
+[ ! -h /dev/stdin ] && ln -s /proc/self/fd/0 /dev/stdin > /dev/null 2>&1
+[ ! -h /dev/stdout ] && ln -s /proc/self/fd/1 /dev/stdout > /dev/null 2>&1
+[ ! -h /dev/stderr ] && ln -s /proc/self/fd/2 /dev/stderr > /dev/null 2>&1
+
+if ! ismounted /dev/pts; then
+ mkdir -m 0755 -p /dev/pts
+ mount -t devpts -o gid=5,mode=620,noexec,nosuid devpts /dev/pts > /dev/null
+fi
+
+if ! ismounted /dev/shm; then
+ mkdir -m 0755 -p /dev/shm
+ mount -t tmpfs -o mode=1777,noexec,nosuid,nodev,strictatime tmpfs /dev/shm > /dev/null
+fi
+
+if ! ismounted /run; then
+ mkdir -m 0755 -p /newrun
+ if ! str_starts "$(readlink -f /bin/sh)" "/run/"; then
+ mount -t tmpfs -o mode=0755,noexec,nosuid,nodev,strictatime tmpfs /newrun > /dev/null
+ else
+ # the initramfs binaries are located in /run, so don't mount it with noexec
+ mount -t tmpfs -o mode=0755,nosuid,nodev,strictatime tmpfs /newrun > /dev/null
+ fi
+ cp -a /run/* /newrun > /dev/null 2>&1
+ mount --move /newrun /run
+ rm -fr -- /newrun
+fi
+
+if command -v kmod > /dev/null 2> /dev/null; then
+ kmod static-nodes --format=tmpfiles 2> /dev/null \
+ | while read -r type file mode _ _ _ majmin || [ -n "$type" ]; do
+ type=${type%\!}
+ case $type in
+ d)
+ mkdir -m "$mode" -p "$file"
+ ;;
+ c)
+ mknod -m "$mode" "$file" "$type" "${majmin%:*}" "${majmin#*:}"
+ ;;
+ esac
+ done
+fi
+
+trap "emergency_shell Signal caught!" 0
+
+export UDEVRULESD=/run/udev/rules.d
+[ -d /run/udev ] || mkdir -p -m 0755 /run/udev
+[ -d "$UDEVRULESD" ] || mkdir -p -m 0755 "$UDEVRULESD"
+
+if [ "$RD_DEBUG" = "yes" ]; then
+ mkfifo /run/initramfs/loginit.pipe
+ loginit "$DRACUT_QUIET" < /run/initramfs/loginit.pipe > /dev/console 2>&1 &
+ exec > /run/initramfs/loginit.pipe 2>&1
+else
+ exec 0<> /dev/console 1<> /dev/console 2<> /dev/console
+fi
+
+[ -f /usr/lib/initrd-release ] && . /usr/lib/initrd-release
+[ -n "$VERSION_ID" ] && info "$NAME-$VERSION_ID"
+
+source_conf /etc/conf.d
+
+if getarg "rd.cmdline=ask"; then
+ echo "Enter additional kernel command line parameter (end with ctrl-d or .)"
+ while read -r -p "> " ${BASH:+-e} line || [ -n "$line" ]; do
+ [ "$line" = "." ] && break
+ echo "$line" >> /etc/cmdline.d/99-cmdline-ask.conf
+ done
+fi
+
+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
+
+# run scriptlets to parse the command line
+make_trace_mem "hook cmdline" '1+:mem' '1+:iomem' '3+:slab'
+getarg 'rd.break=cmdline' -d 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline"
+source_hook cmdline
+
+[ -z "$root" ] && die "No or empty root= argument"
+[ -z "$rootok" ] && die "Don't know how to handle 'root=$root'"
+
+export root rflags fstype netroot NEWROOT
+
+# pre-udev scripts run before udev starts, and are run only once.
+make_trace_mem "hook pre-udev" '1:shortmem' '2+:mem' '3+:slab'
+getarg 'rd.break=pre-udev' -d 'rdbreak=pre-udev' && emergency_shell -n pre-udev "Break before pre-udev"
+source_hook pre-udev
+
+UDEV_LOG=err
+getargbool 0 rd.udev.info -d -y rdudevinfo && UDEV_LOG=info
+getargbool 0 rd.udev.debug -d -y rdudevdebug && UDEV_LOG=debug
+
+# start up udev and trigger cold plugs
+UDEV_LOG=$UDEV_LOG "$systemdutildir"/systemd-udevd --daemon --resolve-names=never
+
+UDEV_QUEUE_EMPTY="udevadm settle --timeout=0"
+
+udevproperty "hookdir=$hookdir"
+
+make_trace_mem "hook pre-trigger" '1:shortmem' '2+:mem' '3+:slab'
+getarg 'rd.break=pre-trigger' -d 'rdbreak=pre-trigger' && emergency_shell -n pre-trigger "Break before pre-trigger"
+source_hook pre-trigger
+
+udevadm control --reload > /dev/null 2>&1 || :
+# then the rest
+udevadm trigger --type=subsystems --action=add > /dev/null 2>&1
+udevadm trigger --type=devices --action=add > /dev/null 2>&1
+
+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
+
+ udevsettle
+
+ 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
+ # shellcheck disable=SC2097 disable=SC1090 disable=SC2098
+ job=$job . "$job"
+ check_finished && break 2
+ done
+
+ $UDEV_QUEUE_EMPTY > /dev/null 2>&1 || continue
+
+ for job in "$hookdir"/initqueue/settled/*.sh; do
+ [ -e "$job" ] || break
+ # shellcheck disable=SC2097 disable=SC1090 disable=SC2098
+ job=$job . "$job"
+ check_finished && break 2
+ done
+
+ $UDEV_QUEUE_EMPTY > /dev/null 2>&1 || continue
+
+ # no more udev jobs and queues empty.
+ sleep 0.5
+
+ if [ $main_loop -gt $((2 * RDRETRY / 3)) ]; then
+ for job in "$hookdir"/initqueue/timeout/*.sh; do
+ [ -e "$job" ] || break
+ # shellcheck disable=SC2097 disable=SC1090 disable=SC2098
+ job=$job . "$job"
+ udevadm settle --timeout=0 > /dev/null 2>&1 || main_loop=0
+ [ -f "$hookdir"/initqueue/work ] && main_loop=0
+ done
+ fi
+
+ main_loop=$((main_loop + 1))
+ [ $main_loop -gt $RDRETRY ] \
+ && {
+ flock -s 9
+ emergency_shell "Could not boot."
+ } 9> /.console_lock
+done
+unset job
+unset queuetriggered
+unset main_loop
+unset RDRETRY
+
+# pre-mount happens before we try to mount the root filesystem,
+# and happens once.
+make_trace_mem "hook pre-mount" '1:shortmem' '2+:mem' '3+:slab'
+getarg 'rd.break=pre-mount' -d 'rdbreak=pre-mount' && emergency_shell -n pre-mount "Break before pre-mount"
+source_hook pre-mount
+
+getarg 'rd.break=mount' -d 'rdbreak=mount' && emergency_shell -n mount "Break before mount"
+# mount scripts actually try to mount the root filesystem, and may
+# be sourced any number of times. As soon as one succeeds, no more are sourced.
+_i_mount=0
+while :; do
+ if ismounted "$NEWROOT"; then
+ usable_root "$NEWROOT" && break
+ umount "$NEWROOT"
+ fi
+ for f in "$hookdir"/mount/*.sh; do
+ # shellcheck disable=SC1090
+ [ -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_mount=$((_i_mount + 1))
+ [ $_i_mount -gt 20 ] \
+ && {
+ flock -s 9
+ emergency_shell "Can't mount root filesystem"
+ } 9> /.console_lock
+done
+
+{
+ printf "Mounted root filesystem "
+ while read -r dev mp _ || [ -n "$dev" ]; do [ "$mp" = "$NEWROOT" ] && echo "$dev"; done < /proc/mounts
+} | vinfo
+
+# pre pivot scripts are sourced just before we doing cleanup and switch over
+# to the new root.
+make_trace_mem "hook pre-pivot" '1:shortmem' '2+:mem' '3+:slab'
+getarg 'rd.break=pre-pivot' -d 'rdbreak=pre-pivot' && emergency_shell -n pre-pivot "Break before pre-pivot"
+source_hook pre-pivot
+
+make_trace_mem "hook cleanup" '1:shortmem' '2+:mem' '3+:slab'
+# pre pivot cleanup scripts are sourced just before we switch over to the new root.
+getarg 'rd.break=cleanup' -d 'rdbreak=cleanup' && emergency_shell -n cleanup "Break before cleanup"
+source_hook cleanup
+
+# By the time we get here, the root filesystem should be mounted.
+# Try to find init.
+for i in "$(getarg real_init=)" "$(getarg init=)" $(getargs rd.distroinit=) /sbin/init; do
+ [ -n "$i" ] || continue
+
+ __p="${NEWROOT}/${i}"
+ if [ -h "$__p" ]; then
+ # relative links need to be left alone,
+ # while absolute links need to be resolved and prefixed.
+ __pt=$(readlink "$__p")
+ [ "${__pt#/}" = "$__pt" ] || __p="${NEWROOT}/$__pt"
+ fi
+ if [ -x "$__p" ]; then
+ INIT="$i"
+ break
+ fi
+done
+
+[ "$INIT" ] || {
+ echo "Cannot find init!"
+ echo "Please check to make sure you passed a valid root filesystem!"
+ emergency_shell
+}
+
+udevadm control --exit
+udevadm info --cleanup-db
+
+debug_off # Turn off debugging for this section
+
+CAPSH=$(command -v capsh)
+SWITCH_ROOT=$(command -v switch_root)
+
+# unexport some vars
+export_n root rflags fstype netroot NEWROOT
+unset CMDLINE
+
+# Clean up the environment
+for i in $(export -p); do
+ i=${i#declare -x}
+ i=${i#export}
+ strstr "$i" "=" || continue
+ i=${i%%=*}
+ [ -z "$i" ] && continue
+ case $i in
+ root | PATH | HOME | TERM | PS4 | RD_*)
+ :
+ ;;
+ *)
+ unset "$i"
+ ;;
+ esac
+done
+. /tmp/export.orig 2> /dev/null || :
+rm -f -- /tmp/export.orig
+
+initargs=""
+read -r CLINE < /proc/cmdline
+if getarg init= > /dev/null; then
+ ignoreargs="console BOOT_IMAGE"
+ # only pass arguments after init= to the init
+ CLINE=${CLINE#*init=}
+ # shellcheck disable=SC2086
+ set -- $CLINE
+ shift # clear out the rest of the "init=" arg
+ for x in "$@"; do
+ for s in $ignoreargs; do
+ [ "${x%%=*}" = "$s" ] && continue 2
+ done
+ initargs="$initargs $x"
+ done
+ unset CLINE
+else
+ debug_off # Turn off debugging for this section
+ # shellcheck disable=SC2086
+ set -- $CLINE
+ for x in "$@"; do
+ case "$x" in
+ [0-9] | s | S | single | emergency | auto)
+ initargs="$initargs $x"
+ ;;
+ esac
+ done
+fi
+debug_on
+
+if ! [ -d "$NEWROOT"/run ]; then
+ NEWRUN=/dev/.initramfs
+ mkdir -m 0755 -p "$NEWRUN"
+ mount --rbind /run/initramfs "$NEWRUN"
+fi
+
+wait_for_loginit
+
+# remove helper symlink
+[ -h /dev/root ] && rm -f -- /dev/root
+
+bv=$(getarg rd.break -d rdbreak) && [ -z "$bv" ] \
+ && emergency_shell -n switch_root "Break before switch_root"
+unset bv
+info "Switching root"
+
+unset PS4
+
+PATH=$OLDPATH
+export PATH
+
+if [ -f /etc/capsdrop ]; then
+ . /etc/capsdrop
+ info "Calling $INIT with capabilities $CAPS_INIT_DROP dropped."
+ unset RD_DEBUG
+ exec "$CAPSH" --drop="$CAPS_INIT_DROP" -- \
+ -c "exec \"$SWITCH_ROOT\" \"$NEWROOT\" \"$INIT\" $initargs" \
+ || {
+ warn "Command:"
+ warn capsh --drop="$CAPS_INIT_DROP" -- -c exec "$SWITCH_ROOT" "$NEWROOT" "$INIT" "$initargs"
+ warn "failed."
+ emergency_shell
+ }
+else
+ unset RD_DEBUG
+ # shellcheck disable=SC2086
+ exec "$SWITCH_ROOT" "$NEWROOT" "$INIT" $initargs || {
+ warn "Something went very badly wrong in the initramfs. Please "
+ warn "file a bug against dracut."
+ emergency_shell
+ }
+fi
diff --git a/modules.d/99base/initqueue.sh b/modules.d/99base/initqueue.sh
new file mode 100755
index 0000000..2c49079
--- /dev/null
+++ b/modules.d/99base/initqueue.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+#
+# Licensed under the GPLv2+
+#
+# Copyright 2008-2010, Red Hat, Inc.
+# Harald Hoyer <harald@redhat.com>
+
+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
+
+{
+ # shellcheck disable=SC2016
+ [ -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
diff --git a/modules.d/99base/loginit.sh b/modules.d/99base/loginit.sh
new file mode 100755
index 0000000..cdb305b
--- /dev/null
+++ b/modules.d/99base/loginit.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# turn off debugging
+set +x
+
+QUIET=$1
+
+printf "%s" "$$" > /run/initramfs/loginit.pid
+
+# shellcheck disable=SC2015
+[ -e /dev/kmsg ] && exec 5> /dev/kmsg || exec 5> /dev/null
+exec 6> /run/initramfs/init.log
+
+while read -r line || [ -n "$line" ]; do
+ if [ "$line" = "DRACUT_LOG_END" ]; then
+ rm -f -- /run/initramfs/loginit.pipe
+ exit 0
+ fi
+ echo "<31>dracut: $line" >&5
+ # if "quiet" is specified we output to /dev/console
+ [ -n "$QUIET" ] || echo "dracut: $line"
+ echo "$line" >&6
+done
diff --git a/modules.d/99base/module-setup.sh b/modules.d/99base/module-setup.sh
new file mode 100755
index 0000000..54b0deb
--- /dev/null
+++ b/modules.d/99base/module-setup.sh
@@ -0,0 +1,146 @@
+#!/bin/bash
+
+# called by dracut
+check() {
+ return 0
+}
+
+# called by dracut
+depends() {
+ echo udev-rules
+ return 0
+}
+
+# called by dracut
+install() {
+ inst_multiple mount mknod mkdir sleep chown \
+ sed ls flock cp mv dmesg rm ln rmmod mkfifo umount readlink setsid \
+ modprobe chmod tr
+
+ inst_multiple -o findmnt less kmod
+
+ inst_binary "${dracutbasedir}/dracut-util" "/usr/bin/dracut-util"
+
+ ln -s dracut-util "${initdir}/usr/bin/dracut-getarg"
+ ln -s dracut-util "${initdir}/usr/bin/dracut-getargs"
+
+ if [ ! -e "${initdir}/bin/sh" ]; then
+ inst_multiple bash
+ (ln -s bash "${initdir}/bin/sh" || :)
+ fi
+
+ # add common users in /etc/passwd, it will be used by nfs/ssh currently
+ # use password for hostonly images to facilitate secure sulogin in emergency console
+ [[ $hostonly ]] && pwshadow='x'
+ grep '^root:' "$initdir/etc/passwd" > /dev/null 2>&1 || echo "root:$pwshadow:0:0::/root:/bin/sh" >> "$initdir/etc/passwd"
+ grep '^nobody:' "$dracutsysrootdir"/etc/passwd >> "$initdir/etc/passwd"
+
+ [[ $hostonly ]] && grep '^root:' "$dracutsysrootdir"/etc/shadow >> "$initdir/etc/shadow"
+
+ # install our scripts and hooks
+ inst_script "$moddir/init.sh" "/init"
+ inst_script "$moddir/initqueue.sh" "/sbin/initqueue"
+ inst_script "$moddir/loginit.sh" "/sbin/loginit"
+ inst_script "$moddir/rdsosreport.sh" "/sbin/rdsosreport"
+
+ [ -e "${initdir}/lib" ] || mkdir -m 0755 -p "${initdir}"/lib
+ mkdir -m 0755 -p "${initdir}"/lib/dracut
+ mkdir -m 0755 -p "${initdir}"/lib/dracut/hooks
+
+ mkdir -p "${initdir}"/tmp
+
+ inst_simple "$moddir/dracut-lib.sh" "/lib/dracut-lib.sh"
+ inst_simple "$moddir/dracut-dev-lib.sh" "/lib/dracut-dev-lib.sh"
+ mkdir -p "${initdir}"/var
+
+ if ! dracut_module_included "systemd"; then
+ inst_multiple switch_root || dfatal "Failed to install switch_root"
+ inst_hook cmdline 10 "$moddir/parse-root-opts.sh"
+ fi
+
+ if [[ $realinitpath ]]; then
+ for i in $realinitpath; do
+ echo "rd.distroinit=$i"
+ done > "${initdir}/etc/cmdline.d/distroinit.conf"
+ fi
+
+ ln -fs /proc/self/mounts "$initdir/etc/mtab"
+ if [[ $ro_mnt == yes ]]; then
+ echo ro >> "${initdir}/etc/cmdline.d/base.conf"
+ fi
+
+ [ -e "${initdir}/usr/lib" ] || mkdir -m 0755 -p "${initdir}"/usr/lib
+
+ local VERSION=""
+ local PRETTY_NAME=""
+ # Derive an os-release file from the host, if it exists
+ if [[ -e $dracutsysrootdir/etc/os-release ]]; then
+ # shellcheck disable=SC1090
+ . "$dracutsysrootdir"/etc/os-release
+ grep -hE -ve '^VERSION=' -ve '^PRETTY_NAME' "$dracutsysrootdir"/etc/os-release > "${initdir}"/usr/lib/initrd-release
+ [[ -n ${VERSION} ]] && VERSION+=" "
+ [[ -n ${PRETTY_NAME} ]] && PRETTY_NAME+=" "
+ else
+ # Fall back to synthesizing one, since dracut is presently used
+ # on non-systemd systems as well.
+ {
+ echo "NAME=dracut"
+ echo "ID=dracut"
+ echo "VERSION_ID=\"$DRACUT_VERSION\""
+ echo 'ANSI_COLOR="0;34"'
+ } > "${initdir}"/usr/lib/initrd-release
+ fi
+ VERSION+="dracut-$DRACUT_VERSION"
+ PRETTY_NAME+="dracut-$DRACUT_VERSION (Initramfs)"
+ {
+ echo "VERSION=\"$VERSION\""
+ echo "PRETTY_NAME=\"$PRETTY_NAME\""
+ # This addition is relatively new, intended to allow software
+ # to easily detect the dracut version if need be without
+ # having it mixed in with the real underlying OS version.
+ echo "DRACUT_VERSION=\"${DRACUT_VERSION}\""
+ } >> "$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
+
+ ## save host_devs which we need bring up
+ if [[ $hostonly_cmdline == "yes" ]]; then
+ if [[ -n ${host_devs[*]} ]]; then
+ dracut_need_initqueue
+ fi
+ if [[ -f $initdir/lib/dracut/need-initqueue ]] || ! dracut_module_included "systemd"; then
+ (
+ if dracut_module_included "systemd"; then
+ export DRACUT_SYSTEMD=1
+ fi
+ export PREFIX="$initdir"
+ export hookdir=/lib/dracut/hooks
+
+ # shellcheck source=dracut-dev-lib.sh
+ . "$moddir/dracut-dev-lib.sh"
+
+ for _dev in "${host_devs[@]}"; do
+ for _dev2 in "${root_devs[@]}"; do
+ [[ $_dev == "$_dev2" ]] && continue 2
+ done
+
+ # We only actually wait for real devs - swap is only needed
+ # for resume and udev rules generated when parsing resume=
+ # argument take care of the waiting for us
+ for _dev2 in "${swap_devs[@]}"; do
+ [[ $_dev == "$_dev2" ]] && continue 2
+ done
+
+ _pdev=$(get_persistent_dev "$_dev")
+
+ case "$_pdev" in
+ /dev/?*) wait_for_dev "$_pdev" 0 ;;
+ *) ;;
+ esac
+ done
+ )
+ fi
+ fi
+}
diff --git a/modules.d/99base/parse-root-opts.sh b/modules.d/99base/parse-root-opts.sh
new file mode 100755
index 0000000..9525249
--- /dev/null
+++ b/modules.d/99base/parse-root-opts.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+# shellcheck disable=SC2034
+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
diff --git a/modules.d/99base/rdsosreport.sh b/modules.d/99base/rdsosreport.sh
new file mode 100755
index 0000000..dadf30b
--- /dev/null
+++ b/modules.d/99base/rdsosreport.sh
@@ -0,0 +1,61 @@
+#!/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-*
+
+echo "/proc/cmdline"
+sed -e "$PWFILTER" /proc/cmdline
+
+if [ -f /etc/cmdline ]; then
+ echo "/etc/cmdline"
+ sed -e "$PWFILTER" /etc/cmdline
+fi
+
+for _i in /etc/cmdline.d/*.conf; do
+ [ -f "$_i" ] || break
+ echo "$_i"
+ sed -e "$PWFILTER" "$_i"
+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"
+ sed -e "$PWFILTER" "$_i"
+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"
+ if [ -f /run/initramfs/init.log ]; then
+ echo "/run/initramfs/init.log"
+ sed -e "$PWFILTER" /run/initramfs/init.log
+ fi
+fi