Skip to content

Commit 92c9dc6

Browse files
committed
feat(dracut.sh): add "--cpio-reflink" 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 "--cpio-reflink" parameter for dracut which sees dracut-cpio called for archive creation instead of GNU cpio. Signed-off-by: David Disseldorp <[email protected]>
1 parent 469af85 commit 92c9dc6

File tree

3 files changed

+75
-19
lines changed

3 files changed

+75
-19
lines changed

dracut.sh

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ Creates initial ramdisk images for preloading modules
226226
otherwise you will not be able to boot.
227227
--no-compress Do not compress the generated initramfs. This will
228228
override any other compression options.
229+
--cpio-reflink Attempt to reflink cpio file data using dracut-cpio.
229230
--list-modules List all available dracut modules.
230231
-M, --show-modules Print included module's name to standard output during
231232
build.
@@ -412,6 +413,7 @@ rearrange_params() {
412413
--long zstd \
413414
--long no-compress \
414415
--long gzip \
416+
--long cpio-reflink \
415417
--long list-modules \
416418
--long show-modules \
417419
--long keep \
@@ -770,6 +772,7 @@ while :; do
770772
--zstd) compress_l="zstd" ;;
771773
--no-compress) _no_compress_l="cat" ;;
772774
--gzip) compress_l="gzip" ;;
775+
--cpio-reflink) cpio_reflink="yes" ;;
773776
--list-modules) do_list="yes" ;;
774777
-M | --show-modules)
775778
show_modules_l="yes"
@@ -1151,6 +1154,17 @@ trap 'exit 1;' SIGINT
11511154
readonly initdir="${DRACUT_TMPDIR}/initramfs"
11521155
mkdir -p "$initdir"
11531156
1157+
if [[ $cpio_reflink == "yes" ]]; then
1158+
dracut_cpio="$dracutbasedir/dracut-cpio"
1159+
if [[ -x $dracut_cpio ]]; then
1160+
# align based on statfs optimal transfer size
1161+
cpio_align=$(stat --file-system -c "%s" -- "$initdir")
1162+
else
1163+
dinfo "cpio-reflink ignored due to lack of dracut-cpio"
1164+
unset cpio_reflink
1165+
fi
1166+
fi
1167+
11541168
# shellcheck disable=SC2154
11551169
if [[ $early_microcode == yes ]] || { [[ $acpi_override == yes ]] && [[ -d $acpi_table_dir ]]; }; then
11561170
readonly early_cpio_dir="${DRACUT_TMPDIR}/earlycpio"
@@ -2252,6 +2266,8 @@ if dracut_module_included "squash"; then
22522266
fi
22532267
22542268
if [[ $do_strip == yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then
2269+
# warn that stripping files negates (dedup) benefits of using reflink
2270+
[ -n "$cpio_reflink" ] && dinfo "inefficient: strip is enabled alongside cpio reflink"
22552271
dinfo "*** Stripping files ***"
22562272
find "$initdir" -type f \
22572273
-executable -not -path '*/lib/modules/*.ko' -print0 \
@@ -2322,15 +2338,29 @@ if [[ $create_early_cpio == yes ]]; then
23222338
fi
23232339
23242340
# The microcode blob is _before_ the initramfs blob, not after
2325-
if ! (
2326-
umask 077
2327-
cd "$early_cpio_dir/d"
2328-
find . -print0 | sort -z \
2329-
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null \
2330-
${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet > "${DRACUT_TMPDIR}/initramfs.img"
2331-
); then
2332-
dfatal "dracut: creation of $outfile failed"
2333-
exit 1
2341+
if [[ -n $cpio_reflink ]]; then
2342+
if ! (
2343+
umask 077
2344+
cd "$early_cpio_dir/d"
2345+
find . -print0 | sort -z \
2346+
| $dracut_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
2347+
--mtime 0 --data-align "$cpio_align" --truncate-existing \
2348+
"${DRACUT_TMPDIR}/initramfs.img"
2349+
); then
2350+
dfatal "dracut: creation of reflinked $outfile failed"
2351+
exit 1
2352+
fi
2353+
else
2354+
if ! (
2355+
umask 077
2356+
cd "$early_cpio_dir/d"
2357+
find . -print0 | sort -z \
2358+
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null \
2359+
${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet > "${DRACUT_TMPDIR}/initramfs.img"
2360+
); then
2361+
dfatal "dracut: creation of $outfile failed"
2362+
exit 1
2363+
fi
23342364
fi
23352365
fi
23362366
@@ -2381,15 +2411,31 @@ case $compress in
23812411
;;
23822412
esac
23832413
2384-
if ! (
2385-
umask 077
2386-
cd "$initdir"
2387-
find . -print0 | sort -z \
2388-
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet \
2389-
| $compress >> "${DRACUT_TMPDIR}/initramfs.img"
2390-
); then
2391-
dfatal "dracut: creation of $outfile failed"
2392-
exit 1
2414+
if [[ -n $cpio_reflink && $compress == "cat" ]]; then
2415+
# dracut-cpio appends by default, so any ucode remains
2416+
if ! (
2417+
umask 077
2418+
cd "$initdir"
2419+
find . -print0 | sort -z \
2420+
| $dracut_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
2421+
--mtime 0 --data-align "$cpio_align" \
2422+
"${DRACUT_TMPDIR}/initramfs.img"
2423+
); then
2424+
dfatal "dracut: creation of reflinked $outfile failed"
2425+
exit 1
2426+
fi
2427+
else
2428+
[ -n "$cpio_reflink" ] && dinfo "cpio-reflink ignored due to compression"
2429+
if ! (
2430+
umask 077
2431+
cd "$initdir"
2432+
find . -print0 | sort -z \
2433+
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet \
2434+
| $compress >> "${DRACUT_TMPDIR}/initramfs.img"
2435+
); then
2436+
dfatal "dracut: creation of $outfile failed"
2437+
exit 1
2438+
fi
23932439
fi
23942440
23952441
# shellcheck disable=SC2154

man/dracut.8.asc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,15 @@ will not be able to boot.
530530
Specifies the kernel image, which to include in the UEFI executable. The default is
531531
_/lib/modules/<KERNEL-VERSION>/vmlinuz_ or _/boot/vmlinuz-<KERNEL-VERSION>_
532532
533+
**--cpio-reflink**::
534+
Attempt to use the dracut-cpio binary, which optimizes archive creation for
535+
copy-on-write filesystems by using the copy_file_range(2) syscall via Rust's
536+
io::copy(). When specified, initramfs archives are also padded to ensure
537+
optimal data alignment for extent sharing. To retain reflink data
538+
deduplication benefits, this should be used alongside the **--no-compress**
539+
and **--no-strip** parameters, with initramfs source files, **--tmpdir**
540+
staging area and destination all on the same copy-on-write capable filesystem.
541+
533542
ENVIRONMENT
534543
-----------
535544

shell-completion/bash/dracut

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ _dracut() {
3232
--local --hostonly --no-hostonly --fstab --help --bzip2 --lzma
3333
--xz --zstd --no-compress --gzip --list-modules --show-modules --keep
3434
--printsize --regenerate-all --noimageifnotneeded --early-microcode
35-
--no-early-microcode --print-cmdline --reproducible --uefi'
35+
--no-early-microcode --print-cmdline --reproducible --uefi
36+
--cpio-reflink'
3637
[ARG]='-a -m -o -d -I -k -c -L --kver --add --force-add --add-drivers
3738
--omit-drivers --modules --omit --drivers --filesystems --install
3839
--fwdir --libdirs --fscks --add-fstab --mount --device --nofscks

0 commit comments

Comments
 (0)