]> git.ipfire.org Git - thirdparty/dracut.git/blobdiff - dracut.sh
test: use hosts randomness, not rngd
[thirdparty/dracut.git] / dracut.sh
index 81e1562ddd46bb5a5eb5ca657211ee4801811a7a..06c751dce09d6b64f59c8fc1c199914f1a926edb 100755 (executable)
--- a/dracut.sh
+++ b/dracut.sh
@@ -1,4 +1,4 @@
-#!/bin/bash --norc
+#!/bin/bash -p
 #
 # Generator script for a dracut initramfs
 # Tries to retain some degree of compatibility with the command line
@@ -23,6 +23,8 @@
 
 # store for logging
 
+unset BASH_ENV
+
 # Verify bash version, current minimum is 4
 if (( BASH_VERSINFO[0] < 4 )); then
     printf -- 'You need at least Bash 4 to use dracut, sorry.' >&2
@@ -35,7 +37,8 @@ readonly dracut_cmd="$(readlink -f $0)"
 set -o pipefail
 
 usage() {
-    [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
+       [[ $sysroot_l ]] && dracutsysrootdir="$sysroot_l"
+    [[ $dracutbasedir ]] || dracutbasedir=$dracutsysrootdir/usr/lib/dracut
     if [[ -f $dracutbasedir/dracut-version.sh ]]; then
         . $dracutbasedir/dracut-version.sh
     fi
@@ -60,7 +63,7 @@ EOF
 }
 
 long_usage() {
-    [[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
+    [[ $dracutbasedir ]] || dracutbasedir=$dracutsysrootdir/usr/lib/dracut
     if [[ -f $dracutbasedir/dracut-version.sh ]]; then
         . $dracutbasedir/dracut-version.sh
     fi
@@ -108,8 +111,6 @@ Creates initial ramdisk images for preloading modules
   --kernel-cmdline [PARAMETERS] Specify default kernel command line parameters
   --strip               Strip binaries in the initramfs
   --nostrip             Do not strip binaries in the initramfs
-  --prelink             Prelink binaries in the initramfs
-  --noprelink           Do not prelink binaries in the initramfs
   --hardlink            Hardlink files in the initramfs
   --nohardlink          Do not hardlink files in the initramfs
   --prefix [DIR]        Prefix initramfs files with [DIR]
@@ -140,6 +141,7 @@ Creates initial ramdisk images for preloading modules
                          from. Default: /etc/dracut.conf.d
   --tmpdir [DIR]        Temporary directory to be used instead of default
                          /var/tmp.
+  -r, --sysroot [DIR]   Specify sysroot directory to collect files from.
   -l, --local           Local mode. Use modules from the current working
                          directory instead of the system-wide installed in
                          /usr/lib/dracut/modules.d.
@@ -147,10 +149,29 @@ Creates initial ramdisk images for preloading modules
   -H, --hostonly        Host-Only mode: Install only what is needed for
                         booting the local host instead of a generic host.
   -N, --no-hostonly     Disables Host-Only mode
+  --hostonly-mode <mode>
+                        Specify the hostonly mode to use. <mode> could be
+                        one of "sloppy" or "strict". "sloppy" mode is used
+                        by default.
+                        In "sloppy" hostonly mode, extra drivers and modules
+                        will be installed, so minor hardware change won't make
+                        the image unbootable (eg. changed keyboard), and the
+                        image is still portable among similar hosts.
+                        With "strict" mode enabled, anything not necessary
+                        for booting the local host in its current state will
+                        not be included, and modules may do some extra job
+                        to save more space. Minor change of hardware or
+                        environment could make the image unbootable.
+                        DO NOT use "strict" mode unless you know what you
+                        are doing.
   --hostonly-cmdline    Store kernel command line arguments needed
                         in the initramfs
   --no-hostonly-cmdline Do not store kernel command line arguments needed
                         in the initramfs
+  --no-hostonly-default-device
+                        Do not generate implicit host devices like root,
+                        swap, fstab, etc. Use "--mount" or "--add-device"
+                        to explicitly add devices as needed.
   --hostonly-i18n       Install only needed keyboard and font files according
                         to the host configuration (default).
   --no-hostonly-i18n    Install all keyboard and font files available.
@@ -193,6 +214,9 @@ Creates initial ramdisk images for preloading modules
   --lz4                 Compress the generated initramfs using lz4.
                          Make sure that your kernel has lz4 support compiled
                          in, otherwise you will not be able to boot.
+  --zstd                Compress the generated initramfs using Zstandard.
+                         Make sure that your kernel has zstd support compiled
+                         in, otherwise you will not be able to boot.
   --compress [COMPRESSION] Compress the generated initramfs with the
                          passed compression program.  Make sure your kernel
                          knows how to decompress the generated initramfs,
@@ -279,14 +303,18 @@ dropindirs_sort()
 rearrange_params()
 {
     # Workaround -i, --include taking 2 arguments
-    set -- "${@/--include/++include}"
-
-    # This prevents any long argument ending with "-i"
-    # -i, like --opt-i but I think we can just prevent that
-    set -- "${@/%-i/++include}"
+    newat=()
+    for i in "$@"; do
+      if [[ $i == "-i" ]] || [[ $i == "--include" ]]; then
+            newat+=("++include") # Replace --include by ++include
+        else
+            newat+=("$i")
+        fi
+    done
+    set -- "${newat[@]}" # Set new $@
 
     TEMP=$(unset POSIXLY_CORRECT; getopt \
-        -o "a:m:o:d:I:k:c:L:fvqlHhMN" \
+        -o "a:m:o:d:I:k:c:r:L:fvqlHhMN" \
         --long kver: \
         --long add: \
         --long force-add: \
@@ -306,12 +334,13 @@ rearrange_params()
         --long mount: \
         --long device: \
         --long add-device: \
-        --long nofscks: \
+        --long nofscks \
         --long ro-mnt \
         --long kmoddir: \
         --long conf: \
         --long confdir: \
         --long tmpdir: \
+        --long sysroot: \
         --long stdlog: \
         --long compress: \
         --long prefix: \
@@ -323,8 +352,6 @@ rearrange_params()
         --long kernel-cmdline: \
         --long strip \
         --long nostrip \
-        --long prelink \
-        --long noprelink \
         --long hardlink \
         --long nohardlink \
         --long noprefix \
@@ -343,8 +370,10 @@ rearrange_params()
         --long host-only \
         --long no-hostonly \
         --long no-host-only \
+        --long hostonly-mode: \
         --long hostonly-cmdline \
         --long no-hostonly-cmdline \
+        --long no-hostonly-default-device \
         --long persistent-policy: \
         --long fstab \
         --long help \
@@ -353,6 +382,7 @@ rearrange_params()
         --long xz \
         --long lzo \
         --long lz4 \
+        --long zstd \
         --long no-compress \
         --long gzip \
         --long list-modules \
@@ -447,9 +477,6 @@ if [[ $append_args_l == "yes" ]]; then
         eval set -- "$TEMP"
         rearrange_params "$@"
     fi
-
-    # clean the temporarily used scratch-pad directory
-    rm -rf $scratch_dir
 fi
 
 unset PARMS_TO_STORE
@@ -487,6 +514,7 @@ while :; do
         -c|--conf)     conffile="$2";                  PARMS_TO_STORE+=" '$2'"; shift;;
         --confdir)     confdir="$2";                   PARMS_TO_STORE+=" '$2'"; shift;;
         --tmpdir)      tmpdir_l="$2";                  PARMS_TO_STORE+=" '$2'"; shift;;
+        -r|--sysroot)  sysroot_l="$2";                 PARMS_TO_STORE+=" '$2'"; shift;;
         -L|--stdlog)   stdloglvl_l="$2";               PARMS_TO_STORE+=" '$2'"; shift;;
         --compress)    compress_l="$2";                PARMS_TO_STORE+=" '$2'"; shift;;
         --prefix)      prefix_l="$2";                  PARMS_TO_STORE+=" '$2'"; shift;;
