Irritante, btrfs filesystem show
retorna um valor aproximado se o tamanho não for um múltiplo de 1MB. Também requer um dispositivo de loop, btrfs filesystem show img.btrfs
não funciona (como no Debian jessie). Não consigo encontrar outro subcomando btrfs
que ajude.
Mas file img.btrfs
de forma útil retorna o tamanho desejado.
$ truncate -s 16684k /tmp/img.btrfs $ /sbin/mkfs.btrfs /tmp/img.btrfs SMALL VOLUME: forcing mixed metadata/data groups Btrfs v3.17 See http://btrfs.wiki.kernel.org for more information. Turning ON incompat feature 'mixed-bg': mixed data and metadata block groups Turning ON incompat feature 'extref': increased hardlink limit per file to 65536 Created a data/metadata chunk of size 1703936 failed to open /dev/btrfs-control skipping device registration: Permission denied fs created label (null) on /tmp/img.btrfs nodesize 4096 leafsize 4096 sectorsize 4096 size 16.29MiB $ truncate -s 32m /tmp/img.btrfs $ file /tmp/img.btrfs /tmp/img.btrfs: BTRFS Filesystem sectorsize 4096, nodesize 4096, leafsize 4096, UUID=61297945-d399-4fdc-ba9f-750ef9f9dfdb, 28672/17084416 bytes used, 1 devices
Ele lê diretamente o valor little-endian de 8 bytes no deslocamento 0x10070. Se você não quiser analisar a saída de file
, poderá extraí-lo. O seguinte trecho POSIX faz o job¹:
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
ou em 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
funciona para alguns outros tipos de sistema de arquivos, mas isso não ajuda muito em scripts porque a saída não é padronizada. Não consigo pensar em um utilitário genérico com uma interface padrão para todos os sistemas de arquivos comuns, talvez alguma ferramenta de virtualização ou análise forense.
¹ Exercício: por que isso é um uso útil de cat
?