diff --git a/mkinitramfs b/mkinitramfs index e14251f..ead6106 100755 --- a/mkinitramfs +++ b/mkinitramfs @@ -276,6 +276,7 @@ fi # Prepare to clean up temporary files on exit DESTDIR= __TMPMAINFILES= +__TMPUNCOMPRESSEDFILES= __TMPCPIOGZ= __TMPEARLYCPIO= __MODULES_TO_ADD= @@ -284,10 +285,11 @@ clean_on_exit() { if [ "${keep}" = "y" ]; then echo "Working files in ${DESTDIR:-}," \ "list of files for main initramfs in ${__TMPMAINFILES:-}," \ + "list of files for uncompressed initramfs in ${__TMPUNCOMPRESSEDFILES:-}," \ "early initramfs in ${__TMPEARLYCPIO:-} and" \ "overlay in ${__TMPCPIOGZ:-}" else - for path in "${DESTDIR}" "${__TMPMAINFILES}" "${__TMPCPIOGZ}" "${__TMPEARLYCPIO}" "${__MODULES_TO_ADD}"; do + for path in "${DESTDIR}" "${__TMPMAINFILES}" "${__TMPUNCOMPRESSEDFILES}" "${__TMPCPIOGZ}" "${__TMPEARLYCPIO}" "${__MODULES_TO_ADD}"; do test -z "${path}" || rm -rf "${path}" done fi @@ -300,6 +302,7 @@ trap "exit 1" INT TERM # makes the EXIT trap effective even when killed DESTDIR="$(mktemp -d "${TMPDIR:-/var/tmp}/mkinitramfs_XXXXXX")" || exit 1 chmod 755 "${DESTDIR}" __TMPMAINFILES="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-MAIN_files_XXXXXX")" || exit 1 +__TMPUNCOMPRESSEDFILES="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-UNCOMPRESSED_files_XXXXXX")" || exit 1 __TMPCPIOGZ="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-OL_XXXXXX")" || exit 1 __TMPEARLYCPIO="$(mktemp "${TMPDIR:-/var/tmp}/mkinitramfs-FW_XXXXXX")" || exit 1 __MODULES_TO_ADD="$(mktemp "${TMPDIR:-/var/tmp}/modules_XXXXXX")" || exit 1 @@ -443,24 +446,6 @@ apply_add_modules || exit $? # Resolve hidden dependencies hidden_dep_add_modules -# decompress modules for boot speed, if possible -find "${DESTDIR}/${MODULESDIR}" -name '*.ko.*' | while read -r ko; do - case "$ko" in - *.xz) - if ! command -v xz >/dev/null 2>&1; then - break - fi - xz -d "${ko}" - ;; - *.zst) - if ! command -v zstd >/dev/null 2>&1; then - break - fi - zstd -q -d --rm "${ko}" - ;; - esac -done - # generate module deps depmod -a -b "${DESTDIR}" "${version}" rm -f "${DESTDIR}/lib/modules/${version}"/modules.*map @@ -498,15 +483,45 @@ if [ -n "${SOURCE_DATE_EPOCH}" ]; then cpio_reproducible="--reproducible" fi +# Read list of files and echo them plus all leading directories. +# The same directories might be printed multiple times (even with sorted input)! +add_directories() { + local last_dir path dir + while read -r path; do + dir="${path%/*}" + parent="${dir}" + while [ "$parent" != "$last_dir" ] && [ "$parent" != "." ]; do + echo "$parent" + parent="${parent%/*}" + done + last_dir="$dir" + echo "$path" + done + if [ -n "$last_dir" ]; then + echo "." + fi +} + +cd "${DESTDIR}" || exit 1 + # work around lack of "set -o pipefail" for pipes. # Write exit code to FD 3 in case of a failure to pass it through the pipes. { - cd "${DESTDIR}" { - find . || { echo "E: mkinitramfs failure find $?" >&2; echo 1 >&3; exit; } - } | { + find . \( ! -type d ! -name '*.zst' ! -name '*.xz' \) -o \( -type d -empty \) || + { echo "E: mkinitramfs failure main find $?" >&2; echo 1 >&3; exit; } + } | add_directories | { LC_ALL=C sort || { echo "E: mkinitramfs failure sort $?" >&2; echo 1 >&3; exit; } - } > "${__TMPMAINFILES}" || echo $? >&3 + } | uniq > "${__TMPMAINFILES}" || { echo "E: mkinitramfs failure uniq $?" >&2; echo 1 >&3; exit; } +} 3>&1 | { read -r exit_code; exit "${exit_code:-0}"; } || exit $? + +{ + { + find . -name '*.zst' -o -name '*.xz' || + { echo "E: mkinitramfs failure uncompressed find $?" >&2; echo 1 >&3; exit; } + } | add_directories | { + LC_ALL=C sort || { echo "E: mkinitramfs failure sort $?" >&2; echo 1 >&3; exit; } + } | uniq > "${__TMPUNCOMPRESSEDFILES}" || { echo "E: mkinitramfs failure uniq $?" >&2; echo 1 >&3; exit; } } 3>&1 | { read -r exit_code; exit "${exit_code:-0}"; } || exit $? { @@ -515,6 +530,12 @@ fi cat "${__TMPEARLYCPIO}" || { echo 1 >&3; exit; } fi + if [ -s "${__TMPUNCOMPRESSEDFILES}" ]; then + # shellcheck disable=SC2086 + cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc -D "${DESTDIR}" <"${__TMPUNCOMPRESSEDFILES}" || + { echo "E: mkinitramfs failure uncompressed cpio $?" >&2; echo 1 >&3; exit; } + fi + { # shellcheck disable=SC2086 cpio --quiet $cpio_owner_root $cpio_reproducible -o -H newc -D "${DESTDIR}" <"${__TMPMAINFILES}" ||