aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Disseldorp <ddiss@suse.de>2021-02-17 01:05:37 +0100
committerHarald Hoyer <harald@hoyer.xyz>2021-11-24 11:14:54 +0100
commitafe4a6dbb7df62982baab8212bba5d90010dfbac (patch)
tree31505fa13a7e05646fb3c5cb85ec5498d1469afe
parent51d21c6b37b0eb8566d18d665d0197ca4d68101c (diff)
downloaddracut-afe4a6dbb7df62982baab8212bba5d90010dfbac.tar.gz
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>
-rwxr-xr-xdracut.sh95
-rw-r--r--man/dracut.8.asc9
-rw-r--r--shell-completion/bash/dracut3
3 files changed, 88 insertions, 19 deletions
diff --git a/dracut.sh b/dracut.sh
index 0f111e80..867febe1 100755
--- a/dracut.sh
+++ b/dracut.sh
@@ -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() {
--long zstd \
--long no-compress \
--long gzip \
+ --long enhanced-cpio \
--long list-modules \
--long show-modules \
--long keep \
@@ -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))
[[ $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
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
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
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_
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
diff --git a/man/dracut.8.asc b/man/dracut.8.asc
index 515e32db..708166bd 100644
--- a/man/dracut.8.asc
+++ b/man/dracut.8.asc
@@ -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
-----------
diff --git a/shell-completion/bash/dracut b/shell-completion/bash/dracut
index 286fd1ce..d20b307f 100644
--- a/shell-completion/bash/dracut
+++ b/shell-completion/bash/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