@@ -507,8 +535,6 @@ while :; do
                        early_microcode_l="no";;
         --strip)       do_strip_l="yes";;
         --nostrip)     do_strip_l="no";;
-        --prelink)     do_prelink_l="yes";;
-        --noprelink)   do_prelink_l="no";;
         --hardlink)    do_hardlink_l="yes";;
         --nohardlink)  do_hardlink_l="no";;
         --noprefix)    prefix_l="/";;
@@ -531,6 +557,8 @@ while :; do
                        hostonly_l="yes" ;;
         -N|--no-hostonly|--no-host-only)
                        hostonly_l="no" ;;
+        --hostonly-mode)
+                       hostonly_mode_l="$2";           PARMS_TO_STORE+=" '$2'"; shift;;
         --hostonly-cmdline)
                        hostonly_cmdline_l="yes" ;;
         --hostonly-i18n)
@@ -539,6 +567,8 @@ while :; do
                        i18n_install_all_l="yes" ;;
         --no-hostonly-cmdline)
                        hostonly_cmdline_l="no" ;;
+        --no-hostonly-default-device)
+                       hostonly_default_device="no" ;;
         --persistent-policy)
                        persistent_policy_l="$2";       PARMS_TO_STORE+=" '$2'"; shift;;
         --fstab)       use_fstab_l="yes" ;;
@@ -550,6 +580,7 @@ while :; do
         --xz)          compress_l="xz";;
         --lzo)         compress_l="lzo";;
         --lz4)         compress_l="lz4";;
+        --zstd)        compress_l="zstd";;
         --no-compress) _no_compress_l="cat";;
         --gzip)        compress_l="gzip";;
         --list-modules) do_list="yes";;
