Browse Source

feat(dracut.sh): add "--enhanced-cpio" option for calling dracut-cpio

The new dracut-cpio binary is capable of performing copy-on-write
optimized initramfs archive creation, but due to the rust dependency
isn't built / installed by default.
This change adds a new "--enhanced-cpio" parameter for dracut which
sees dracut-cpio called for archive creation instead of GNU cpio.

Signed-off-by: David Disseldorp <ddiss@suse.de>
master
David Disseldorp 3 years ago committed by Harald Hoyer
parent
commit
afe4a6dbb7
  1. 95
      dracut.sh
  2. 9
      man/dracut.8.asc
  3. 3
      shell-completion/bash/dracut

95
dracut.sh

@ -226,6 +226,7 @@ Creates initial ramdisk images for preloading modules @@ -226,6 +226,7 @@ Creates initial ramdisk images for preloading modules
otherwise you will not be able to boot.
--no-compress Do not compress the generated initramfs. This will
override any other compression options.
--enhanced-cpio Attempt to reflink cpio file data using dracut-cpio.
--list-modules List all available dracut modules.
-M, --show-modules Print included module's name to standard output during
build.
@ -412,6 +413,7 @@ rearrange_params() { @@ -412,6 +413,7 @@ rearrange_params() {
--long zstd \
--long no-compress \
--long gzip \
--long enhanced-cpio \
--long list-modules \
--long show-modules \
--long keep \
@ -770,6 +772,7 @@ while :; do @@ -770,6 +772,7 @@ while :; do
--zstd) compress_l="zstd" ;;
--no-compress) _no_compress_l="cat" ;;
--gzip) compress_l="gzip" ;;
--enhanced-cpio) enhanced_cpio_l="yes" ;;
--list-modules) do_list="yes" ;;
-M | --show-modules)
show_modules_l="yes"
@ -982,6 +985,7 @@ stdloglvl=$((stdloglvl + verbosity_mod_l)) @@ -982,6 +985,7 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
[[ $tmpdir ]] || tmpdir="$dracutsysrootdir"/var/tmp
[[ $INITRD_COMPRESS ]] && compress=$INITRD_COMPRESS
[[ $compress_l ]] && compress=$compress_l
[[ $enhanced_cpio_l ]] && enhanced_cpio=$enhanced_cpio_l
[[ $show_modules_l ]] && show_modules=$show_modules_l
[[ $nofscks_l ]] && nofscks="yes"
[[ $ro_mnt_l ]] && ro_mnt="yes"
@ -1188,6 +1192,19 @@ else @@ -1188,6 +1192,19 @@ else
exit 1
fi

if [[ $enhanced_cpio == "yes" ]]; then
enhanced_cpio="$dracutbasedir/dracut-cpio"
if [[ -x $enhanced_cpio ]]; then
# align based on statfs optimal transfer size
cpio_align=$(stat --file-system -c "%s" -- "$initdir")
else
dinfo "--enhanced-cpio ignored due to lack of dracut-cpio"
unset enhanced_cpio
fi
else
unset enhanced_cpio
fi

# shellcheck disable=SC2154
if [[ $no_kernel != yes ]] && ! [[ -d $srcmods ]]; then
printf "%s\n" "dracut: Cannot find module directory $srcmods" >&2
@ -2252,6 +2269,8 @@ if dracut_module_included "squash"; then @@ -2252,6 +2269,8 @@ if dracut_module_included "squash"; then
fi

