Comment convertir une image disque Linux en un fichier clairsemé?

12

J'ai un tas d'images de disque, faites avec ddrescue, sur une partition EXT, et je veux réduire leur taille sans perdre de données, tout en étant montable.

Comment puis-je remplir l'espace vide du système de fichiers de l'image avec des zéros, puis convertir le fichier en fichier clairsemé afin que cet espace vide ne soit pas réellement stocké sur le disque?

Par exemple:

> du -s --si --apparent-size Jimage.image 
120G Jimage.image
> du -s --si Jimage.image 
121G Jimage.image

Cela n'a en fait que 50 G de données réelles, donc la deuxième mesure devrait être beaucoup plus petite.

Cela remplira censément l'espace vide avec des zéros:

cat /dev/zero > zero.file
rm zero.file

Mais si les fichiers clairsemés sont traités de manière transparente , cela peut en fait créer un fichier clairsemé sans écrire quoi que ce soit sur le disque virtuel, ce qui m'empêche ironiquement de transformer l'image de disque virtuel en un fichier clairsemé lui-même. :) Est-ce que c'est?

Remarque: Pour une raison quelconque, sudo dd if=/dev/zero of=./zero.filefonctionne lorsque catne se trouve pas sur une image disque montée.

endolith
la source
2
L'écriture de zéros dans un fichier ne créera pas un fichier clairsemé. C'est un concept différent. Lorsque vous recherchez / lisez un fichier clairsemé lorsque le système d'exploitation découvre que le bloc de données n'est pas vraiment là (la liste des blocs est vide pour les données de cette région), il (le système d'exploitation) remplit automatiquement comme par magie le tampon de lecture avec zéro octet.
hotei
Remarque: sudo cat /dev/zero > zero.filene fonctionne pas car votre bash (qui s'exécute comme vous, pas root) fait la redirection avant d'exécuter la sudocommande. Voir unix.stackexchange.com/questions/1416/…
Fritz

Réponses:

19

Tout d'abord, les fichiers épars ne sont traités de manière transparente que si vous recherchez, pas si vous écrivez des zéros.

Pour être plus clair, l'exemple de Wikipedia

dd if=/dev/zero of=sparse-file bs=1k count=0 seek=5120

n'écrit pas de zéros, il ouvrira le fichier de sortie, recherchera (sautera) 5 Mo, puis écrira zéro zéros (c'est-à-dire rien du tout). Cette commande ( pas de Wikipedia)

dd if=/dev/zero of=sparse-file bs=1k count=5120

écrira 5 Mo de zéros et ne créera pas de fichier clairsemé!

Par conséquent, un fichier qui n'est pas déjà clairsemé ne deviendra pas par magie clairsemé plus tard.

En second lieu , pour créer un fichier avec beaucoup de zéros rares, vous devez cp il

cp --sparse=always original sparsefile

ou vous pouvez également utiliser l' option --sparse de tar ou rsync .

mihi
la source
1
Selon Wikipedia, l'écriture de zéros avec dd créera un fichier clairsemé. Pouvez-vous expliquer ce que signifie «chercher»?
endolith
1
Et le chat alors? Il n'y a rien dans la page de manuel sur les fichiers clairsemés, donc je suppose que cat /dev/zero > zero.filec'est parfaitement OK pour remplir un espace vide avec des zéros?
Ludwig Weinzierl
2
@endolith: Mise à jour de ma réponse pour clarifier la différence à utiliser ddpour écrire des zéros ou pour rechercher.
mihi
2
@Ludwig Weinzierl: Oui, cette catcommande remplira l'intégralité de votre disque (ou au moins la quantité non réservée à la racine ou par quotas) avec de "vrais" zéros, et ne créera pas de fichiers épars.
mihi
1
@endolith, vous aurez besoin d'espace supplémentaire, oui. mais comme vous pouvez compresser l'archive tar, vous n'aurez besoin que d'espace pour le fichier d'origine et une version compressée du fichier épars.
mihi
12

La façon la plus simple de réduire un fichier en place serait peut-être d'utiliser l' fallocateutilitaire comme suit:

fallocate -v --dig-holes {file_name}

fallocate (1) est fourni par le paquet util-linux sur Debian .

Onlyjob
la source
1
Pour une raison quelconque, le fallocate --dig-holesfichier 103GiB a été créé à partir de l'original 299GiB, tout en cp --sparse=alwaysme donnant 93GiB - tous avec la même somme SHA1 (tailles vérifiées via du -B1Gvs du --apparent-size -B1G). Donc , fallocatesemble donner des résultats inférieurs.
Ruslan
3

Modification de ma réponse pour l'exhaustivité:

  1. Ballon vide de l'espace FS avec des zéros (AVERTISSEMENT: cela change votre image disque):

losetup --partscan --find --show disk.img

Supposons qu'il donne / dev / loop1 comme disque et qu'il n'y ait qu'une seule partition, sinon nous devons répéter cela pour chaque partition avec FS montable (ignorer la partition de swap, etc.).

mkdir -p /mnt/tmp mount /dev/loop1p1 /mnt/tmp dd if=/dev/zero of=/mnt/tmp/tempfile

Laissez-le finir à l'échec avec ENOSPC.

/bin/rm -f /mnt/tmp/tempfile umount /mnt/tmp losetup -d /dev/loop1

  1. Copiez dans une image clairsemée:

'dd' a une option pour convertir un fichier avec des zéros en un fichier clairsemé:

dd if=disk.img of=disk-sparse.img conv=sparse

Lam Das
la source
1
Oui, cette option ne date pas du moment où OP l'a demandé. C'était plus de "laisser une miette de pain pour les autres chercheurs" ... :-)
Lam Das
1
selon le type de système de fichiers, zerofreepeut être plus rapide que de monter et d'écrire des zéros sur le système de fichiers, et de réduire l'image disque si elle contient déjà beaucoup de zéros.
mihi
2