@@ -590,6 +621,8 @@ while (($# > 0)); do
     shift
 done
 
+[[ $sysroot_l ]] && dracutsysrootdir="$sysroot_l"
+
 if [[ $regenerate_all == "yes" ]]; then
     ret=0
     if [[ $kernel ]]; then
@@ -608,7 +641,7 @@ if [[ $regenerate_all == "yes" ]]; then
             unset dracut_args[$i]
     done
 
-    cd /lib/modules
+    cd $dracutsysrootdir/lib/modules
     for i in *; do
         [[ -f $i/modules.dep ]] || [[ -f $i/modules.dep.bin ]] || continue
         "$dracut_cmd" --kver="$i" "${dracut_args[@]}"
@@ -642,14 +675,14 @@ export DRACUT_LOG_LEVEL=warning
     debug=yes
 }
 
-[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
+[[ $dracutbasedir ]] || dracutbasedir=$dracutsysrootdir/usr/lib/dracut
 
 # if we were not passed a config file, try the default one
 if [[ ! -f $conffile ]]; then
     if [[ $allowlocal ]]; then
         conffile="$dracutbasedir/dracut.conf"
     else
-        conffile="/etc/dracut.conf"
+        conffile="$dracutsysrootdir/etc/dracut.conf"
     fi
 fi
 
@@ -657,7 +690,7 @@ if [[ ! -d $confdir ]]; then
     if [[ $allowlocal ]]; then
         confdir="$dracutbasedir/dracut.conf.d"
     else
-        confdir="/etc/dracut.conf.d"
+        confdir="$dracutsysrootdir/etc/dracut.conf.d"
     fi
 fi
 
@@ -673,8 +706,8 @@ DRACUT_PATH=${DRACUT_PATH:-/sbin /bin /usr/sbin /usr/bin}
 
 for i in $DRACUT_PATH; do
     rl=$i
-    if [ -L "$i" ]; then
-        rl=$(readlink -f $i)
+    if [ -L "$dracutsysrootdir$i" ]; then
+        rl=$(readlink -f $dracutsysrootdir$i)
     fi
     if [[ "$NPATH" != *:$rl* ]] ; then
         NPATH+=":$rl"
@@ -708,31 +741,30 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
 [[ $drivers_dir_l ]] && drivers_dir=$drivers_dir_l
 [[ $do_strip_l ]] && do_strip=$do_strip_l
 [[ $do_strip ]] || do_strip=yes
-[[ $do_prelink_l ]] && do_prelink=$do_prelink_l
-[[ $do_prelink ]] || do_prelink=yes
 [[ $do_hardlink_l ]] && do_hardlink=$do_hardlink_l
 [[ $do_hardlink ]] || do_hardlink=yes
 [[ $prefix_l ]] && prefix=$prefix_l
 [[ $prefix = "/" ]] && unset prefix
 [[ $hostonly_l ]] && hostonly=$hostonly_l
 [[ $hostonly_cmdline_l ]] && hostonly_cmdline=$hostonly_cmdline_l
+[[ $hostonly_mode_l ]] && hostonly_mode=$hostonly_mode_l
 [[ "$hostonly" == "yes" ]] && ! [[ $hostonly_cmdline ]] && hostonly_cmdline="yes"
 [[ $i18n_install_all_l ]] && i18n_install_all=$i18n_install_all_l
 [[ $persistent_policy_l ]] && persistent_policy=$persistent_policy_l
 [[ $use_fstab_l ]] && use_fstab=$use_fstab_l
 [[ $mdadmconf_l ]] && mdadmconf=$mdadmconf_l
 [[ $lvmconf_l ]] && lvmconf=$lvmconf_l
-[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut
-[[ $fw_dir ]] || fw_dir="/lib/firmware/updates:/lib/firmware:/lib/firmware/$kernel"
+[[ $dracutbasedir ]] || dracutbasedir=$dracutsysrootdir/usr/lib/dracut
+[[ $fw_dir ]] || fw_dir="$dracutsysrootdir/lib/firmware/updates:$dracutsysrootdir/lib/firmware:$dracutsysrootdir/lib/firmware/$kernel"
 [[ $tmpdir_l ]] && tmpdir="$tmpdir_l"
-[[ $tmpdir ]] || tmpdir=/var/tmp
+[[ $tmpdir ]] || tmpdir=$dracutsysrootdir/var/tmp
 [[ $INITRD_COMPRESS ]] && compress=$INITRD_COMPRESS
 [[ $compress_l ]] && compress=$compress_l
 [[ $show_modules_l ]] && show_modules=$show_modules_l
 [[ $nofscks_l ]] && nofscks="yes"
 [[ $ro_mnt_l ]] && ro_mnt="yes"
 [[ $early_microcode_l ]] && early_microcode=$early_microcode_l
-[[ $early_microcode ]] || early_microcode=no
+[[ $early_microcode ]] || early_microcode=yes
 [[ $logfile_l ]] && logfile="$logfile_l"
 [[ $reproducible_l ]] && reproducible="$reproducible_l"
 [[ $loginstall_l ]] && loginstall="$loginstall_l"
@@ -742,29 +774,48 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
 
 if ! [[ $outfile ]]; then
     if [[ $machine_id != "no" ]]; then
-        [[ -f /etc/machine-id ]] && read MACHINE_ID < /etc/machine-id
+        [[ -f $dracutsysrootdir/etc/machine-id ]] && read MACHINE_ID < $dracutsysrootdir/etc/machine-id
     fi
 
     if [[ $uefi == "yes" ]]; then
-        BUILD_ID=$(cat /etc/os-release /usr/lib/os-release \
+        if [[ -n "$uefi_secureboot_key" && -z "$uefi_secureboot_cert" ]] || [[ -z $uefi_secureboot_key && -n $uefi_secureboot_cert ]]; then
+            dfatal "Need 'uefi_secureboot_key' and 'uefi_secureboot_cert' both to be set."
+            exit 1
+        fi
+
+        if [[ -n "$uefi_secureboot_key" && -n "$uefi_secureboot_cert" ]] && !command -v sbsign &>/dev/null; then
+            dfatal "Need 'sbsign' to create a signed UEFI executable"
+            exit 1
+        fi
+
+        BUILD_ID=$(cat $dracutsysrootdir/etc/os-release $dracutsysrootdir/usr/lib/os-release \
                        | while read -r line || [[ $line ]]; do \
                        [[ $line =~ BUILD_ID\=* ]] && eval "$line" && echo "$BUILD_ID" && break; \
                    done)
-        if [[ -d /efi ]] && mountpoint -q /efi; then
-            efidir=/efi
+        if [[ -z $dracutsysrootdir ]]; then
+            if [[ -d /efi ]] && mountpoint -q /efi; then
+                efidir=/efi/EFI
+            else
+                efidir=/boot/EFI
+                if [[ -d $dracutsysrootdir/boot/efi/EFI ]]; then
+                    efidir=/boot/efi/EFI
+                fi
+            fi
         else
             efidir=/boot/EFI
-            if [[ -d /boot/efi/EFI ]] && mountpoint -q /boot/efi; then
+            if [[ -d $dracutsysrootdir/boot/efi/EFI ]]; then
                 efidir=/boot/efi/EFI
             fi
         fi
-        mkdir -p "$efidir/Linux"
-        outfile="$efidir/Linux/linux-$kernel${MACHINE_ID:+-${MACHINE_ID}}${BUILD_ID:+-${BUILD_ID}}.efi"
+        mkdir -p "$dracutsysrootdir$efidir/Linux"
+        outfile="$dracutsysrootdir$efidir/Linux/linux-$kernel${MACHINE_ID:+-${MACHINE_ID}}${BUILD_ID:+-${BUILD_ID}}.efi"
     else
-        if [[ $MACHINE_ID ]] && ( [[ -d /boot/${MACHINE_ID} ]] || [[ -L /boot/${MACHINE_ID} ]] ); then
-            outfile="/boot/${MACHINE_ID}/$kernel/initrd"
-        else
+        if [[ -e "$dracutsysrootdir/boot/vmlinuz-$kernel" ]]; then
             outfile="/boot/initramfs-$kernel.img"
+        elif [[ $MACHINE_ID ]] && ( [[ -d $dracutsysrootdir/boot/${MACHINE_ID} ]] || [[ -L $dracutsysrootdir/boot/${MACHINE_ID} ]] ); then
+            outfile="$dracutsysrootdir/boot/${MACHINE_ID}/$kernel/initrd"
+        else
+            outfile="$dracutsysrootdir/boot/initramfs-$kernel.img"
         fi
     fi
 fi
@@ -784,13 +835,24 @@ if [[ -n "$logfile" ]];then
 fi
 
 # handle compression options.
-if [[ $_no_compress_l = "cat" ]]; then
-    compress="cat"
+DRACUT_COMPRESS_BZIP2=${DRACUT_COMPRESS_BZIP2:-bzip2}
+DRACUT_COMPRESS_LBZIP2=${DRACUT_COMPRESS_LBZIP2:-lbzip2}
+DRACUT_COMPRESS_LZMA=${DRACUT_COMPRESS_LZMA:-lzma}
+DRACUT_COMPRESS_XZ=${DRACUT_COMPRESS_XZ:-xz}
+DRACUT_COMPRESS_GZIP=${DRACUT_COMPRESS_GZIP:-gzip}
+DRACUT_COMPRESS_PIGZ=${DRACUT_COMPRESS_PIGZ:-pigz}
+DRACUT_COMPRESS_LZOP=${DRACUT_COMPRESS_LZOP:-lzop}
+DRACUT_COMPRESS_ZSTD=${DRACUT_COMPRESS_ZSTD:-zstd}
+DRACUT_COMPRESS_LZ4=${DRACUT_COMPRESS_LZ4:-lz4}
+DRACUT_COMPRESS_CAT=${DRACUT_COMPRESS_CAT:-cat}
+
+if [[ $_no_compress_l = "$DRACUT_COMPRESS_CAT" ]]; then
+    compress="$DRACUT_COMPRESS_CAT"
 fi
 
 if ! [[ $compress ]]; then
     # check all known compressors, if none specified
-    for i in pigz gzip lz4 lzop lzma xz lbzip2 bzip2 cat; do
+    for i in $DRACUT_COMPRESS_PIGZ $DRACUT_COMPRESS_GZIP $DRACUT_COMPRESS_LZ4 $DRACUT_COMPRESS_LZOP $ $DRACUT_COMPRESS_ZSTD $DRACUT_COMPRESS_LZMA $DRACUT_COMPRESS_XZ $DRACUT_COMPRESS_LBZIP2 $OMPRESS_BZIP2 $DRACUT_COMPRESS_CAT; do
         command -v "$i" &>/dev/null || continue
         compress="$i"
         break
@@ -803,38 +865,54 @@ fi
 # choose the right arguments for the compressor
 case $compress in
     bzip2|lbzip2)
-        if [[ "$compress" =  lbzip2 ]] || command -v lbzip2 &>/dev/null; then
-            compress="lbzip2 -9"
+        if [[ "$compress" =  lbzip2 ]] || command -v $DRACUT_COMPRESS_LBZIP2 &>/dev/null; then
+            compress="$DRACUT_COMPRESS_LBZIP2 -9"
         else
-            compress="bzip2 -9"
+            compress="$DRACUT_COMPRESS_BZIP2 -9"
         fi
         ;;
     lzma)
-        compress="lzma -9 -T0"
+        compress="$DRACUT_COMPRESS_LZMA -9 -T0"
         ;;
     xz)
-        compress="xz --check=crc32 --lzma2=dict=1MiB -T0"
+        compress="$DRACUT_COMPRESS_XZ --check=crc32 --lzma2=dict=1MiB -T0"
         ;;
     gzip|pigz)
