Comment redimensionner un fichier img créé avec dd?

19

J'ai une image DD d'une carte SD de 4 Go qui a deux partitions, ces deux partitions n'utilisent qu'environ 800 Mo et en tant que tel, je souhaite réduire la taille de l'img fie.

Quelqu'un connaît-il un moyen de supprimer "l'espace libre" du fichier img?

A_Porcupine
la source
vous voudrez peut-être ajouter le résultat souhaité. ie: image de retour sur la carte, à stocker sur CD.
Wayne

Réponses:

8

Assurez-vous d'abord que l'espace libre est réellement vide et ne contient pas de restes de fichiers supprimés. La façon la plus simple d'y parvenir est de créer un énorme fichier sur le disque, ne contenant que des octets nuls, puis de le supprimer.

# losetup --find --partscan foo.img
# lsblk
NAME      MAJ:MIN RM    SIZE RO TYPE MOUNTPOINT
loop0       7:0    0   4096M  0 loop 
├─loop0p1 259:0    0   2048M  0 loop 
└─loop0p2 259:1    0   2048M  0 loop 
# for part in /dev/loop0p*; do
    mount $part /mnt
    dd if=/dev/zero of=/mnt/filler conv=fsync bs=1M
    rm /mnt/filler
    umount /mnt
  done
dd: error writing ‘/mnt/filler’: No space left on device
dd: error writing ‘/mnt/filler’: No space left on device
# losetup --detach /dev/loop0

Ensuite, compressez-le avec un outil comme gzipou xz. Même aux niveaux de compression les plus bas, une longue série de zéros se comprime bien:

# ls -s
4096M foo.img
# gzip foo.img
# ls -s
11M foo.img.gz

Notez que vous devez décompresser l'image lors de la réécriture sur le disque. Cela le décompressera «en direct»:

# cat foo.img.gz | gunzip | dd of=/dev/sda

Notez que le périphérique de sortie (sda) doit être de taille suffisante pour s'adapter à l' image d' origine , sinon les données seront perdues ou corrompues.


Une autre méthode, si vous souhaitez continuer à utiliser l'image - par exemple avec une machine virtuelle - consiste à convertir l'image brute en l'un des formats d'image utilisés par le logiciel de virtualisation; par exemple qcow2 pour Qemu, VDI pour VirtualBox ou VMDK pour VMware.

Notez que cela vous oblige toujours à préparer l'image en nettoyant l'espace libre en utilisant la méthode ci-dessus.

# qemu-img convert -f raw -O qcow2 foo.img foo.qcow

# qemu-img convert -f raw -O vmdk foo.img foo.vmdk

Mais s'il doit être réécrit sur un vrai disque, vous devez le reconvertir en image brute.

user1686
la source
1
Comment pouvez-vous être sûr que tous les fichiers actuellement stockés sur les partitions ne sont pas physiquement dispersés sur le disque?
Valerio Santinelli
car je suppose que les fichiers ne sont pas écrits séquentiellement sur le disque et si un fichier se trouve à la fin du stockage, lorsque je réduis la taille, je perdrai le contenu de ce fichier.
Valerio Santinelli
Parce que l'OP demande comment réduire une image disque sans perdre de données. Si vous tronquez une image à une certaine taille, vous ne pouvez pas être sûr que les données seront préservées.
Valerio Santinelli
@ValerioSantinelli: Où dois-je suggérer exactement de tronquer l'image?
user1686
1
@ValerioSantinelli: en utilisant l'outil de redimensionnement du système de fichiers approprié pour votre système de fichiers, par exemple resize2fsou ntfsresize(Linux n'a pas d'outil pour FAT), avant de l'écrire sur le plus petit appareil, ou en créant un nouveau système de fichiers et en copiant uniquement les fichiers.
user1686
22

L'utilisation resize2fsest beaucoup plus facile

resize2fs -M xxx.img

il vous sera d'abord demandé d'e2fsck - donc:

e2fsck -f -y xxx.img

(l'image ne doit PAS être montée!)

Remarque: cela ne fonctionnera que si l'image est d'une seule partition, si c'est un périphérique de bloc entier avec plusieurs partitions, voir la réponse ci-dessus ...

Serge Wagner
la source
Juste une note: pour plusieurs partitions, utilisez losetup --find --partscan xxx.imgpour configurer le fichier image comme périphérique de boucle. puis exécutez lsblkpour trouver les partitions du périphérique de boucle.
Yihui Xiong
Il semble que cela ne fonctionne pas pour une image ISO contenant un système d'exploitation. Après le redimensionnement, le système ne démarre pas.
SR
@SR Linux système d'exploitation?
Rolf
1
C'est une très bonne réponse, mais resize2fsne concerne que extNles partitions de type. D'autres types de partitions nécessiteront d'autres outils.
Rolf
2

Je l'ai également essayé avec qemu-img , et cela a fonctionné comme un charme:

qemu-img resize test.img 2G

Nous redimensionnons le test.imgpour le rendre 2G (2 Go).

A fonctionné sans faille pour moi.

Phil Roggenbuck
la source
1
Génial, a fonctionné sans faille pour moi aussi, en compressant une image Raspbian. entièrement fonctionnel!
ffleandro
Eh bien, tout fonctionne, mais après le démarrage, l'exécution df -haffiche la taille d'origine. Comment est-ce possible?
ffleandro
Apparemment, qemu-img ne fait pas la table de partition, alors comment compresser le .img?
ffleandro
Je peux redimensionner un disque .img à 1 Mo, ce qui casse définitivement l'image du disque. Une idée pour rendre le redimensionnement plus sûr?
lesca
1

J'ai utilisé l'approche gparted avec mon ordinateur Ubuntu 16.10:

1) Mappez le fichier img à la prochaine partition de boucle disponible avec losetup, comme décrit dans les articles précédents comme ci-dessus

2) Vérifiez avec lsblkquel lecteur de boucle votre fichier image est mappé, par exemple/dev/loop0

3) Exécuter sudo gparted /dev/loop0

4) Rétrécir la ou les partitions de boucle comme jugé approprié; veuillez vous assurer que ces partitions sont démontées.

5) Exécutez fdisk /dev/loop0, puis entrez p, cela vous montrera la taille du bloc et le numéro de bloc de fin des différentes partitions.

6) Exécuter dd if=/dev/loop0 of=shrunk_image_file.img, appliquer à cette commande les options bs=[BlockSize]et count=[EndBlockNumberOfLastLoopPartition+1]vous aurez un fichier image et rétrécis rightsized.

VeryNoob
la source