我在 10G 图像文件中有一个大约 7G 的 btrfs 文件系统img.btrfs
(我使用 缩小了它btrfs fi resize -3G /mnt
)。如何找到文件系统的总大小(结束字节偏移量),以便缩小图像大小?$SIZE
即找出
truncate -s $SIZE img.btrfs
适用于图像文件内任何其他文件系统的机制将是一个优点。
笔记: 一件事做工作是:
INITIAL=$(stat -c %s img.btrfs)
mount img.btrfs /mnt
btrfs fi resize -$NBYTES /mnt
umount /mnt
truncate -s $((INITIAL - NBYTES + 1024*1024)) img.btrfs
mount /img.btrfs /mnt
btrfs fi resize max /mnt
即缩小 btrfs,将图像缩小一点(留下 1M 开销),然后将 btrfs 增大到缩小图像所能提供的最大值。
答案1
令人烦恼的是,btrfs filesystem show
如果大小不是 1MB 的倍数,则返回一个近似值。它还需要一个循环设备,但btrfs filesystem show img.btrfs
不起作用(从 Debian jessie 开始)。我找不到另一个btrfs
有帮助的子命令。
但file img.btrfs
有助于返回所需的大小。
$ 截断-s16684k/tmp/img.btrfs $ /sbin/mkfs.btrfs /tmp/img.btrfs SMALL VOLUME:强制混合元数据/数据组 Btrfs v3.17 请参阅 http://btrfs.wiki.kernel.org 了解更多信息。 打开不兼容功能“mixed-bg”:混合数据和元数据块组 打开不兼容功能“extref”:将每个文件的硬链接限制增加到 65536 创建了大小为 1703936 的数据/元数据块 无法打开 /dev/btrfs-control 跳过设备注册:权限被拒绝 fs 在 /tmp/img.btrfs 上创建了标签(空) 节点大小 4096 叶大小 4096 扇区大小 4096 大小16.29MiB $ 截断-s 32m /tmp/img.btrfs $ 文件 /tmp/img.btrfs /tmp/img.btrfs:BTRFS 文件系统扇区大小 4096,节点大小 4096,叶大小 4096,UUID=61297945-d399-4fdc-ba9f-750ef9f9dfdb,28672/17084416使用的字节数,1 个设备
它直接读取偏移量 0x10070 处的 8 字节小端值。如果您不想解析 的输出file
,可以将其提取。以下 POSIX 代码片段完成了这项工作:
size_hex=$(cat /tmp/img.btrfs | dd ibs=8 skip=8206 count=1 2>/dev/null | od -tx8 -An | tr abcdef ABCDEF | tr -dc 0-9ABCDEF)
[ ${#size_hex} -eq 16 ] &&
{ echo "ibase=16; $size_hex"; } | bc
或者在 Perl 中:
</tmp/btrfs.img perl -e 'seek(STDIN, 0x10070, 0) or sysread(STDIN, $_, 0x10070) == 0x10070 or die "seek"; sysread(STDIN, $_, 8) == 8 or die "read"; print unpack("Q<", $_), "\n"'
file
适用于某些其他文件系统类型,但这对脚本没有多大帮助,因为输出未标准化。我想不出一个具有适用于所有常见文件系统的标准接口的通用实用程序,也许是一些虚拟化或取证工具。
1练习:为什么这是 的有用用途cat
?
答案2
两者都btrfs filesystem show
给出btrfs filesystem usage
了设备的大小,单位为兆字节、Gibibytes 或其他 2 的幂。您可以将其与后缀 M 或 G 等一起传递,truncate
因为它们也是 2 的幂(不要使用后缀 MB GB!)。例如,在缩小10M的1G图像上:
sudo btrfs fi show /mnt
devid 1 size 1014.00MiB used 12.00MiB path /dev/loop0
sudo btrfs fi usage /mnt
Device size: 1014.00MiB
SIZE=1014M # not MB!
truncate -s $SIZE img.btrfs
不应使用超过此大小的任何块。