직장에서는 Oracle VM 환경의 일부로 스파스 파일을 게스트 디스크 이미지로 사용합니다. 동료들에게 몇 가지 질문을 한 후(현재 답변됨) 희소 파일에 대한 더 많은 질문과 아마도 더 일반적인 inode 구조에 대한 질문이 남았습니다. stat(2) 및 statfs(2)(FreeBSD(위))를 읽어보면 다음과 같은 인상을 받을 수 있습니다. C를 더 많이 알면 이해하기가 더 쉬울 텐데 아쉽게도 C에 대한 지식은 기껏해야 미미합니다...
나는 이것 중 일부가 파일 시스템 유형에 따라 다르다는 것을 알고 있습니다. 저는 FreeBSD/Solaris 및 ext4의 UFS에 가장 관심이 있습니다. ZFS가 있으면 더할 나위 없이 좋을 것입니다. 하지만 저는 기대를 저버리지 않습니다. :)
저는 정기적으로 Solaris 10, FreeBSD 10.3 및 CentOS 6.7을 사용합니다. 여기의 명령은 CentOS 6.7 VM에서 실행되지만 FreeBSD와 상호 참조되었습니다. 가능하다면 POSIX 관점에서 이해하고 싶습니다. 가능하지 않다면 Linux보다 FreeBSD를 선호합니다.
다음 명령 세트를 고려하십시오.
printf "BIL" > /tmp/BIL
dd of=/tmp/sparse bs=1 count=0 seek=10
dd if=/tmp/BIL of=/tmp/sparse bs=1 count=3 seek=10
dd if=/tmp/BIL of=/tmp/sparse bs=1 count=3 seek=17
dd of=/tmp/sparse bs=1 count=0 seek=30
dd if=/tmp/BIL of=/tmp/sparse bs=1 count=3 seek=30
파일에 /tmp/BIL
포함되어야 하는 내용(16진수) 이므로 파일을 4942 004c
보면 파일 전체에서 다음 조합 중 일부를 볼 수 있습니다.hexdump
/tmp/sparse
%>hexdump sparse
0000000 0000 4942 004c 0000 0000 4942 004c 0000
0000010 4200 4c49 0000 0000 0000 0000 0000 4942
0000020 004c
0000021
%>cat sparse
BILBILBILBIL%
1. "BIL"이 두 번째로 나타날 때 순서가 잘못된 이유는 무엇입니까?그 4200 4c49
대신에 4942 004c
? 이것은 dd
작성된 세 번째 명령입니다.
2. 다른 도구는 cat
올바른 순서로 인쇄하는 방법을 어떻게 알 수 있습니까?
다음을 사용하여 ls
사용된 공간과 할당된 블록을 확인할 수 있습니다 .
%>ls -ls /tmp/sparse
8.0K -rw-r--r--. 1 bil bil 33 May 26 14:17 /tmp/sparse
주장된 크기는 33바이트이지만 할당된 크기는 8KB(파일 시스템 블록 크기는 4K)임을 알 수 있습니다.
3. 이와 같은 프로그램은 ls
"소위" 크기와 할당된 크기를 어떻게 구별합니까?
inode에 저장된 "소위" 숫자가 직접 및 간접 블록을 순회하여 계산되는 반면 할당된 크기는 직접 및 간접 블록을 순회하여 계산되는지 궁금합니다. 순회가 정확하지 않기 때문에 이는 정확할 수 없습니다. 계산을 수행하면 시간이 걸리며 ls
매우 큰 파일의 경우에도 빠른 반환과 같은 도구가 필요합니다.
4. inode 정보를 쿼리하는 데 어떤 도구를 사용할 수 있습니까?
알겠습니다 stat
만, 인덱스 노드의 모든 필드의 값이 출력되지 않는 것 같습니다...
5. 직접 블록과 간접 블록을 순회할 수 있는 도구가 있나요?
데이터가 어떻게 저장되는지 더 잘 이해하기 위해 디스크의 모든 주소와 그 내용을 살펴보는 것은 흥미로울 것입니다.
위의 다른 명령 다음에 다음 명령을 실행하면 파일이 /tmp/sparse
잘립니다.
%>dd of=/tmp/sparse bs=1 count=0 seek=5
%>hexdump sparse
0000000 0000 4942 004c
0000005
6. dd
파일이 잘리고 dd
다른 도구가 파일 중간에 쓸 수 있는 이유는 무엇입니까?
마지막으로, 스파스 파일은 공간을 사전 할당하는 좋은 아이디어처럼 보이지만 명령이 파일을 자르거나 임의로 늘리지 않는다는 파일 시스템이나 운영 체제 수준의 보장은 없는 것 같습니다.
7. 희소 파일이 축소/증가하는 것을 방지하는 메커니즘이 있습니까? 그렇지 않다면 스파스 파일이 왜 유용한가요?
위의 각 문제는 별개의 문제일 수 있지만 모두 근본적인 이해와 관련되어 있기 때문에 분석할 수는 없습니다.
답변1
몇 가지 빠른 답변: 첫째, 스파스 파일을 생성하지 않습니다. 다음 추가 명령을 사용해 보세요.
dd if=/tmp/BIL of=/tmp/sparse seek=1000
ls -ls /tmp/sparse
크기는 512003바이트인데 8블록만 점유된 것을 볼 수 있습니다. NULL 바이트는 파일 시스템에서 희소할 수 있도록 전체 블록을 차지하고 블록 경계에 있어야 합니다.
두 번째로 나타나는 "BIL"이 순서가 잘못된 이유는 무엇입니까?
왜냐하면 당신은 little endian 시스템을 사용하고 있고 출력을 짧은 형식으로 쓰고 있기 때문입니다. 고양이처럼 바이트를 사용하세요.
고양이와 기타 도구는 올바른 순서로 인쇄하는 방법을 어떻게 알 수 있나요?
바이트 단위로 작동합니다.
ls와 같은 프로그램은 "소위" 크기와 할당된 크기를 어떻게 식별합니까?
ls
그리고stat(2)
2개의 값을 반환하는 시스템 호출을 사용하여 다음과 같이 진행합니다.st_size; /* total size, in bytes */ blkcnt_t st_blocks; /* number of 512B blocks allocated */
inode 정보를 쿼리하는 데 어떤 도구를 사용할 수 있나요?
통계는 좋습니다.
직접 및 간접 블록을 반복할 수 있는 도구가 있습니까?
hdparm --fibmap
ext2/3/4에서는 다음 파일 이름을 사용할 수 있습니다 .$ sudo hdparm --fibmap ~/sparse filesystem blocksize 4096, begins at LBA 25167872; assuming 512 byte sectors. byte_offset begin_LBA end_LBA sectors 512000 226080744 226080751 8
다음을 사용할 수도 있습니다
debugfs
.$ sudo debugfs /dev/sda3 debugfs: stat <1040667> Inode: 1040667 Type: regular Mode: 0644 Flags: 0x0 Generation: 1161905167 Version: 0x00000000 User: 127 Group: 500 Size: 335360 File ACL: 0 Directory ACL: 0 Links: 1 Blockcount: 664 Fragment: Address: 0 Number: 0 Size: 0 ctime: 0x4dd61e6c -- Fri May 20 09:55:24 2011 atime: 0x4dd61e29 -- Fri May 20 09:54:17 2011 mtime: 0x4dd61e6c -- Fri May 20 09:55:24 2011 Size of extra inode fields: 4 BLOCKS: (0-11):4182714-4182725, (IND):4182726, (12-81):4182727-4182796 TOTAL: 83
dd가 내 파일을 자르고 dd 또는 다른 도구가 파일 중간에 쓸 수 있는 이유는 무엇입니까?
네,
dd
가운데까지 쓰시면 됩니다. 에 추가하세요conv=notrunc
.희소 파일이 축소되거나 커지는 것을 방지하는 메커니즘이 있습니까? 그렇지 않다면 스파스 파일이 왜 유용한가요?
습관. 공간을 덜 차지하기 때문이죠.
파일의 희소성은 프로그램에 완전히 투명해야 합니다. 이는 때때로 프로그램이 파일을 업데이트할 때 희소성이 손실될 수 있음을 의미합니다.
일부 복사 유틸리티에는 희소성을 유지하는 옵션이 있습니다(예 tar --sparse
: ) rsync --sparse
.
cp --sparse=always
를 사용하여 파일에서 적절하게 정렬된 0 블록을 희소 공간으로 명시적으로 변환할 수 있으며, 반대로 를 사용하여 희소 공간을 실제 0으로 변환할 수 있습니다 cp --sparse=never
.
답변2
Linux에서 파일 레이아웃을 덤프하는 더 나은 도구는 소프트웨어 패키지 filefrag
에 포함된 유틸리티 입니다 e2fsprogs
. 이렇게 하면 파일의 모든 범위가 효율적이고 간결하게 덤프됩니다.
$ dd of=/var/tmp/sparse if=/dev/zero count=1
$ dd of=/var/tmp/sparse if=/dev/zero seek=1000 count=1
$ filefrag -v /var/tmp/sparse
Filesystem type is: ef53
File size of /var/tmp/sparse is 512512 (126 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 0: 3441408.. 3441408: 1:
1: 125.. 125: 3441533.. 3441533: 1: 3441409: last,eof
/var/tmp/sparse: 2 extents found
FIEMAP ioctl은 가장 일반적인 Linux 파일 시스템(ext4, XFS, Btrfs 등)에서 작동하지만 아직 ZFS에서는 작동하지 않습니다(개발 중이지만).