J'ai un système de files btrfs d'environ 7G dans un file image 10G img.btrfs
(je l'ai img.btrfs
utilisant btrfs fi resize -3G /mnt
). Comment puis-je find la taille totale (offset de fin d'octet) du système de files, de sorte que je puisse réduire la taille de l'image? C'est à dire find $SIZE
pour
truncate -s $SIZE img.btrfs
Un mécanisme qui s'applique à tout autre système de files à l'intérieur d'un file image serait un plus.
REMARQUE : une chose qui fonctionne est:
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
c'est-à-dire rétrécir les btrfs, réduire l'image d'un peu less (en laissant un overhead 1M), puis augmenter les btrfs au maximum offert par l'image rétrécie.
De façon gênante, le btrfs filesystem show
une valeur approximative si la taille n'est pas un multiple de 1 Mo. Il nécessite également un périphérique de boucle, le btrfs filesystem show img.btrfs
ne fonctionne pas (à partir de jessie Debian). Je ne peux pas find une autre sous-command btrfs
qui aiderait.
Mais le file img.btrfs
renvoie utilement la taille désirée.
$ tronquer -s 16684k /tmp/img.btrfs $ /sbin/mkfs.btrfs /tmp/img.btrfs PETIT VOLUME: forçage de métadonnées / groupes de données mixtes Btrfs v3.17 Voir http://btrfs.wiki.kernel.org pour plus d'informations. Activer la fonction incompat 'mixed-bg': groupes de blocs de données et de métadonnées mixtes Activation de la fonction incompat 'extref': augmentation de la limite du lien fixe par file à 65536 Création d'un bloc de données / métadonnées de taille 1703936 a échoué à ouvrir / dev / btrfs-control en ignorant l'logging du périphérique: Autorisation refusée fs créé label (null) sur /tmp/img.btrfs taille de noeud 4096 taille de champ 4096 taille de segment 4096 taille 16.29MiB $ tronquer -s 32m /tmp/img.btrfs $ file /tmp/img.btrfs /tmp/img.btrfs: Système de files BTRFS secteursize 4096, nodesize 4096, taille 4096, UUID = 61297945-d399-4fdc-ba9f-750ef9f9dfdb, 28672/17084416 octets utilisés, 1 périphériques
Il lit directement la valeur little-endian à 8 octets à l'offset 0x10070. Si vous ne souhaitez pas parsingr la sortie du file
, vous pouvez l'extraire. L'extrait POSIX suivant fait le travail¹:
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 en 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
fonctionne pour d'autres types de filesystems, mais cela n'aide pas beaucoup pour les scripts car la sortie n'est pas standardisée. Je ne peux pas penser à un utilitaire générique avec une interface standard pour tous les filesystems courants, peut-être un outil de virtualisation ou de médecine légale.
¹ Exercice: pourquoi est-ce une utilisation utile du cat
?
Les deux btrfs filesystem show
et l' btrfs filesystem usage
vous donne la taille de l'appareil, en Mebibytes , Gibibytes, ou d'autres puissances de 2. Vous pouvez simplement passer cela pour truncate
avec le suffixe M ou G etc car elles sont également en puissance de 2 (n'utilisez pas le suffixe MB GB!). Par exemple, sur une image 1G réduite de 10M:
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
Il ne devrait pas y avoir de blocs utilisés au-delà de cette taille.