make-initrd: fix reproducibility problems

cpio includes the number of directory hard links in archives it creates.
Some filesystems, like btrfs, do not count directory hard links the same
way as more common filesystems like ext4 or tmpfs, so archives built
when /tmp is on such a filesystem do not reproduce. This patch replaces
cpio with bsdtar, which does not have this issue. The specific
invocation is from this page:
https://reproducible-builds.org/docs/archives/
This commit is contained in:
Thomas Watson 2022-03-26 18:34:30 -05:00
parent a9414de122
commit 7fd6cea253
3 changed files with 5 additions and 5 deletions

View file

@ -400,7 +400,7 @@ let
${lib.optionalString (config.boot.initrd.secrets == {}) ${lib.optionalString (config.boot.initrd.secrets == {})
"exit 0"} "exit 0"}
export PATH=${pkgs.coreutils}/bin:${pkgs.cpio}/bin:${pkgs.gzip}/bin:${pkgs.findutils}/bin export PATH=${pkgs.coreutils}/bin:${pkgs.libarchive}/bin:${pkgs.gzip}/bin:${pkgs.findutils}/bin
function cleanup { function cleanup {
if [ -n "$tmp" -a -d "$tmp" ]; then if [ -n "$tmp" -a -d "$tmp" ]; then
@ -420,7 +420,7 @@ let
) config.boot.initrd.secrets) ) config.boot.initrd.secrets)
} }
(cd "$tmp" && find . -print0 | sort -z | cpio --quiet -o -H newc -R +0:+0 --reproducible --null) | \ (cd "$tmp" && find . -print0 | sort -z | bsdtar --uid 0 --gid 0 -cnf - -T - | bsdtar --null -cf - --format=newc @-) | \
${compressorExe} ${lib.escapeShellArgs initialRamdisk.compressorArgs} >> "$1" ${compressorExe} ${lib.escapeShellArgs initialRamdisk.compressorArgs} >> "$1"
''; '';

View file

@ -18,7 +18,7 @@ let
# compression type and filename extension. # compression type and filename extension.
compressorName = fullCommand: builtins.elemAt (builtins.match "([^ ]*/)?([^ ]+).*" fullCommand) 1; compressorName = fullCommand: builtins.elemAt (builtins.match "([^ ]*/)?([^ ]+).*" fullCommand) 1;
in in
{ stdenvNoCC, perl, cpio, ubootTools, lib, pkgsBuildHost { stdenvNoCC, perl, libarchive, ubootTools, lib, pkgsBuildHost
# Name of the derivation (not of the resulting file!) # Name of the derivation (not of the resulting file!)
, name ? "initrd" , name ? "initrd"
@ -82,7 +82,7 @@ in stdenvNoCC.mkDerivation rec {
builder = ./make-initrd.sh; builder = ./make-initrd.sh;
nativeBuildInputs = [ perl cpio ] nativeBuildInputs = [ perl libarchive ]
++ lib.optional makeUInitrd ubootTools; ++ lib.optional makeUInitrd ubootTools;
compress = "${_compressorExecutable} ${lib.escapeShellArgs _compressorArgsReal}"; compress = "${_compressorExecutable} ${lib.escapeShellArgs _compressorArgsReal}";

View file

@ -40,7 +40,7 @@ for PREP in $prepend; do
cat $PREP >> $out/initrd cat $PREP >> $out/initrd
done done
(cd root && find * .[^.*] -exec touch -h -d '@1' '{}' +) (cd root && find * .[^.*] -exec touch -h -d '@1' '{}' +)
(cd root && find * .[^.*] -print0 | sort -z | cpio -o -H newc -R +0:+0 --reproducible --null | eval -- $compress >> "$out/initrd") (cd root && find * .[^.*] -print0 | sort -z | bsdtar --uid 0 --gid 0 -cnf - -T - | bsdtar --null -cf - --format=newc @- | eval -- $compress >> "$out/initrd")
if [ -n "$makeUInitrd" ]; then if [ -n "$makeUInitrd" ]; then
mkimage -A "$uInitrdArch" -O linux -T ramdisk -C "$uInitrdCompression" -d "$out/initrd" $out/initrd.img mkimage -A "$uInitrdArch" -O linux -T ramdisk -C "$uInitrdCompression" -d "$out/initrd" $out/initrd.img