if [[ $do_strip == yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then
# stripping files negates (dedup) benefits of using reflink
[[ -n $enhanced_cpio ]] && ddebug "strip is enabled alongside cpio reflink"
dinfo "*** Stripping files ***"
find "$initdir" -type f \
-executable -not -path '*/lib/modules/*.ko' -print0 \
@ -2322,15 +2341,29 @@ if [[ $create_early_cpio == yes ]]; then @@ -2322,15 +2341,29 @@ if [[ $create_early_cpio == yes ]]; then
fi

# The microcode blob is _before_ the initramfs blob, not after
if ! (
umask 077
cd "$early_cpio_dir/d"
find . -print0 | sort -z \
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null \
${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet > "${DRACUT_TMPDIR}/initramfs.img"
); then
dfatal "dracut: creation of $outfile failed"
exit 1
if [[ -n $enhanced_cpio ]]; then
if ! (
umask 077
cd "$early_cpio_dir/d"
find . -print0 | sort -z \
| $enhanced_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
--mtime 0 --data-align "$cpio_align" --truncate-existing \
"${DRACUT_TMPDIR}/initramfs.img"
); then
dfatal "dracut-cpio: creation of $outfile failed"
exit 1
fi
else
if ! (
umask 077
cd "$early_cpio_dir/d"
find . -print0 | sort -z \
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null \
${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet > "${DRACUT_TMPDIR}/initramfs.img"
); then
dfatal "dracut: creation of $outfile failed"
exit 1
fi
fi
fi

@ -2386,15 +2419,41 @@ if [[ $compress == $DRACUT_COMPRESS_ZSTD* ]] && ! check_kernel_config CONFIG_RD_ @@ -2386,15 +2419,41 @@ if [[ $compress == $DRACUT_COMPRESS_ZSTD* ]] && ! check_kernel_config CONFIG_RD_
compress="cat"
fi

if ! (
umask 077
cd "$initdir"
find . -print0 | sort -z \
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet \
| $compress >> "${DRACUT_TMPDIR}/initramfs.img"
); then
dfatal "dracut: creation of $outfile failed"
exit 1
if [[ -n $enhanced_cpio ]]; then
if [[ $compress == "cat" ]]; then
# dracut-cpio appends by default, so any ucode remains
cpio_outfile="${DRACUT_TMPDIR}/initramfs.img"
else
ddebug "$compress compression enabled alongside cpio reflink"
# dracut-cpio doesn't output to stdout, so stage for compression
cpio_outfile="${DRACUT_TMPDIR}/initramfs.img.uncompressed"
fi

if ! (
umask 077
cd "$initdir"
find . -print0 | sort -z \
| $enhanced_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
--mtime 0 --data-align "$cpio_align" "$cpio_outfile" || exit 1
[[ $compress == "cat" ]] && exit 0
$compress < "$cpio_outfile" >> "${DRACUT_TMPDIR}/initramfs.img" \
&& rm "$cpio_outfile"
); then
dfatal "dracut-cpio: creation of $outfile failed"
exit 1
fi
unset cpio_outfile
else
if ! (
umask 077
cd "$initdir"
find . -print0 | sort -z \
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet \
| $compress >> "${DRACUT_TMPDIR}/initramfs.img"
); then
dfatal "dracut: creation of $outfile failed"
exit 1
fi
fi

# shellcheck disable=SC2154

9
man/dracut.8.asc

@ -530,6 +530,15 @@ will not be able to boot. @@ -530,6 +530,15 @@ will not be able to boot.
Specifies the kernel image, which to include in the UEFI executable. The default is
_/lib/modules/<KERNEL-VERSION>/vmlinuz_ or _/boot/vmlinuz-<KERNEL-VERSION>_

**--enhanced-cpio**::
Attempt to use the dracut-cpio binary, which optimizes archive creation for
copy-on-write filesystems by using the copy_file_range(2) syscall via Rust's
io::copy(). When specified, initramfs archives are also padded to ensure
optimal data alignment for extent sharing. To retain reflink data
deduplication benefits, this should be used alongside the **--no-compress**
and **--no-strip** parameters, with initramfs source files, **--tmpdir**
staging area and destination all on the same copy-on-write capable filesystem.

ENVIRONMENT
-----------


3
shell-completion/bash/dracut

@ -32,7 +32,8 @@ _dracut() { @@ -32,7 +32,8 @@ _dracut() {
--local --hostonly --no-hostonly --fstab --help --bzip2 --lzma
--xz --zstd --no-compress --gzip --list-modules --show-modules --keep
--printsize --regenerate-all --noimageifnotneeded --early-microcode
--no-early-microcode --print-cmdline --reproducible --uefi'
--no-early-microcode --print-cmdline --reproducible --uefi
--enhanced-cpio'
[ARG]='-a -m -o -d -I -k -c -L --kver --add --force-add --add-drivers
--omit-drivers --modules --omit --drivers --filesystems --install
--fwdir --libdirs --fscks --add-fstab --mount --device --nofscks

Loading…
Cancel
Save