Voulez-vous dire que votre image créée par ddrescue est, disons, de 50 Go et en réalité quelque chose de bien moins suffirait?

Si tel est le cas, ne pourriez-vous pas tout d'abord créer une nouvelle image avec dd:

dd if=/dev/zero of=some_image.img bs=1M count=20000

puis créez-y un système de fichiers:

mkfsofyourchoice some_image.img

puis montez simplement l'image et copiez tout de l'ancienne image à la nouvelle? Cela marcherait-il pour toi?

Janne Pikkarainen
la source
2

PartImage peut créer des images de disque qui stockent uniquement les blocs utilisés d'un système de fichiers, réduisant ainsi considérablement l'espace requis en ignorant les blocs inutilisés. Je ne pense pas que vous puissiez monter directement les images résultantes, mais en allant:

image -> partimage -> image -> cp --sparse=alway

Devrait produire ce que vous voulez (peut-être même possible de coller la dernière étape, je n'ai pas essayé).

Grumbel
la source
1
Malheureusement, les images créées par partimage ne peuvent pas être montées sans les étendre à nouveau, ce qui les rend appropriées uniquement à des fins d'archivage.
Perkins
0

Il existe maintenant un outil appelé virt-sparsify qui fera cela. Il remplit l'espace vide avec des zéros, puis copie l'image dans un fichier clairsemé. Cela nécessite cependant l'installation de nombreuses dépendances.

endolith
la source
-2

Je suppose que vous aurez besoin d'un programme personnalisé écrit dans cette spécification si c'est vraiment ce que vous voulez faire. Mais est-ce ...?

Si vous avez réellement beaucoup de zones entièrement nulles, tout bon outil de compression le réduira considérablement. Et essayer d'écrire des fichiers clairsemés ne fonctionnera pas dans tous les cas. Si je me souviens bien, même les fichiers clairsemés occupent au moins 1 bloc de stockage de sortie où le bloc d'entrée contient TOUT bit différent de zéro. Par exemple - disons que vous aviez un fichier qui avait en moyenne même 1 bit non nul par bloc de 512 octets - il ne peut pas être écrit "avec parcimonie". Au fait, vous n'allez pas perdre de données si vous compressez le fichier avec zip, bzip, bzip2 ou p7zip. Ils ne sont pas comme la compression mpeg ou jpeg qui est avec perte.

D'un autre côté, si vous devez effectuer des lectures aléatoires dans le fichier, la compression peut être plus problématique que cela en vaut la peine et vous revenez à l'écriture clairsemée. Un programmeur C ou C ++ compétent devrait être capable d'écrire quelque chose comme ça en une heure ou moins.

hotei
la source
Intéressant - un downvote pourtant je remarque qu'il n'y a aucune réfutation de ce que j'ai écrit. Si elle est précise mais inutile, ce n'est pas une raison pour revenir en arrière. Si ce n'est pas précis et pas utile, cela le mérite.
hotei
Je vois ailleurs que l'OP avait une question concernant le montage d'images compressées. Je suppose que c'est une continuation de ce fil. Sachant que je peux maintenant voir pourquoi ma suggestion de compression n'a pas été acceptée. Un simple programme C est toujours un moyen facile de créer des fichiers clairsemés. MAIS - le système d'exploitation (non spécifié) vous permettra-t-il de monter une image ISO clairsemée. Aussi difficile que soit le monteur ISO Ubuntu, je ne suis pas sûr à 100% que cela fonctionnera non plus ... mais bonne chance dans tous les cas.
hotei
4
pourquoi réinventer la roue? cp --sparse=alwaysfonctionne bien
mihi
@mihi: C'est une bonne idée. Je ne connaissais pas l'option clairsemée car elle n'est pas disponible dans les versions BSD ( freebsd.org/cgi/… ) et je n'ai jamais eu besoin de consulter une page de manuel Linux pour cp (jusqu'à aujourd'hui).
hotei
Une façon d'avoir vos images compressées et de les monter aussi est de simplement les stocker sur un système de fichiers qui prend en charge la compression native. Rend la récupération de données horrible en cas de panne de disque, mais c'est à cela que servent les sauvegardes, non?
Perkins