debootstrap에 대한 루프백 장치 파일 시스템 이미지의 올바른 크기를 계산하는 방법은 무엇입니까?

debootstrap에 대한 루프백 장치 파일 시스템 이미지의 올바른 크기를 계산하는 방법은 무엇입니까?

저는 debootstrap을 사용하여 이미지 파일을 쓰려는 장치에 대한 rootfs를 생성하고 있습니다. 필요한 rootfs 크기를 계산하려면 다음을 수행합니다.

local SIZE_NEEDED=$(du -sb $CHROOT_DIR|awk '{print $1}')
SIZE_NEEDED=$(($SIZE_NEEDED / 1048576 + 50)) # in MB + 50 MB space
dd if=/dev/zero of=$ROOTFS_IMAGE bs=1M count=$SIZE_NEEDED

보시다시피, 제가 dd계산한 것보다 더 많은 50MB의 패딩이 남아 있습니다.

그런 다음 루프백 장치를 만들고 파티션 테이블과 파일 시스템을 만듭니다.

LO_DEVICE=$(losetup --show -f $ROOTFS_IMAGE)
parted $LO_DEVICE mktable msdos mkpart primary ext4 0% 100%
partprobe $LO_DEVICE
local LO_ROOTFS_PARTITION="${LO_DEVICE}p1"
mkfs.ext4 -O ^64bit $LO_ROOTFS_PARTITION

parted파티션이 전체 가상 디스크를 차지하지는 않지만 충분히 가깝기 때문에 일부 섹터 정렬(?)을 시도하는 것 같습니다 .

그런 다음 새 파티션을 마운트하고 파일 쓰기를 시작합니다. 그런데 마지막에 디스크 공간이 부족해졌습니다!

mount $LO_ROOTFS_PARTITION $LO_MOUNT_POINT
cp -rp $CHROOT_DIR/* $LO_MOUNT_POINT

.....
cp: cannot create directory '/root/buildimage/rootfs_mount/var': No space left on device

이것이 블록 크기 변환 문제인지 아니면 MiB와 MB의 차이인지 의심됩니다. 어느 정도 이미지 크기에 도달하니 여유 공간과 50MB 정도의 패딩이 확보된 것 같습니다. (제 생각에는일부기본적으로 이미지에는 사용 가능한 공간이 있지만 많지는 않습니다. ) 이미지 크기는 2배로 다르지 않으므로 이미지 크기가 커질수록 약간의 크리프나 오버헤드가 증폭됩니다. 이것이 어디서 오는지 잘 모르겠습니다.

맥락상 이것은 제가 마지막으로 부적절한 행동을 한 것입니다:

# du -sb build/rootfs
489889774   build/rootfs

좋습니다. 489MB/1024**2 + 50MB = 517MB 이미지 크기입니다. 그래서 dd그것은 다음과 같습니다:

# dd if=/dev/zero of=build/rootfs.img size=1M count=517
517+0 records in
517+0 records out
542113792 bytes (542 MB, 517 MiB) copied, 2.02757 s, 267 MB/s

디스크에서 약간 더 커 보이는지 확인합니다.

# du -sb build/rootfs.img
542113792   build/rootfs.img

파티션은 다음과 같습니다:

# parted /dev/loop0 print
Model: Loopback device (loopback)
Disk /dev/loop0: 542MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End    Size   Type     File system  Flags
 1      1049kB  542MB  541MB  primary  ext4

그리고 파일 시스템을 마운트합니다:

# df -h /dev/loop0p1
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0p1    492M  482M     0 100% /root/buildimage/build/rootfs_mount

그렇다면 ext4 파일 시스템에 슈퍼블록/저널/등의 오버헤드가 있을 수 있습니까? 크기 계산에서 이를 어떻게 설명합니까?

편집하다:

ext4 오버헤드를 연구합니다.이번 서버 장애 문제.

또한 조사 중mkfs.ext4 옵션예를 들어 -m(보존) 및 다양한 로깅 및 inode 옵션이 있습니다. 일반적으로 말해서, 파일 시스템의 오버헤드가 5%라는 것을 안다면 이를 쉽게 고려할 수 있습니다.

편집 #2:

나는 이것이 du실제 디스크 크기 요구 사항을 과소평가할 수 있다고 생각했습니다(예: 10바이트 파일은 여전히 ​​4k 블록을 차지합니다. 그렇죠?). 저는 몇 가지 다른 옵션을 시도했습니다.

# du -sb build/rootfs        # This is what I was using
489889774   build/rootfs

# du -sm build/rootfs        # bigger
527 build/rootfs

# du -sk build/rootfs        # bigger-est
539088  build/rootfs

또한 매뉴얼 페이지에는 -b이것이 별칭 --apparent-size이며 "실제 디스크 사용량"보다 적을 수 있다고 명시되어 있습니다. 그래서 이것은 아마도 내 수학이 (대부분) 틀린 곳일 것입니다.

답변1

가장 간단한 해결책은 아마도 처음에 공간을 대량으로 과잉 프로비저닝하고 모든 파일을 복사한 다음 resize2fs -M유틸리티를 사용하여 크기를 관리 가능한 최소 수준으로 줄이는 것입니다. 예는 다음과 같습니다.

dir=/home/meuh/some/dir
rm -f /tmp/image
size=$(du -sb $dir/ | awk '{print $1*2}')
truncate -s $size /tmp/image
mkfs.ext4 -m 0 -O ^64bit /tmp/image
sudo mount /tmp/image /mnt/loop
sudo chown $USER /mnt/loop
rsync -a $dir/ /mnt/loop
sync
df /mnt/loop
sudo umount /mnt/loop
e2fsck -f /tmp/image 
resize2fs -M /tmp/image 
newsize=$(e2fsck -n /tmp/image | awk -F/ '/blocks$/{print $NF*1024}')
truncate -s $newsize /tmp/image
sudo mount /tmp/image /mnt/loop
df /mnt/loop
diff -r $dir/ /mnt/loop
sudo umount /mnt/loop

예제 디렉터리 출력에서 ​​일부 발췌:

+ size=13354874
Creating filesystem with 13040 1k blocks and 3264 inodes
+ df /mnt/loop
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/loop1         11599  7124      4215  63% /mnt/loop
+ resize2fs -M /tmp/image
Resizing the filesystem on /tmp/image to 8832 (1k) blocks.
+ newsize=9043968
+ truncate -s 9043968 /tmp/image
+ df /mnt/loop
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/loop1          7391  7124        91  99% /mnt/loop

답변2

기록을 위해 원래 코드를 변경했는데 du -sm이로 인해 문제가 해결된 것 같습니다. 내 생각에 문제의 핵심은 그것이 의 -sb별칭이라는 것입니다 --apparent-size.

또한 ext4에 5%의 오버헤드가 필요하다는 것을 알면 이를 계산에 포함시키는 것은 쉽지만 슈퍼유저로 작성할 때 실패하기 때문에 이것이 실제 문제는 아니라고 생각합니다.

관련 정보