-        if [[ "$compress" = pigz ]] || command -v pigz &>/dev/null; then
-            compress="pigz -9 -n -T -R"
-        elif command -v gzip &>/dev/null && gzip --help 2>&1 | grep -q rsyncable; then
-            compress="gzip -n -9 --rsyncable"
+        if [[ "$compress" = pigz ]] || command -v $DRACUT_COMPRESS_PIGZ &>/dev/null; then
+            compress="$DRACUT_COMPRESS_PIGZ -9 -n -T -R"
+        elif command -v gzip &>/dev/null && $DRACUT_COMPRESS_GZIP --help 2>&1 | grep -q rsyncable; then
+            compress="$DRACUT_COMPRESS_GZIP -n -9 --rsyncable"
         else
-            compress="gzip -n -9"
+            compress="$DRACUT_COMPRESS_GZIP -n -9"
         fi
         ;;
     lzo|lzop)
-        compress="lzop -9"
+        compress="$DRACUT_COMPRESS_LZOP -9"
         ;;
     lz4)
-        compress="lz4 -l -9"
+        compress="$DRACUT_COMPRESS_LZ4 -l -9"
         ;;
+    zstd)
+       compress="$DRACUT_COMPRESS_ZSTD -15 -q -T0"
+       ;;
 esac
 
 [[ $hostonly = yes ]] && hostonly="-h"
 [[ $hostonly != "-h" ]] && unset hostonly
 
+case $hostonly_mode in
+    '')
+        [[ $hostonly ]] && hostonly_mode="sloppy" ;;
+    sloppy|strict)
+        if [[ ! $hostonly ]]; then
+            unset hostonly_mode
+        fi
+        ;;
+    *)
+        printf "%s\n" "dracut: Invalid hostonly mode '$hostonly_mode'." >&2
+        exit 1
+esac
+
 [[ $reproducible == yes ]] && DRACUT_REPRODUCIBLE=1
 
 readonly TMPDIR="$(realpath -e "$tmpdir")"
@@ -866,7 +944,7 @@ if [[ $early_microcode = yes ]] || ( [[ $acpi_override = yes ]] && [[ -d $acpi_t
     mkdir "$early_cpio_dir"
 fi
 
-export DRACUT_RESOLVE_LAZY="1"
+[[ -n "$dracutsysrootdir" ]] || export DRACUT_RESOLVE_LAZY="1"
 
 if [[ $print_cmdline ]]; then
     stdloglvl=0
@@ -895,8 +973,8 @@ if [[ $no_kernel != yes ]] && ! [[ -d $srcmods ]]; then
 fi
 
 if ! [[ $print_cmdline ]]; then
-    inst /bin/sh
-    if ! $DRACUT_INSTALL ${initdir:+-D "$initdir"} -R "$initdir/bin/sh" &>/dev/null; then
+    inst $DRACUT_TESTBIN
+    if ! $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${dracutsysrootdir:+-r "$dracutsysrootdir"} -R "$DRACUT_TESTBIN" &>/dev/null; then
         unset DRACUT_RESOLVE_LAZY
         export DRACUT_RESOLVE_DEPS=1
     fi
@@ -955,6 +1033,16 @@ esac
 
 abs_outfile=$(readlink -f "$outfile") && outfile="$abs_outfile"
 
+
+[[ -d $dracutsysrootdir$systemdutildir ]] \
+    || systemdutildir=$(pkg-config systemd --variable=systemdutildir 2>/dev/null)
+
+if ! [[ -d "$dracutsysrootdir$systemdutildir" ]]; then
+    [[ -e $dracutsysrootdir/lib/systemd/systemd-udevd ]] && systemdutildir=/lib/systemd
+    [[ -e $dracutsysrootdir/usr/lib/systemd/systemd-udevd ]] && systemdutildir=/usr/lib/systemd
+fi
+
+
 if [[ $no_kernel != yes ]] && [[ -d $srcmods ]]; then
     if ! [[ -f $srcmods/modules.dep ]]; then
         if [[ -n "$(find "$srcmods" -name '*.ko*')" ]]; then
@@ -1016,21 +1104,21 @@ if [[ ! $print_cmdline ]]; then
             exit 1
         fi
         unset EFI_MACHINE_TYPE_NAME
-        case $(arch) in
+        case $(uname -m) in
             x86_64)
                 EFI_MACHINE_TYPE_NAME=x64;;
             ia32)
                 EFI_MACHINE_TYPE_NAME=ia32;;
             *)
-                dfatal "Architecture '$(arch)' not supported to create a UEFI executable"
+                dfatal "Architecture '$(uname -m)' not supported to create a UEFI executable"
                 exit 1
                 ;;
         esac
 
         if ! [[ -s $uefi_stub ]]; then
             for uefi_stub in \
-                "${systemdutildir}/boot/efi/linux${EFI_MACHINE_TYPE_NAME}.efi.stub" \
-                    "/usr/lib/gummiboot/linux${EFI_MACHINE_TYPE_NAME}.efi.stub"; do
+                $dracutsysrootdir"${systemdutildir}/boot/efi/linux${EFI_MACHINE_TYPE_NAME}.efi.stub" \
+                    "$dracutsysrootdir/usr/lib/gummiboot/linux${EFI_MACHINE_TYPE_NAME}.efi.stub"; do
                 [[ -s $uefi_stub ]] || continue
                 break
             done
