Disk-Usage

如何計算用於 debootstrap 的環回設備文件系統映像的正確大小?

  • March 11, 2018

我正在使用 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

正如你所看到的,我留下了 50MB 的填充超出了dd我需要的計算量。

然後我創建環回設備,創建分區表和文件系統:

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 的填充。(預設情況下,我想要圖像中的一些可用空間,但不是很多。)圖像大小並沒有縮小兩倍,所以隨著圖像大小變大,我會放大一些蠕變或成本我不確定它來自哪裡。

對於上下文,這是我做的最後一個不適合的:

# 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 成本,例如這個 ServerFault question

還研究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,可以小於“實際磁碟使用量”。所以這可能是(大部分)我的數學錯誤的地方。

可能最簡單的解決方案是最初大量過度配置空間,複製所有文件,然後用於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

引用自:https://unix.stackexchange.com/questions/353156