diff --git a/dracut.sh b/dracut.sh index 092b7b426d..d04e0dd4b1 100755 --- a/dracut.sh +++ b/dracut.sh @@ -1168,17 +1168,6 @@ trap 'exit 1;' SIGINT readonly initdir="${DRACUT_TMPDIR}/initramfs" mkdir -p "$initdir" -if [[ $cpio_reflink == "yes" ]]; then - dracut_cpio="$dracutbasedir/dracut-cpio" - if [[ -x $dracut_cpio ]]; then - # align based on statfs optimal transfer size - cpio_align=$(stat --file-system -c "%s" -- "$initdir") - else - dinfo "cpio-reflink ignored due to lack of dracut-cpio" - unset cpio_reflink - fi -fi - # shellcheck disable=SC2154 if [[ $early_microcode == yes ]] || { [[ $acpi_override == yes ]] && [[ -d $acpi_table_dir ]]; }; then readonly early_cpio_dir="${DRACUT_TMPDIR}/earlycpio" @@ -1216,6 +1205,48 @@ else exit 1 fi +is_reflink_supported() { + dracut_cpio="$dracutbasedir/dracut-cpio" + [ -x $dracut_cpio ] || { + dinfo "cpio-reflink ignored due to lack of dracut-cpio" + return 1 + } + local fstype=$(find_mp_fstype $dracutsysrootdir/boot) + case $fstype in + xfs|btrfs) ;; + *) + dinfo "cpio-reflink is unsupported on $fstype" + return 1;; + esac + # reflinking doesn't work across mount points + if mountpoint -q $dracutsysrootdir/boot; then + dinfo "cpio-reflink ignored because /boot is a separate mountpoint" + return 1; + elif [[ $(stat -f -c %i $dracutsysrootdir/) != $(stat -f -c %i "$TMPDIR") ]]; then + dinfo "cpio-reflink ignored because tmpdir=\"$TMPDIR\" is on a separate file system" + return 1 + else + return 0 + fi +} + +if [[ $cpio_reflink == "yes" ]]; then + if [[ ! $compress_l && $do_strip_l != "yes" ]] && is_reflink_supported; then + if [[ $do_strip == "yes" ]]; then + dinfo "ignoring --strip because of cpio-reflink" + do_strip="no" + fi + if [[ $compress != "$DRACUT_COMPRESS_CAT" ]]; then + dinfo "setting compress=\"$DRACUT_COMPRESS_CAT\" because of cpio-reflink" + compress="$DRACUT_COMPRESS_CAT" + fi + # align based on statfs optimal transfer size + cpio_align=$(stat --file-system -c "%s" -- "$initdir") + else + unset cpio_reflink + fi +fi + # shellcheck disable=SC2154 if [[ $no_kernel != yes ]] && ! [[ -d $srcmods ]]; then printf "%s\n" "dracut: Cannot find module directory $srcmods" >&2