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