27 Apr 2018, 00:00

Monter une image de disque complet sous Linux (y compris Gparted, et VirtualBox)

Présentation et analyse

Si on a créé une image entière de disque (par exemple avec dd , dcfldd ou bien ddrescue), il est possible de la monter au sein du système, pour qu’elle soit détectée par le noyau, par Gparted, et même transférable (en tant que disque brut) à une machine virtuelle sous VirtualBox.

Dans mon exemple, on a le fichier /home/user/sdi.img, qui est une image complète d’un disque (avec le boot code et la table de partition, dans cet exemple au format MBR).

On vérifie la structure de l’image (qui doit être une copie du disque, donc avec une ou des partitions) : sudo fdisk -l ~/sdi.img. Chez moi, ça donne :

Disk sdi.img: 1,8 TiB, 2000399892480 bytes, 3907031040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x909b28dc

Device     Boot Start        End    Sectors  Size Id Type
sdi.img1   *     2048 3907031039 3907028992  1,8T  7 HPFS/NTFS/exFAT

J’ai bien la partition sdi.img1, formattée en NTFS.

Montage du disque complet

On utilise pour ça la commande losetup (en root).
Si on l’exécute toute seul, elle nous liste les périphériques actuellement montés. Par défaut, ce devrait être vide.
Si on l’exécute avec le paramètre -f, elle nous donne le premier périphérique disponible pour monter une image. Par défaut, ce devrait être /dev/loop0.

On monte l’image sur le périphérique loop : sudo losetup -P /dev/loop0 ~/sdi.img.
L’image est bien montée (vérifiable avec losetup sans argument), mais la partition n’est pour l’instant pas prise en compte par le noyau. (EDIT : plus vrai avec l’option -P)

Prise en compte de la table de partition par le noyau

EDIT : l’option losetup -P permet de faire cette étape automatiquement. Ceci dit c’est toujours bien d’avoir un peu les détails des rouages :)

Pour ceci : sudo partprobe /dev/loop0.

Ceci va dire au noyau d’aller réactualiser la table des partitions connues (en l’occurence en n’analysant que le périphérique loop0). Ceci a du créer les périphériques pour chacune des partitions de l’image (pour moi une seule). On vérifie : ls -l /dev/loop0* qui donne chez moi :

 20423171 brw-rw---- 1 root disk   7, 0 avril 27 13:56 /dev/loop0
213017956 brw-rw---- 1 root disk 259, 0 avril 27 13:56 /dev/loop0p1

J’ai bien le périphérique loop0p1 qui représente la première partition de mon image. On peut alors utiliser cette partition comme une partition physique : la monter (sudo mount /dev/loop0p1 /mnt), la fsck (sudo fsck /dev/loop0p1) etc.
On peut également manipuler l’image comme un vrai disque avec Gparted : sudo gparted /dev/loop0. Il faut spécifier manuellement l’emplacement, car Gparted sans argument ne liste que les disques physiques.

À noter, si la partition a été retrécie via GParted, l’image du disque ne le sera pas pour autant (car l’espace non-partitionné existe toujours). Pour ceci, suivant les conseils de ce billet, on peut lancer la commande sudo fdisk -l /home/user/sdi.img pour analyser la table de partition, puis utiliser la commande truncate pour couper l’image dès que la partition se finit. Pour ceci, on multiplie le numéro de secteur final de la dernière partition+1 par la taile des secteurs (logique, je suppose, en cas de différence entre physique et logique. A vérifier).

Par exemple, selon mon exemple en début d’article :

truncate --size=$[(3907031039+1)*512] /home/user/sdi.img

Accès à l’image depuis Virtualbox

VirtualBox permet l’accès depuis le système invité aux disques physiques de la machine hôte. Cela se fait via les disques virtuels VMDK.

Cette partie est grandement recopiée de ce billet.

On commence par s’assurer qu’on fait bien partie du groupe disk : sudo usermod -G disk -a user_name (et on pense à log out pour appliquer les modifs). Ceci permet de pouvoir accéder aux disques sans avoir besoin de lancer VB en root.

On crée le fichier vmdk avec la commande suivante : VBoxManage internalcommands createrawvmdk -filename image.vmdk -rawdisk /dev/loop0. Ceci va donner l’accès au disque complet.

Si on souhaite ne donner accès qu’à une partition, on peut utiliser l’option -partitions 2 (pour donner l’accès à la 2ème partition).
A noter que, selon ce Github, cet outil n’est capable de comprendre que les tables MBR. L’outil proposé par le github lui-même semble capable de lire le GPT aussi.

Une fois le fichier créé, il n’y a plus qu’à l’ajouter dans la configuration Stockage de la machine virtuelle.

Démontage

Une fois que l’on a fini, on peut démonter la partition de son point de montage (umount), puis démonter l’image du périphérique loop0 via la commande sudo losetup -d /dev/loop0.

[EDIT : avec l’option -P au montage, losetup supprimera les blocks partitions au démontage, l’étape suivant n’est donc pas nécessaire.]

Ceci ne supprime néanmoins pas le block /dev/loop0p1. Pour ceci : sudo delpart /dev/loop0 1.
C’est l’inverse de partprobe, cette commande dit au noyau d’oublier la partition 1 du périphérique loop0. A faire pour chaque partition.