mercredi 11 novembre 2015

Cloner un disque sur un disque plus petit

Cloner un disque sur un disque plus petit


Deux cas possibles :
1- le disque plus grand contient des partitions qui ne remplissent pas tout le disque
2- le disque plus grand contient des partitions qui remplissent tout le disque

Pour réaliser les étapes décrites ci-après il faut un système Linux. Le plus pratique est d'utiliser un LiveCD de Gparted.

1- Si le disque plus grand contient des partitions qui ne remplissent pas tout le disque

On peut utiliser la commande dd avec des paramètres pour limiter la taille de la copie à l'espace disque utilisé par les partitions.

Le disque à copier est /dev/sda (une carte SD de 32 Go avec seulement une partition de 65 Mo.
Pour copier ce disque vers une image disque qui contient seulement l'espace disque utilisé, il faut utiliser les commandes :
- fdisk -l /dev/sda
- dd if=/dev/sda of=/mnt/sd.img bs=1M count=70

root@debian:/home/user# fdisk -l /dev/sda
Disk /dev/sda: 29,3 GiB, 31440502784 bytes, 61407232 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: 0x0005bdc5

Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 133119 131072 64M b W95 FAT32

root@debian:/home/user# dd if=/dev/sda of=/mnt/sd.img bs=1M count=70
70+0 records in
70+0 records out
73400320 bytes (73 MB) copied, 4,35592 s, 16,9 MB/s

Pour connaître la valeur à utiliser pour count :
bs=1M est la taille de bloc en Mo (peut être en octets si on ne met pas le M).
count est le nombre de blocs de l'espace disque à copier (si bs est 1 Mo, count indique la taille en Mo).
Pour le déterminer il faut connaître la taille en Mo occupée par toutes les partitions sur le disque, soit :
Taille totale occupée en octets = dernier secteur de la dernière partition X taille de secteur
(dans notre cas, d'après les infos fournies par fdisk : 133119 x 512 = 68156928 octets).

Taille totale occupée en Mo = Taille totale occupée en octets / 1024 / 1024 (dans notre cas 68156928 / 1024 / 1024 = 65 Mo).
On ajoute quelques Mo supplémentaires par sécurité. On peut donc utiliser un count de 70.

Autre méthode sans calcul :
On peut utiliser la commande dd if=/dev/sda of=/mnt/sd.img bs=512 count=133120
On indique la taille de secteur pour bs (512) et le dernier secteur de la dernière partition (133119) + un secteur (car les secteurs commencent à 0) pour count.

Méthode moins précise pour connaître la valeur à utiliser pour count :
Il faut monter toutes les partitions du disque et exécuter la commande 
df -H --total /mnt/part1 /mnt/part2 (lister tous les points de montage séparés par un espace)

Résultat :
On obtient une image disque qui fait 70 Mo et qui contient seulement les partitions de l'espace disque utilisé.

Analyse de l’image disque :
root@debian:/home/user# fdisk -l /mnt/sd.img
Disk /mnt/sd.img: 70 MiB, 73400320 bytes, 143360 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: 0x0005bdc5

Device Boot Start End Sectors Size Id Type
/mnt/sd.img1 2048 133119 131072 64M b W95 FAT32

On peut restaurer cette image disque sur un disque plus petit que celui d'origine soit avec dd sous Linux soit avec Win32diskimager sous Windows.

Remarque : On peut aussi copier directement un disque sur un autre avec dd :
dd if=/dev/sda of=/dev/sdb bs=1M count=70
ou
dd if=/dev/sda of=/dev/sdb bs=512 count=133120



2- Si le disque plus grand contient des partitions qui remplissent tout le disque

Deux méthodes :
a- La risquée
b- La sans risque

a- La risquée :

Principe : Rétrécir, avec Gparted, la taille de la dernière partition du disque à copier pour faire correspondre la taille au disque de destination et faire la copie avec dd comme vu lorsque les partitions ne remplissent pas tout le disque.

Risque possible : perdre des données sur le disque d'origine à cause du rétrécissement de partition.

b- La sans risque :

Principe : Faire une image disque complète, avec dd, du disque à copier vers un fichier .img, puis monter ce fichier img comme un disque et rétrécir, avec Gparted, les partitions selon la taille désirée, puis supprimer l'espace inutilisé dans le fichier img pour obtenir un fichier img qu'on peut copier sur le disque de destination avec dd ou Win32diskimager.

Le disque à copier est /dev/sda (une carte SD de 4 Go avec une partition de 63 Mo et une autre de 3.7 Go avec environ 1 Go utilisé.

Faire une image disque complète, avec dd, du disque à copier vers un fichier .img :
root@debian:/home/user# dd if=/dev/sda of=/mnt/sd4go.img

Détail des infos de l'image disque :
root@debian:/home/user# fdisk -l /mnt/sd4go.img
Disk /mnt/sd4go.img: 3,7 GiB, 3980394496 bytes, 7774208 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: 0x00000000

Device Boot Start End Sectors Size Id Type
/mnt/sd4go.img1 2048 131071 129024 63M e W95 FAT16 (LBA)
/mnt/sd4go.img2 131072 7774207 7643136 3,7G 83 Linux

Taille de l'image disque :
root@debian:/home/user# du -hs /mnt/sd4go.img
3,8G /mnt/sd4go.img

Monter le fichier img comme un disque :
root@debian:/home/user# modprobe loop (active un disque virtuel loop)

root@debian:/home/user# losetup -f (affiche le disque virtuel loop disponible)
/dev/loop1

root@debian:/home/user# losetup /dev/loop1 /mnt/sd4go.img (associe l'image disque au disque virtuel)

root@debian:/home/user# partprobe /dev/loop1 (charge les partitions contenue dans l'image disque)

Ouvrir le disque dans Gparted pour rétrécir la ou les partitions :
root@debian:/home/user# gparted /dev/loop1



On réduit la dernière partition à une taille de 2 Go, ce qui crée de l'espace non alloué qu'on va pouvoir supprimer de l'image disque.

Désactiver le disque virtuel loop :
root@debian:/home/user# losetup -d /dev/loop1

Les infos de l'image disque indique le rétrécissement de la partition mais la taille de l'image disque est toujours la même (nombre de secteurs totaux identiques par rapport au fdisk précédent) :
root@debian:/home/user# fdisk -l /mnt/sd4go.img
Disk /mnt/sd4go.img: 3,7 GiB, 3980394496 bytes, 7774208 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: 0xba9811e1

Device Boot Start End Sectors Size Id Type
/mnt/sd4go.img1 2048 131071 129024 63M e W95 FAT16 (LBA)
/mnt/sd4go.img2 131072 4227071 4096000 2G 83 Linux

Réduire la taille de l'image disque :
root@debian:/home/user# truncate --size=$[(4227071+1)*512] /mnt/sd4go.img

truncate permet de garder la taille indiquée en octets à partir du début de l'image disque (size) et supprime le reste.

Pour connaître la taille à indiquer pour size :
size = [dernier secteur de la dernière partition + un secteur (car les secteurs commencent à 0)] X taille de secteur.
Dans notre cas, d'après les infos fournies par fdisk : (4227071+1)*512

La taille de l'image disque est réduite :
root@debian:/home/user# du -hs /mnt/sd4go.img
2,1G /mnt/sd4go.img

Les infos de l'image disque indique le rétrécissement de la partition et de la taille de l'image disque (nombre de secteurs totaux ajustés à la taille occupée par les partitions) :
root@debian:/home/user# fdisk -l /mnt/sd4go.img
Disk /mnt/sd4go.img: 2 GiB, 2164260864 bytes, 4227072 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: 0xba9811e1

Device Boot Start End Sectors Size Id Type
/mnt/sd4go.img1 2048 131071 129024 63M e W95 FAT16 (LBA)
/mnt/sd4go.img2 131072 4227071 4096000 2G 83 Linux


Résultat :
On obtient une image disque qui contient seulement les partitions de l'espace disque utilisé.
On peut restaurer cette image disque sur un disque plus petit que celui d'origine soit avec dd sous Linux soit avec Win32diskimager sous Windows.
Après restauration de l'image disque, on peut agrandir la partition rétrécie avec Gparted aussi.

Cloner un disque vers une image disque plus petite - méthode rapide et dangereuse

Voici une méthode pour cloner un disque vers une image disque plus petite que la taille du disque sauvegardé pour la restaurer sur un disque de même taille ou plus grand.

Attention : La procédure décrite ci-après peut ne pas fonctionner dans tous les cas, il faut faire des tests de restauration pour éviter des pertes de données. Pour plus de fiabilité, suivre cette autre méthode.

Par défaut la commande dd crée une image disque de la taille totale du disque donc si on a une clé USB de 32 Go avec seulement 500 Mo utilisé, l'image disque fera quand même 32 Go, ce n'est pas très pratique si on veut stocker l'image disque.

Pour éviter cela, on utilise la commande dd en utilisant un paramètre count plus grand que la somme de la taille de toutes les partitions (sauf la dernière) + la taille de l'espace disque utilisé de la dernière partition + quelques Mo de sécurité.

Le disque à copier est /dev/sda (une carte SD de 32 Go avec une partition de 65 Mo et une autre de 30 Go avec environ 500 Mo utilisés.

Pour obtenir une image disque de 600 Mo, on utilise la commande :
dd if=/dev/sda of=/mnt/imagedisque.img bs=1M count=600

bs=1M est la taille de bloc en Mo (peut être en octets si on ne met pas le M).
count est le nombre de blocs de l'espace disque à copier (si bs est 1 Mo, count indique la taille en Mo).

Pour connaitre la valeur de count :

Afficher la liste des partitions pour connaitre leur taille :
root@debian:/home/user# fdisk -l /dev/sda
Disk /dev/sda: 29,3 GiB, 31440502784 bytes, 61407232 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: 0x0005bdc5

Device Boot Start End Sectors Size Id Type
/dev/sda1 2048 133119 131072 64M b W95 FAT32
/dev/sda2 133120 61407231 61274112 29,2G 83 Linux

Monter la dernière partition (ici sda2) et afficher la taille de l'espace disque utilisé, puis démonter la partition :
root@debian:/home/user# mount /dev/sda2 /media/
root@debian:/home/user# du -hs /media/
459M /media/
root@debian:/home/user# umount /media/

Pour connaitre la valeur de count, on additionne donc les 64 Mo de la partition 1, les 459 Mo de la partition 2 et on ajoute quelques Mo de sécurité, soit 600 Mo.

Résultat :
On obtient une image disque de 600 Mo qu'on peut restaurer sur un disque de même taille ou plus grand (mais pas plus petit car sinon la taille des partitions dépasse la taille du disque et cela corrompt le système de fichiers rendant le disque inutilisable) soit avec dd sous Linux soit avec Win32diskimager sous Windows.

Remarque : On peut aussi copier directement un disque sur un autre avec dd et utiliser count pour limiter la copie à l'espace utilisé et ainsi réduire le temps de copie.
dd if=/dev/sda of=/dev/sdb bs=1M count=600