スクリプトからinitramfsファイルをビルドすると、比較できないバイナリcmp
ファイルが生成され、diff -r /rootfs1/ /rootfs2/
終了0
後もdiff
違いはありません。
私が見つけた違いは使用する権利そして変化日付。たとえば、
# stat /rootfs1/config
File: /rootfs1/config
Size: 275 Blocks: 8 IO Block: 4096 regular file
Device: 28h/40d Inode: 119120 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2017-12-12 01:31:03.800453381 +0100
Modify: 2017-12-05 20:11:38.000000000 +0100
Change: 2017-12-12 01:02:38.607238288 +0100
Birth: -
# stat /rootfs2/config
File: /rootfs2/config
Size: 275 Blocks: 8 IO Block: 4096 regular file
Device: 28h/40d Inode: 119881 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2017-12-12 01:28:02.913799257 +0100
Modify: 2017-12-05 20:11:38.000000000 +0100
Change: 2017-12-12 01:20:44.920496295 +0100
Birth: -
返品
find
コマンドがすべてのディレクトリエントリをまったく同じ順序で返すことを確認しました。頑張ったtouch は、ディレクトリ構造の各エントリを同じソースファイルとして参照します。。それでも同じバイトストリームを作成できません。
結果 initramfs イメージは
lz4 -l
bsdcpio
既にバイト 5 で異なります。$ cmp /tmp/1.img /tmp/2.img
/tmp/rootfs1/initramfs.img /tmp/rootfs2/initramfs.img differ: char 5, line 1
mount -o remount,noatime /tmp
引き続き更新中最後の状態変更時間」によるとstat %z
bsdcpioスクリプトコードは次のとおりです。
pushd "$BUILDROOT" >/dev/null
find -mindepth 1 -printf '%P\0' | LANG=C bsdcpio -0 -o -H newc | lz4 -l > "$out"
$ BUILDROOTが各実行の新しい一時フォルダーである連続スクリプト実行に対して同じ出力バイトストリームを提供できますか?
答え1
アクセス時間と変更時間は cpio newc 構造には保存されません。しかし、実際にはファイルシステムのinode番号とデバイス番号です。
構造 cpio_newc_header { char c_magic[6]; 性格 c_ino[8]; 文字c_mode [8]; char c_uid[8]; 文字c_gid [8]; 文字c_nlink [8]; char c_mtime[8]; char c_filesize[8]; 性格 c_devmajor[8]; 性格 c_devminor[8]; char c_rdevmajor[8]; 文字c_rdevminor [8]; char c_namesize[8]; 文字c_check [8]; };
毎回新しいファイルシステムからファイルを抽出してinode番号を一貫してコピーすることはできますが、同じ時点に存在する2つの別々のディレクトリ構造がdev +の組み合わせと同じcpioアーカイブinoを生成することはできません。デザインシステムでユニークです。
一貫したcpioアーカイブを作成するには、毎回新しいファイルシステムを作成し、同じデバイス番号を割り当て、各ファイルに毎回同じinode番号を割り当てる必要があります。
あるいは、結果のcpioアーカイブを後処理して、デバイスとinodeの番号を変更することもできます。それは次のとおりです。
printf '%s\0' **/*(D) | bsdcpio -0 -o -H newc | perl -0777 -pe '
$dev = sprintf("%016x", 1);
while (substr($_, 0, 6) eq "070701") {
($inode, $size, $nsize) = map hex, unpack("x6a8x40a8x32a8", $_);
$nsize += (2-$nsize) % 4; $size += (-$size) % 4;
$inode{$inode} ||= ++$n;
substr($_, 6, 8) = sprintf("%08x", $inode{$inode});
substr($_, 62, 16) = $dev;
print substr($_, 0, 110+$size+$nsize, "")
}'
どこ開発者ハードコーディングされており、1
各エントリのinodeは1から始まります(ただし、ハードリンクはまだ同じです)。
「代わりにソートされたファイルパスのリストを取得するにはzsh
」を使用してください。順序が一貫していない可能性があります。**/*(D)
find