@@ -1041,7 +1129,7 @@ if [[ ! $print_cmdline ]]; then
         fi
 
         if ! [[ $kernel_image ]]; then
-            for kernel_image in "/lib/modules/$kernel/vmlinuz" "/boot/vmlinuz-$kernel"; do
+            for kernel_image in "$dracutsysrootdir/lib/modules/$kernel/vmlinuz" "$dracutsysrootdir/boot/vmlinuz-$kernel"; do
                 [[ -s "$kernel_image" ]] || continue
                 break
             done
@@ -1133,7 +1221,7 @@ if (( ${#add_device_l[@]} )); then
     push_host_devs "${add_device_l[@]}"
 fi
 
-if [[ $hostonly ]]; then
+if [[ $hostonly ]] && [[ "$hostonly_default_device" != "no" ]]; then
     # in hostonly mode, determine all devices, which have to be accessed
     # and examine them for filesystem types
 
@@ -1151,9 +1239,10 @@ if [[ $hostonly ]]; then
         "/usr/lib64" \
         "/boot" \
         "/boot/efi" \
+        "/boot/zipl" \
         ;
     do
-        mp=$(readlink -f "$mp")
+        mp=$(readlink -f "$dracutsysrootdir$mp")
         mountpoint "$mp" >/dev/null 2>&1 || continue
         _dev=$(find_block_device "$mp")
         _bdev=$(readlink -f "/dev/block/$_dev")
@@ -1168,7 +1257,8 @@ if [[ $hostonly ]]; then
         fi
     done
 
-    if [[ -f /proc/swaps ]] && [[ -f /etc/fstab ]]; then
+    # TODO - with sysroot, /proc/swaps is not relevant
+    if [[ -f /proc/swaps ]] && [[ -f $dracutsysrootdir/etc/fstab ]]; then
         while read dev type rest || [ -n "$dev" ]; do
             [[ -b $dev ]] || continue
             [[ "$type" == "partition" ]] || continue
@@ -1182,7 +1272,7 @@ if [[ $hostonly ]]; then
                 _d=$(expand_persistent_dev "$_d")
                 [[ "$_d" -ef "$dev" ]] || continue
 
-                if [[ -f /etc/crypttab ]]; then
+                if [[ -f $dracutsysrootdir/etc/crypttab ]]; then
                     while read _mapper _a _p _o || [ -n "$_mapper" ]; do
                         [[ $_mapper = \#* ]] && continue
                         [[ "$_d" -ef /dev/mapper/"$_mapper" ]] || continue
@@ -1191,19 +1281,19 @@ if [[ $hostonly ]]; then
                         [[ "$_p" == /* ]] && [[ -f $_p ]] && continue 2
                         # skip mkswap swap
                         [[ $_o == *swap* ]] && continue 2
-                    done < /etc/crypttab
+                    done < $dracutsysrootdir/etc/crypttab
                 fi
 
                 _dev="$(readlink -f "$dev")"
                 push_host_devs "$_dev"
                 swap_devs+=("$_dev")
                 break
-            done < /etc/fstab
+            done < $dracutsysrootdir/etc/fstab
         done < /proc/swaps
     fi
 
     # collect all "x-initrd.mount" entries from /etc/fstab
-    if [[ -f /etc/fstab ]]; then
+    if [[ -f $dracutsysrootdir/etc/fstab ]]; then
         while read _d _m _t _o _r || [ -n "$_d" ]; do
             [[ "$_d" == \#* ]] && continue
             [[ $_d ]] || continue
@@ -1214,11 +1304,11 @@ if [[ $hostonly ]]; then
 
             push_host_devs "$_dev"
             if [[ "$_t" == btrfs ]]; then
-                for i in $(find_btrfs_devs "$_m"); do
+                for i in $(btrfs_devs "$_m"); do
                     push_host_devs "$i"
                 done
             fi
-        done < /etc/fstab
+        done < $dracutsysrootdir/etc/fstab
     fi
 fi
 
@@ -1263,44 +1353,36 @@ for dev in "${!host_fs_types[@]}"; do
     fi
 done
 
-[[ -d $udevdir ]] \
+[[ -d $dracutsysrootdir$udevdir ]] \
     || udevdir="$(pkg-config udev --variable=udevdir 2>/dev/null)"
-if ! [[ -d "$udevdir" ]]; then
-    [[ ! -h /lib ]] && [[ -d /lib/udev ]] && udevdir=/lib/udev
-    [[ -d /usr/lib/udev ]] && udevdir=/usr/lib/udev
+if ! [[ -d "$dracutsysrootdir$udevdir" ]]; then
+    [[ -e $dracutsysrootdir/lib/udev/ata_id ]] && udevdir=/lib/udev
+    [[ -e $dracutsysrootdir/usr/lib/udev/ata_id ]] && udevdir=/usr/lib/udev
 fi
 
-[[ -d $systemdutildir ]] \
-    || systemdutildir=$(pkg-config systemd --variable=systemdutildir 2>/dev/null)
-
-if ! [[ -d "$systemdutildir" ]]; then
-    [[ ! -h /lib ]] && [[ -d /lib/systemd ]] && systemdutildir=/lib/systemd
-    [[ -d /usr/lib/systemd ]] && systemdutildir=/usr/lib/systemd
-fi
-
-[[ -d $systemdsystemunitdir ]] \
+[[ -d $dracutsysrootdir$systemdsystemunitdir ]] \
     || systemdsystemunitdir=$(pkg-config systemd --variable=systemdsystemunitdir 2>/dev/null)
 
-[[ -d "$systemdsystemunitdir" ]] || systemdsystemunitdir=${systemdutildir}/system
+[[ -d "$dracutsysrootdir$systemdsystemunitdir" ]] || systemdsystemunitdir=${systemdutildir}/system
 
-[[ -d $systemdsystemconfdir ]] \
+[[ -d $dracutsysrootdir$systemdsystemconfdir ]] \
     || systemdsystemconfdir=$(pkg-config systemd --variable=systemdsystemconfdir 2>/dev/null)
 
-[[ -d "$systemdsystemconfdir" ]] || systemdsystemconfdir=/etc/systemd/system
+[[ -d "$dracutsysrootdir$systemdsystemconfdir" ]] || systemdsystemconfdir=/etc/systemd/system
 
-[[ -d $tmpfilesdir ]] \
+[[ -d $dracutsysrootdir$tmpfilesdir ]] \
     || tmpfilesdir=$(pkg-config systemd --variable=tmpfilesdir 2>/dev/null)
 
-if ! [[ -d "$tmpfilesdir" ]]; then
-    [[ -d /lib/tmpfiles.d ]] && tmpfilesdir=/lib/tmpfiles.d
-    [[ -d /usr/lib/tmpfiles.d ]] && tmpfilesdir=/usr/lib/tmpfiles.d
+if ! [[ -d "$dracutsysrootdir$tmpfilesdir" ]]; then
+    [[ -d $dracutsysrootdir/lib/tmpfiles.d ]] && tmpfilesdir=/lib/tmpfiles.d
+    [[ -d $dracutsysrootdir/usr/lib/tmpfiles.d ]] && tmpfilesdir=/usr/lib/tmpfiles.d
 fi
 
 export initdir dracutbasedir \
     dracutmodules force_add_dracutmodules add_dracutmodules omit_dracutmodules \
     mods_to_load \
     fw_dir drivers_dir debug no_kernel kernel_only \
-    omit_drivers mdadmconf lvmconf root_dev \
+    omit_drivers mdadmconf lvmconf root_devs \
     use_fstab fstab_lines libdirs fscks nofscks ro_mnt \
     stdloglvl sysloglvl fileloglvl kmsgloglvl logfile \
     debug host_fs_types host_devs swap_devs sshkey add_fstab \
@@ -1328,7 +1410,7 @@ do_print_cmdline()
     for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
         _d_mod=${moddir##*/}; _d_mod=${_d_mod#[0-9][0-9]}
         [[ ${_mods_to_print[$_d_mod]} ]] || continue
-        module_cmdline "$_d_mod"
+        module_cmdline "$_d_mod" "$moddir"
     done
     unset moddir
 }
@@ -1342,7 +1424,7 @@ fi
 # Create some directory structure first
 [[ $prefix ]] && mkdir -m 0755 -p "${initdir}${prefix}"
 
-[[ -h /lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
+[[ -h $dracutsysrootdir/lib ]] || mkdir -m 0755 -p "${initdir}${prefix}/lib"
 [[ $prefix ]] && ln -sfn "${prefix#/}/lib" "$initdir/lib"
 
 if [[ $prefix ]]; then
@@ -1409,14 +1491,14 @@ for moddir in "$dracutbasedir/modules.d"/[0-9][0-9]*; do
         dinfo "*** Including module: $_d_mod ***"
     fi
     if [[ $kernel_only == yes ]]; then
-        module_installkernel "$_d_mod" || {
+        module_installkernel "$_d_mod" "$moddir" || {
             dfatal "installkernel failed in module $_d_mod"
             exit 1
         }
     else
-        module_install "$_d_mod"
+        module_install "$_d_mod" "$moddir"
         if [[ $no_kernel != yes ]]; then
-            module_installkernel "$_d_mod" || {
+            module_installkernel "$_d_mod" "$moddir" || {
                 dfatal "installkernel failed in module $_d_mod"
                 exit 1
             }
@@ -1444,12 +1526,15 @@ dinfo "*** Including modules done ***"
 
 ## final stuff that has to happen
 if [[ $no_kernel != yes ]]; then
+    if [[ $hostonly_mode = "strict" ]]; then
+        cp "$DRACUT_KERNEL_MODALIASES" $initdir/lib/dracut/hostonly-kernel-modules.txt
+    fi
 
     if [[ $drivers ]]; then
         hostonly='' instmods $drivers
     fi
 
-    if [[ $add_drivers ]]; then
+    if [[ -n "${add_drivers// }" ]]; then
         hostonly='' instmods -c $add_drivers
     fi
     if [[ $force_drivers ]]; then
@@ -1509,7 +1594,7 @@ if [[ $kernel_only != yes ]]; then
         cat "$f" >> "${initdir}/etc/fstab"
     done
 
-    if [[ $systemdutildir ]]; then
+    if [[ $dracutsysrootdir$systemdutildir ]]; then
         if [ -d ${initdir}/$systemdutildir ]; then
             mkdir -p ${initdir}/etc/conf.d
             {
@@ -1523,13 +1608,17 @@ if [[ $kernel_only != yes ]]; then
     if [[ $DRACUT_RESOLVE_LAZY ]] && [[ $DRACUT_INSTALL ]]; then
         dinfo "*** Resolving executable dependencies ***"
         find "$initdir" -type f -perm /0111 -not -path '*.ko' -print0 \
-        | xargs -r -0 $DRACUT_INSTALL ${initdir:+-D "$initdir"} -R ${DRACUT_FIPS_MODE:+-f} --
-        dinfo "*** Resolving executable dependencies done***"
+        | xargs -r -0 $DRACUT_INSTALL ${initdir:+-D "$initdir"} ${dracutsysrootdir:+-r "$dracutsysrootdir"} -R ${DRACUT_FIPS_MODE:+-f} --
+        dinfo "*** Resolving executable dependencies done ***"
     fi
 
+    # Now we are done with lazy resolving, always install dependencies
+    unset DRACUT_RESOLVE_LAZY
+    export DRACUT_RESOLVE_DEPS=1
+
     # libpthread workaround: pthread_cancel wants to dlopen libgcc_s.so
     for _dir in $libdirs; do
-        for _f in "$_dir/libpthread.so"*; do
+        for _f in "$dracutsysrootdir$_dir/libpthread.so"*; do
             [[ -e "$_f" ]] || continue
             inst_libdir_file "libgcc_s.so*"
             break 2
@@ -1543,7 +1632,7 @@ for ((i=0; i < ${#include_src[@]}; i++)); do
     if [[ $src && $target ]]; then
         if [[ -f $src ]]; then
             inst $src $target
-        else
+        elif [[ -d $src ]]; then
             ddebug "Including directory: $src"
             destdir="${initdir}/${target}"
             mkdir -p "$destdir"
@@ -1559,21 +1648,25 @@ for ((i=0; i < ${#include_src[@]}; i++)); do
                         mkdir -m 0755 -p "$object_destdir"
                         chmod --reference="$objectname" "$object_destdir"
                     fi
-                    $DRACUT_CP -t "$object_destdir" "$objectname"/*
+                    $DRACUT_CP -t "$object_destdir" "$dracutsysrootdir$objectname"/*
                 else
-                    $DRACUT_CP -t "$destdir" "$objectname"
+                    $DRACUT_CP -t "$destdir" "$dracutsysrootdir$objectname"
                 fi
             done
+        elif [[ -e $src ]]; then
+            derror "$src is neither a directory nor a regular file"
+        else
+            derror "$src doesn't exist"
         fi
     fi
 done
 
 if [[ $kernel_only != yes ]]; then
     # make sure that library links are correct and up to date
-    for f in /etc/ld.so.conf /etc/ld.so.conf.d/*; do
-        [[ -f $f ]] && inst_simple "$f"
+    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"; then
+    if ! $DRACUT_LDCONFIG -r "$initdir" -f /etc/ld.so.conf; then
         if [[ $EUID = 0 ]]; then
             derror "ldconfig exited ungracefully"
         else
@@ -1582,21 +1675,6 @@ if [[ $kernel_only != yes ]]; then
     fi
 fi
 
-PRELINK_BIN="$(command -v prelink)"
-if [[ $EUID = 0 ]] && [[ $PRELINK_BIN ]]; then
-    if [[ $DRACUT_FIPS_MODE ]]; then
-        dinfo "*** Installing prelink files ***"
-        inst_multiple -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf /etc/prelink.cache
-    elif [[ $do_prelink == yes ]]; then
-        dinfo "*** Pre-linking files ***"
-        inst_multiple -o prelink /etc/prelink.conf /etc/prelink.conf.d/*.conf
-        chroot "$initdir" "$PRELINK_BIN" -a
-        rm -f -- "$initdir/$PRELINK_BIN"
-        rm -fr -- "$initdir"/etc/prelink.*
-        dinfo "*** Pre-linking files done ***"
-    fi
-fi
-
 if [[ $do_hardlink = yes ]] && command -v hardlink >/dev/null; then
     dinfo "*** Hardlinking files ***"
     hardlink "$initdir" 2>&1
@@ -1617,21 +1695,11 @@ if [[ $do_strip = yes ]] ; then
     done
 fi
 
-if [[ $do_strip = yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then
-    dinfo "*** Stripping files ***"
-    find "$initdir" -type f \
-        -executable -not -path '*/lib/modules/*.ko' -print0 \
-        | xargs -r -0 $strip_cmd -g 2>/dev/null
-
-    # strip kernel modules, but do not touch signed modules
-    find "$initdir" -type f -path '*/lib/modules/*.ko' -print0 \
-        | while read -r -d $'\0' f || [ -n "$f" ]; do
-        SIG=$(tail -c 28 "$f" | tr -d '\000')
-        [[ $SIG == '~Module signature appended~' ]] || { printf "%s\000" "$f"; }
-    done | xargs -r -0 $strip_cmd -g
+# cleanup empty ldconfig_paths directories
+for d in $(ldconfig_paths); do
+    rmdir -p --ignore-fail-on-non-empty "$initdir/$d" >/dev/null 2>&1
+done
 
-    dinfo "*** Stripping files done ***"
-fi
 if [[ $early_microcode = yes ]]; then
     dinfo "*** Generating early-microcode cpio image ***"
     ucode_dir=(amd-ucode intel-ucode)
@@ -1648,10 +1716,11 @@ if [[ $early_microcode = yes ]]; then
         for _fwdir in $fw_dir; do
             if [[ -d $_fwdir && -d $_fwdir/$_fw ]]; then
                 _src="*"
-                dinfo "*** Constructing ${ucode_dest[$idx]} ****"
+                dinfo "*** Constructing ${ucode_dest[$idx]} ***"
                 if [[ $hostonly ]]; then
                     _src=$(get_ucode_file)
                     [[ $_src ]] || break
+                    [[ -r $_fwdir/$_fw/$_src ]] || _src="${_src}.early"
                     [[ -r $_fwdir/$_fw/$_src ]] || break
                 fi
 
@@ -1703,6 +1772,142 @@ if [[ $hostonly_cmdline == "yes" ]] ; then
     fi
 fi
 
+if dracut_module_included "squash"; then
+    dinfo "*** Install squash loader ***"
+    if ! check_kernel_config CONFIG_SQUASHFS; then
+        dfatal "CONFIG_SQUASHFS have to be enabled for dracut squash module to work"
+        exit 1
+    fi
+    if ! check_kernel_config CONFIG_OVERLAY_FS; then
+        dfatal "CONFIG_OVERLAY_FS have to be enabled for dracut squash module to work"
+        exit 1
+    fi
+    if ! check_kernel_config CONFIG_DEVTMPFS; then
+        dfatal "CONFIG_DEVTMPFS have to be enabled for dracut squash module to work"
+        exit 1
+    fi
+
+    readonly squash_dir="$initdir/squash/root"
+    readonly squash_img=$initdir/squash/root.img
+
+    # Currently only move "usr" "etc" to squashdir
+    readonly squash_candidate=( "usr" "etc" )
+
+    mkdir -m 0755 -p $squash_dir
+    for folder in "${squash_candidate[@]}"; do
+        mv $initdir/$folder $squash_dir/$folder
+    done
+
+    # Move some files out side of the squash image, including:
+    # - Files required to boot and mount the squashfs image
+    # - Files need to be accessible without mounting the squash image
+    required_in_root() {
+        local file=$1
+        local _sqsh_file=$squash_dir/$file
+        local _init_file=$initdir/$file
+
+        if [[ -e $_init_file ]]; then
+            return
+        fi
+
+        if [[ ! -e $_sqsh_file ]] && [[ ! -L $_sqsh_file ]]; then
+            derror "$file is required to boot a squashed initramfs but it's not installed!"
+            return
+        fi
+
+        if [[ ! -d $(dirname $_init_file) ]]; then
+            required_in_root $(dirname $file)
+        fi
+
+        if [[ -L $_sqsh_file ]]; then
+          cp --preserve=all -P $_sqsh_file $_init_file
+          _sqsh_file=$(realpath $_sqsh_file 2>/dev/null)
+          if [[ -e $_sqsh_file ]] && [[ "$_sqsh_file" == "$squash_dir"* ]]; then
+            # Relative symlink
+            required_in_root ${_sqsh_file#$squash_dir/}
+            return
+          fi
+          if [[ -e $squash_dir$_sqsh_file ]]; then
+            # Absolute symlink
+            required_in_root ${_sqsh_file#/}
+            return
+          fi
+          required_in_root ${module_spec#$squash_dir/}
+        else
+          if [[ -d $_sqsh_file ]]; then
+            mkdir $_init_file
+          else
+            mv $_sqsh_file $_init_file
+          fi
+        fi
+    }
+
+    required_in_root etc/initrd-release
+
+    for module_spec in $squash_dir/usr/lib/modules/*/modules.*;
+    do
+        required_in_root ${module_spec#$squash_dir/}
+    done
+
+    for dracut_spec in $squash_dir/usr/lib/dracut/*;
+    do
+        required_in_root ${dracut_spec#$squash_dir/}
+    done
+
+    mv $initdir/init $initdir/init.stock
+    ln -s squash/init.sh $initdir/init
+
+    # Reinstall required files for the squash image setup script.
+    # We have moved them inside the squashed image, but they need to be
+    # accessible before mounting the image.
+    inst_multiple "echo" "sh" "mount" "modprobe" "mkdir"
+    hostonly="" instmods "loop" "squashfs" "overlay"
+
+    # Only keep systemctl outsite if we need switch root
+    if [[ ! -f "$initdir/lib/dracut/no-switch-root" ]]; then
+      inst "systemctl"
+    fi
+
+    for folder in "${squash_candidate[@]}"; do
+        # Remove duplicated files in squashfs image, save some more space
+        [[ ! -d $initdir/$folder/ ]] && continue
+        for file in $(find $initdir/$folder/ -not -type d);
+        do
+            if [[ -e $squash_dir${file#$initdir} ]]; then
+                mv $squash_dir${file#$initdir} $file
+            fi
+        done
+    done
+fi
+
+if [[ $do_strip = yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then
+    dinfo "*** Stripping files ***"
+    find "$initdir" -type f \
+        -executable -not -path '*/lib/modules/*.ko' -print0 \
+        | xargs -r -0 $strip_cmd -g -p 2>/dev/null
+
+    # strip kernel modules, but do not touch signed modules
+    find "$initdir" -type f -path '*/lib/modules/*.ko' -print0 \
+        | while read -r -d $'\0' f || [ -n "$f" ]; do
+        SIG=$(tail -c 28 "$f" | tr -d '\000')
+        [[ $SIG == '~Module signature appended~' ]] || { printf "%s\000" "$f"; }
+    done | xargs -r -0 $strip_cmd -g -p
+    dinfo "*** Stripping files done ***"
+fi
+
+if dracut_module_included "squash"; then
+    dinfo "*** Squashing the files inside the initramfs ***"
+    mksquashfs $squash_dir $squash_img -no-xattrs -no-exports -noappend -always-use-fragments -comp xz -Xdict-size 100% -no-progress 1> /dev/null
+
+    if [[ $? != 0 ]]; then
+        dfatal "dracut: Failed making squash image"
+        exit 1
+    fi
+
+    rm -rf $squash_dir
+    dinfo "*** Squashing the files inside the initramfs done ***"
+fi
+
 dinfo "*** Creating image file '$outfile' ***"
 
 if [[ $uefi = yes ]]; then
@@ -1752,7 +1957,7 @@ if ! (
     exit 1
 fi
 
-if (( maxloglvl >= 5 )); then
+if (( maxloglvl >= 5 )) && (( verbosity_mod_l >= 0 )); then
     if [[ $allowlocal ]]; then
        "$dracutbasedir/lsinitrd.sh" "${DRACUT_TMPDIR}/initramfs.img"| ddebug
     else
@@ -1776,19 +1981,32 @@ if [[ $uefi = yes ]]; then
     echo -ne "\x00" >> "$uefi_outdir/cmdline.txt"
 
     dinfo "Using UEFI kernel cmdline:"
-    dinfo $(< "$uefi_outdir/cmdline.txt")
+    dinfo $(tr -d '\000' < "$uefi_outdir/cmdline.txt")
 
-    [[ -s /usr/lib/os-release ]] && uefi_osrelease="/usr/lib/os-release"
-    [[ -s /etc/os-release ]] && uefi_osrelease="/etc/os-release"
+    [[ -s $dracutsysrootdir/usr/lib/os-release ]] && uefi_osrelease="$dracutsysrootdir/usr/lib/os-release"
+    [[ -s $dracutsysrootdir/etc/os-release ]] && uefi_osrelease="$dracutsysrootdir/etc/os-release"
 
     if objcopy \
            ${uefi_osrelease:+--add-section .osrel=$uefi_osrelease --change-section-vma .osrel=0x20000} \
            --add-section .cmdline="${uefi_outdir}/cmdline.txt" --change-section-vma .cmdline=0x30000 \
            --add-section .linux="$kernel_image" --change-section-vma .linux=0x40000 \
            --add-section .initrd="${DRACUT_TMPDIR}/initramfs.img" --change-section-vma .initrd=0x3000000 \
-           "$uefi_stub" "${uefi_outdir}/linux.efi" \
-            && cp --reflink=auto "${uefi_outdir}/linux.efi" "$outfile"; then
-        dinfo "*** Creating UEFI image file '$outfile' done ***"
+           "$uefi_stub" "${uefi_outdir}/linux.efi"; then
+        if [[ -n "${uefi_secureboot_key}" && -n "${uefi_secureboot_cert}" ]]; then \
+            if sbsign \
+                    --key "${uefi_secureboot_key}" \
+                    --cert "${uefi_secureboot_cert}" \
+                    --output "$outfile" "${uefi_outdir}/linux.efi"; then
+                dinfo "*** Creating signed UEFI image file '$outfile' done ***"
+            else
+                dfatal "*** Creating signed UEFI image file '$outfile' failed ***"
+                exit 1
+            fi
+        else
+            if cp --reflink=auto "${uefi_outdir}/linux.efi" "$outfile"; then
+                dinfo "*** Creating UEFI image file '$outfile' done ***"
+            fi
+        fi
     else
         rm -f -- "$outfile"
         dfatal "*** Creating UEFI image file '$outfile' failed ***"
@@ -1806,10 +2024,23 @@ fi
 
 command -v restorecon &>/dev/null && restorecon -- "$outfile"
 
-sync $outfile 2> /dev/null
-if [ $? -ne 0 ] ; then
-    dinfo "dracut: sync operartion on newly created initramfs $outfile failed"
-    exit 1
+# We sync/fsfreeze only if we're operating on a live booted system.
+# It's possible for e.g. `kernel` to be installed as an RPM BuildRequires or equivalent,
+# and there's no reason to sync, and *definitely* no reason to fsfreeze.
+# Another case where this happens is rpm-ostree, which performs its own sync/fsfreeze
+# globally.  See e.g. https://github.com/ostreedev/ostree/commit/8642ef5ab3fec3ac8eb8f193054852f83a8bc4d0
+if test -d $dracutsysrootdir/run/systemd/system; then
+    if ! sync "$outfile" 2> /dev/null; then
+        dinfo "dracut: sync operation on newly created initramfs $outfile failed"
+        exit 1
+    fi
+
+    # use fsfreeze only if we're not writing to /
+    if [[ "$(stat -c %m -- "$outfile")" != "/" && "$(stat -f -c %T -- "$outfile")" != "msdos" ]]; then
+        if ! $(fsfreeze -f $(dirname "$outfile") 2>/dev/null && fsfreeze -u $(dirname "$outfile") 2>/dev/null); then
+            dinfo "dracut: warning: could not fsfreeze $(dirname "$outfile")"
+        fi
+    fi
 fi
 
 exit 0