Convertir l'image d'une partition en image d'un disque avec table de partition

20

J'ai une image d'une partition existante générée avec dd if=/dev/sdXN of=image.bin. Maintenant, je veux utiliser cette image comme base pour une machine virtuelle. Je sais comment convertir l'image dans un format que VirtualBox peut utiliser.

Le problème est que l'image "disque" n'est vraiment que l'image d'une partition et ne contient donc pas de MBR ou de table de partition. Cela rend très difficile le démarrage de la machine virtuelle.

Existe-t-il un moyen simple, étant donné une image d'une partition, de créer une image disque appropriée, y compris une table de partition?

Mika Fischer
la source

Réponses:

13

Vous pouvez le faire sur la machine hôte. La plupart des outils comme fdiskfonctionneront sur les fichiers et kpartxvous donneront accès aux partitions d'un fichier.

  1. Créez une nouvelle image creuse de 100 Go vide (agrandissez-la légèrement par rapport à la taille de l'image de la partition)

    dd if=/dev/zero of=myvm.img bs=1G count=0 seek=100
    
  2. Partitionnez le fichier image avec fdisk

    fdisk myvm.img
    
  3. Rendre les partitions du fichier image disponibles sur les appareils individuels

    sudo kpartx -a myvm.img
    
  4. Copiez l'image de la partition dans la partition

    sudo cp image.bin /dev/mapper/loop0p1
    
  5. Étendez le système de fichiers pour remplir toute la partition

    sudo resize2fs /dev/mapper/loop0p1
    
  6. Fermez les partitions

    sudo kpartx -d myvm.img
    
  7. Démontez le dispositif de bouclage

    sudo losetup -D
    
mgorven
la source
Cela ne ferait-il pas en sorte que la partition créée dans l'image «ne corresponde pas» à la longueur de la partition imagée? Et existe-t-il un moyen de résoudre ce problème? Et un gestionnaire de système de fichiers "assez intelligent" serait-il capable de dire qu'il n'utilise pas toute la taille de la partition et de se développer pour s'adapter?
killermist
@killermist Réponse mise à jour.
mgorven
C'est une bonne réponse. Connaissez-vous un moyen d'éviter de copier le tout dans le processus?
Mika Fischer
@MikaFischer Malheureusement non, car la table de partition doit exister avant la partition, et je ne connais aucun mécanisme pour ajouter des données à un fichier.
mgorven
Je pense que la réponse de Harun est meilleure car elle est facile à faire et peut être scriptée.
philcolbourn
9

Je suis sûr que le problème d'origine a été résolu il y a longtemps, mais pour toute personne ayant un problème similaire:

Une façon d'éviter de copier l'image entière serait de créer une image au format .vmdk qui fait référence à des fichiers d'extension distincts pour la table de partition et pour le contenu de la partition.

J'ai cet extrait qui traîne dans un fichier .vmdk d'un test que j'ai fait il y a un moment:

RW 63 FLAT "parttable.bin" 0
RW 585937489 FLAT "partition-image.bin" 63

Cela signifie que les 63 secteurs à partir de l'offset 0 sont lus à partir du fichier brut "parttable.bin", mais que le secteur 63 et les suivants proviennent du vidage de partition brut "partition-image.bin". (Bien sûr, remplacez 63 par le décalage réel vers la première partition, généralement 2048 de nos jours).

Le résultat final est que, de l'intérieur de la VBox, il semble que vous ayez ajouté la table de partition à l'avant de l'image de partition, sans avoir à effectuer la longue opération de copie.

Partitionnez le lecteur à partir de la machine virtuelle et, si vous obtenez vos bons décalages, vous devriez voir le contenu de votre image de partition à l'intérieur de la partition nouvellement créée.

Harun
la source
2
Je pense que le «63» sur la deuxième ligne doit être 0 si partition-image.bin est une image de partition. Je viens de faire quelque chose comme ça et j'avais besoin de mettre ce décalage dans le fichier image de partition à zéro. philatwarrimoo.blogspot.com.au/2014/01/…
philcolbourn
Génie. Je devais juste faire cela pour utiliser une partition Windows pour une machine virtuelle sur un hôte Linux, et c'est la seule chose qui a fonctionné, en utilisant les étapes de @philcolbourn: superuser.com/a/804396/93066
bmaupin
Que devrait contenir le reste du fichier vmdk?
gozzilli
1
@gozzilli Le reste du fichier est un tas de détails comme les numéros de version des fichiers, le type d'adaptateur de disque, les uuids et la géométrie du disque. Je ne sais pas comment écrire ces bits. Je recommanderais simplement d'utiliser un outil pour créer un vmdk pointant sur l'image disque, puis de modifier uniquement les lignes décrivant où obtenir l'en-tête de partition supplémentaire.
Harun
3

Problème intéressant. Voici ce que je ferais:

  1. Créez la machine virtuelle avec un disque de taille appropriée, puis démarrez-le à partir d'un CD de récupération.
  2. Accédez en quelque sorte à votre image disque existante (nfs, cifs, etc.).
  3. Créez les partitions dont vous aurez besoin sur le disque local de la machine virtuelle.
  4. Utilisez dd pour écrire l'image de partition dans la partition du disque vm.

Après cela, vous devrez mettre à jour votre chargeur de démarrage. En supposant que vous utilisez GRUB, montez la partition nouvellement écrite, puis chrootez dessus et exécutez update-grub(attention cependant, vous devrez peut-être ajuster ses fichiers de configuration avant que cela fonctionne correctement).

Bonne chance!

bahamat
la source
2

Vous pouvez redimensionner le système de fichiers en place, avec GParted.

Créez l'image de test:

dd if=/dev/zero of=extfs bs=1M count=20
mkfs.ext4 extfs

Je n'utilise pas resize2fs, car il redimensionne le fichier, plutôt que de laisser de l'espace libre.

sudo losetup /dev/loop0 extfs
sudo ln -s /dev/loop0 /dev/loop0p1 # needed for GParted to be able to resize it
gksudo gparted /dev/loop0

Libérez 1 Mo au début.

sudo rm /dev/loop0p1
sudo losetup -d /dev/loop0

Enfin, créez la table de partition.

fdisk extfs

Réglez le premier secteur sur 2048 (2048 secteurs * 512 B / secteur = 1 Mo), le dernier secteur par défaut (c'est-à-dire la fin de l'image).

ignis
la source
1

Personnellement, je préfère ajouter en utilisant dd.

Je suppose des secteurs de 512 octets ici. Il peut y avoir un cas pour les secteurs de 2048 octets, alors échangez simplement les chiffres et faites le calcul.

Dans chaque cas, j'utilise un fichier de test de 512 Mo par exemple:

dd if=/dev/zero of=testfs.img bs=512 count=1M mkfs.ext4 testfs.img

MBR

Composer l'image

Personnellement, je préfère ajouter le premier MB (2048 secteurs) à son début:

dd if=testfs.img skip=2048 bs=512 of=full.img

Enfin, exécutez fdisk pour créer la table de partition (ou copiez la vôtre), j'ai créé 1 partition en utilisant les valeurs par défaut.

Vérification

Pour vérifier, créez des partitions de boucle et détectez automatiquement:

sudo losetup -fP full.img

Et exécutez filesur le périphérique de bouclage partitionné résultant:

sudo file -s /dev/loop2p1 /dev/loop2p1: Linux rev 1.0 ext4 filesystem data, UUID=ae2945fd-54b5-486f-8dd0-9b18d6ae01b4 (extents) (large files) (huge files)

GPT

Composer l'image

Personnellement, je préfère ajouter le premier Mo (2048 secteurs, car gdisk aura par défaut ce nombre car il est aligné sur 1 Mo) à son début pour le MBR de début et 34 secteurs à sa fin (ou 2048 pour un MB complet) pour la fin GPT (le secteur final peut être différent). Omettre le GPT final peut vous faire perdre des données:

dd if=testfs.img skip=2048 bs=512 of=full.img dd if=/dev/zero seek=1050624 bs=512 of=full.img count=34

Enfin, exécutez gdisk pour créer la table de partition (ou copiez la vôtre), j'ai créé 1 partition en utilisant les valeurs par défaut.

Vérification

Pour vérifier, créez des partitions de boucle et détectez automatiquement:

sudo losetup -fP full.img

Et exécutez filesur le périphérique de bouclage partitionné résultant:

sudo file -s /dev/loop2p1 /dev/loop2p1: Linux rev 1.0 ext4 filesystem data, UUID=ae2945fd-54b5-486f-8dd0-9b18d6ae01b4 (extents) (large files) (huge files) Cette méthode garantit l'absence de devinettes, de redimensionnement ou d'alignement manuel.

Dan Dart
la source
Comment trouvez-vous le secteur final de l'image en gpt
Anwar
Quand je lance ça, sudo file -s /dev/loop11p1je l'ai /dev/loop11p1: data. Ce qui était auparavant un système de fichiers ext4. Et le full.img résultant est plus petit. Je pense que la solution est inversée.
Anwar
Je pense que vous voulez dire seek=2048dans cette commande dd if = testfs.img skip = 2048 bs = 512 of = full.img
Anwar