Skip to content

Commit afe4a6d

Browse files
ddissharaldh
authored andcommitted
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>
1 parent 51d21c6 commit afe4a6d

File tree

3 files changed

+88
-19
lines changed

3 files changed

+88
-19
lines changed

dracut.sh

+77-18
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+
--enhanced-cpio 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 enhanced-cpio \
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+
--enhanced-cpio) enhanced_cpio_l="yes" ;;
773776
--list-modules) do_list="yes" ;;
774777
-M | --show-modules)
775778
show_modules_l="yes"
@@ -982,6 +985,7 @@ stdloglvl=$((stdloglvl + verbosity_mod_l))
982985
[[ $tmpdir ]] || tmpdir="$dracutsysrootdir"/var/tmp
983986
[[ $INITRD_COMPRESS ]] && compress=$INITRD_COMPRESS
984987
[[ $compress_l ]] && compress=$compress_l
988+
[[ $enhanced_cpio_l ]] && enhanced_cpio=$enhanced_cpio_l
985989
[[ $show_modules_l ]] && show_modules=$show_modules_l
986990
[[ $nofscks_l ]] && nofscks="yes"
987991
[[ $ro_mnt_l ]] && ro_mnt="yes"
@@ -1188,6 +1192,19 @@ else
11881192
exit 1
11891193
fi
11901194
1195+
if [[ $enhanced_cpio == "yes" ]]; then
1196+
enhanced_cpio="$dracutbasedir/dracut-cpio"
1197+
if [[ -x $enhanced_cpio ]]; then
1198+
# align based on statfs optimal transfer size
1199+
cpio_align=$(stat --file-system -c "%s" -- "$initdir")
1200+
else
1201+
dinfo "--enhanced-cpio ignored due to lack of dracut-cpio"
1202+
unset enhanced_cpio
1203+
fi
1204+
else
1205+
unset enhanced_cpio
1206+
fi
1207+
11911208
# shellcheck disable=SC2154
11921209
if [[ $no_kernel != yes ]] && ! [[ -d $srcmods ]]; then
11931210
printf "%s\n" "dracut: Cannot find module directory $srcmods" >&2
@@ -2252,6 +2269,8 @@ if dracut_module_included "squash"; then
22522269
fi
22532270
22542271
if [[ $do_strip == yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then
2272+
# stripping files negates (dedup) benefits of using reflink
2273+
[[ -n $enhanced_cpio ]] && ddebug "strip is enabled alongside cpio reflink"
22552274
dinfo "*** Stripping files ***"
22562275
find "$initdir" -type f \
22572276
-executable -not -path '*/lib/modules/*.ko' -print0 \
@@ -2322,15 +2341,29 @@ if [[ $create_early_cpio == yes ]]; then
23222341
fi
23232342
23242343
# 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
2344+
if [[ -n $enhanced_cpio ]]; then
2345+
if ! (
2346+
umask 077
2347+
cd "$early_cpio_dir/d"
2348+
find . -print0 | sort -z \
2349+
| $enhanced_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
2350+
--mtime 0 --data-align "$cpio_align" --truncate-existing \
2351+
"${DRACUT_TMPDIR}/initramfs.img"
2352+
); then
2353+
dfatal "dracut-cpio: creation of $outfile failed"
2354+
exit 1
2355+
fi
2356+
else
2357+
if ! (
2358+
umask 077
2359+
cd "$early_cpio_dir/d"
2360+
find . -print0 | sort -z \
2361+
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null \
2362+
${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet > "${DRACUT_TMPDIR}/initramfs.img"
2363+
); then
2364+
dfatal "dracut: creation of $outfile failed"
2365+
exit 1
2366+
fi
23342367
fi
23352368
fi
23362369
@@ -2386,15 +2419,41 @@ if [[ $compress == $DRACUT_COMPRESS_ZSTD* ]] && ! check_kernel_config CONFIG_RD_
23862419
compress="cat"
23872420
fi
23882421
2389-
if ! (
2390-
umask 077
2391-
cd "$initdir"
2392-
find . -print0 | sort -z \
2393-
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet \
2394-
| $compress >> "${DRACUT_TMPDIR}/initramfs.img"
2395-
); then
2396-
dfatal "dracut: creation of $outfile failed"
2397-
exit 1
2422+
if [[ -n $enhanced_cpio ]]; then
2423+
if [[ $compress == "cat" ]]; then
2424+
# dracut-cpio appends by default, so any ucode remains
2425+
cpio_outfile="${DRACUT_TMPDIR}/initramfs.img"
2426+
else
2427+
ddebug "$compress compression enabled alongside cpio reflink"
2428+
# dracut-cpio doesn't output to stdout, so stage for compression
2429+
cpio_outfile="${DRACUT_TMPDIR}/initramfs.img.uncompressed"
2430+
fi
2431+
2432+
if ! (
2433+
umask 077
2434+
cd "$initdir"
2435+
find . -print0 | sort -z \
2436+
| $enhanced_cpio --null ${cpio_owner:+--owner "$cpio_owner"} \
2437+
--mtime 0 --data-align "$cpio_align" "$cpio_outfile" || exit 1
2438+
[[ $compress == "cat" ]] && exit 0
2439+
$compress < "$cpio_outfile" >> "${DRACUT_TMPDIR}/initramfs.img" \
2440+
&& rm "$cpio_outfile"
2441+
); then
2442+
dfatal "dracut-cpio: creation of $outfile failed"
2443+
exit 1
2444+
fi
2445+
unset cpio_outfile
2446+
else
2447+
if ! (
2448+
umask 077
2449+
cd "$initdir"
2450+
find . -print0 | sort -z \
2451+
| cpio ${CPIO_REPRODUCIBLE:+--reproducible} --null ${cpio_owner:+-R "$cpio_owner"} -H newc -o --quiet \
2452+
| $compress >> "${DRACUT_TMPDIR}/initramfs.img"
2453+
); then
2454+
dfatal "dracut: creation of $outfile failed"
2455+
exit 1
2456+
fi
23982457
fi
23992458
24002459
# shellcheck disable=SC2154

man/dracut.8.asc

+9
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+
**--enhanced-cpio**::
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

+2-1
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+
--enhanced-cpio'
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)