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