동일한 바이너리 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 번호를 일관되게 복사할 수 있지만, 동일한 시점에 존재하는 두 개의 별도 디렉토리 구조가 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

관련 정보