同じバイナリbsdcpio出力ストリームを生成するためにディレクトリ構造を再生成できますか?

同じバイナリbsdcpio出力ストリームを生成するためにディレクトリ構造を再生成できますか?

スクリプトから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: -

返品

  1. findコマンドがすべてのディレクトリエントリをまったく同じ順序で返すことを確認しました。

  2. 頑張ったtouch は、ディレクトリ構造の各エントリを同じソースファイルとして参照します。。それでも同じバイトストリームを作成できません。

  3. 結果 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

  4. 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

関連情報