Skip to content

Commit

Permalink
feat(dracut.sh): add "--cpio-reflink" option for calling dracut-cpio
Browse files Browse the repository at this point in the history
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 "--cpio-reflink" parameter for dracut which
sees dracut-cpio called for archive creation instead of GNU cpio.

Signed-off-by: David Disseldorp <ddiss@suse.de>
  • Loading branch information
ddiss committed Aug 27, 2021
1 parent 469af85 commit 92c9dc6
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 19 deletions.
82 changes: 64 additions & 18 deletions dracut.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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.
--cpio-reflink 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.
Expand Down Expand Up @@ -412,6 +413,7 @@ rearrange_params() {
--long zstd \
--long no-compress \
--long gzip \
--long cpio-reflink \
--long list-modules \
--long show-modules \
--long keep \
Expand Down Expand Up @@ -770,6 +772,7 @@ while :; do
--zstd) compress_l="zstd" ;;
--no-compress) _no_compress_l="cat" ;;
--gzip) compress_l="gzip" ;;
--cpio-reflink) cpio_reflink="yes" ;;
--list-modules) do_list="yes" ;;
-M | --show-modules)
show_modules_l="yes"
Expand Down Expand Up @@ -1151,6 +1154,17 @@ 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"
Expand Down Expand Up @@ -2252,6 +2266,8 @@ if dracut_module_included "squash"; then
fi
if [[ $do_strip == yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then
# warn that stripping files negates (dedup) benefits of using reflink
[ -n "$cpio_reflink" ] && dinfo "inefficient: strip is enabled alongside cpio reflink"
dinfo "*** Stripping files ***"
find "$initdir" -type f \
-executable -not -path '*/lib/modules/*.ko' -print0 \
Expand Down Expand Up @@ -2322,15 +2338,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 $cpio_reflink ]]; then
if ! (
umask 077
cd "$early_cpio_dir/d"
find . -print0 | sort -z \
| $dracut_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
--mtime 0 --data-align "$cpio_align" --truncate-existing \
"${DRACUT_TMPDIR}/initramfs.img"
); then
dfatal "dracut: creation of reflinked $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
Expand Down Expand Up @@ -2381,15 +2411,31 @@ case $compress in
;;
esac
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 $cpio_reflink && $compress == "cat" ]]; then
# dracut-cpio appends by default, so any ucode remains
if ! (
umask 077
cd "$initdir"
find . -print0 | sort -z \
| $dracut_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
--mtime 0 --data-align "$cpio_align" \
"${DRACUT_TMPDIR}/initramfs.img"
); then
dfatal "dracut: creation of reflinked $outfile failed"
exit 1
fi
else
[ -n "$cpio_reflink" ] && dinfo "cpio-reflink ignored due to compression"
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
Expand Down
9 changes: 9 additions & 0 deletions man/dracut.8.asc
Original file line number Diff line number Diff line change
Expand Up @@ -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>_
**--cpio-reflink**::
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
-----------

Expand Down
3 changes: 2 additions & 1 deletion shell-completion/bash/dracut
Original file line number Diff line number Diff line change
Expand Up @@ -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
--cpio-reflink'
[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
Expand Down

0 comments on commit 92c9dc6

Please sign in to comment.