Blog

Agrandir un disque qcow2 contenant plusieurs partitions

Écrit le 28 02 2017 par Kévin MET _

Introduction

Ce matin, on va partir sur un petit tutoriel rapide sur l’agrandissement d’un disque virtuel au format qcow2 utilisé par KVM. Je vous explique le contexte, j’ai une VM KVM sur proxmox utilisant un disque virtuel au format qcow2 qui lui même contient 2 partitions. Pour prouver mes dires, voici un fdisk dans la VM :


fdisk -l

Disk /dev/vda: 10 GiB, 10737418240 bytes, 20971520 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: 0x1e82b3ba

Device     Boot    Start      End  Sectors  Size Id Type
/dev/vda1       19972096 20969471   997376  487M 82 Linux swap / Solaris
/dev/vda2  *        2048 19972095 19970048  9.5G 83 Linux

Partition table entries are not in disk order.

On voit que /dev/vda1 fait 500Mo et fait office de swap alors que /dev/vda2 fait 9,5Go pour le système. Or on va manquer un peu de place :


df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda2       9.3G  7.0G  1.9G  80% /
udev             10M     0   10M   0% /dev
tmpfs           402M   41M  362M  11% /run
tmpfs          1005M     0 1005M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs          1005M     0 1005M   0% /sys/fs/cgroup

Du coup, on pourrait se dire que cela va être plutôt simple, il suffit d’agrandir le qcow2 à froid et de balancer un bon vieux resize2fs et l’affaire est réglée. Mais pas vraiment, car si l’affaire était si simple je n’en aurai pas fait un article sur le blog...

Le problème réside dans le fait que la partition swap se trouve en deuxième position, on ne peut donc pas agrandir la première partition. Pour illustrer mes propos, voici un parted sur /dev/vda :


parted /dev/vda
GNU Parted 3.2
Using /dev/vda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free                                                       
Model: Virtio Block Device (virtblk)
Disk /dev/vda: 10.7GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End     Size    Type     File system     Flags
        32.3kB  1049kB  1016kB           Free Space
 2      1049kB  10.2GB  10.2GB  primary  ext4            boot
 1      10.2GB  10.7GB  511MB   primary  linux-swap(v1)
        10.7GB  10.7GB  1049kB           Free Space

(parted)

La seule solution est donc d’agrandir l’image qcow2 avec qemu-img, d’exporter l’image avec qemu-nbd, de supprimer la partition swap, d’agrandir la partition système, d’ajouter un disque dans proxmox pour la swap, d’agrandir le FS et enfin de rajouter la swap dans la VM. Allez, on est parti !

Agrandissement de l’image (qemu-img)

Déjà, on commence par éteindre la VM proprement. Pour cela, on se connecte en SSH et on lance un bon vieux shutdown des familles :


shutdown -h now

Sur le serveur host (proxmox dans mon cas) on vérifie que la VM est bien arrêté avec qm :


 qm list
      VMID NAME                 STATUS     MEM(MB)    BOOTDISK(GB) PID       
       [...]      
       102 infogerance             stopped    2048              10.00 0         
       [...]

On voit que la vm infogerance est bien arrêtée, on a pas de PID, tout semble OK. Pour être sur, on lance un check de l’image avec qemu-img. Pour déterminer où se trouve l’image on peut utiliser qm config :


qm config 102
boot: cdn
bootdisk: virtio0
cores: 2
keyboard: fr
memory: 1024
name: infogerance
net0: virtio=02:00:00:21:22:23,bridge=vmbr0,rate=100
numa: 0
ostype: l26
scsihw: virtio-scsi-pci
smbios1: uuid=6a0585ee-f8df-4684-a31a-381f885114e9
sockets: 1
vga: qxl
virtio0: home:102/vm-102-disk-1.qcow2,size=10G

La ligne qui nous intéresse est la suivante :


virtio0: home:102/vm-102-disk-1.qcow2,size=10G

On voit que l’image est dans le pool home mais ou se trouve ce pool exactement ? Il suffit de le demander à /etc/pve/storage.cfg :


cat /etc/pve/storage.cfg 
dir: local
	path /var/lib/vz
	content rootdir,images,vztmpl,iso
	maxfiles 0

dir: home
	path /home
	content backup,rootdir,vztmpl,images,iso
	shared 0
	maxfiles 1
	nodes hv1

Voilà, on sait qu notre image est /home/images/102/vm-102-disk-1.qcow2, on peut donc lancer un check via qemu-img :


qemu-img check /home/images/102/vm-102-disk-1.qcow2
No errors were found on the image.
163840/163840 = 100.00% allocated, 0.34% fragmented, 0.00% compressed clusters
Image end offset: 10754916352

Tout semble OK, on va donc pouvoir l’agrandir. Dans cet exemple je vais ajouter 2Go :


qemu-img resize /home/images/102/vm-102-disk-1.qcow2 +2G
Image resized.

On vérifie qu’on a bien nos 10 + 2 = 12Go :


qemu-img info /home/images/102/vm-102-disk-1.qcow2 
image: /home/images/102/vm-102-disk-1.qcow2
file format: qcow2
virtual size: 12G (12884901888 bytes)
disk size: 4.9G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

Tout semble OK, on peut donc passer à la suppression de la partition de swap et l’agrandissement de la partition système.

Modification de l’image via qemu-nbd

Lorsqu’on a plusieurs partitions dans une même image disque, il faut des outils spéciaux pour pouvoir la manipuler, il existe kpartx par exemple, qui utilise les loop devices pour mapper une partition du disque à un loop device mais dans notre cas on va utiliser les outils fournis par qemu-utils, à savoir qemu-nbd. Cet utilitaire permet d’exporter une image virtuelle en utilisant le protocole NBD. D’abord il faut charger le module en spécifiant le paramètre max_part qui correspond au nombre maximum de partitions contenues dans le disque virtuel.


modprobe nbd max_part=8
lsmod | grep nbd
nbd                    20480  0

Le module est chargé, on peut exporter notre image :


qemu-nbd --connect=/dev/nbd0 /home/images/102/vm-102-disk-1.qcow2

On va ensuite supprimer la partition swap avec parted, on utilise les secteurs comme unité car c’est plus précis et on affiche les espaces libres :


parted /dev/nbd0
GNU Parted 3.2
Using /dev/nbd0
Welcome to GNU Parted! Type 'help' to view a list of commands.


(parted) unit s print free
Model: Unknown (unknown)
Disk /dev/nbd0: 25165824s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start      End        Size       Type     File system     Flags
        63s        2047s      1985s               Free Space
 2      2048s      19972095s  19970048s  primary  ext4            boot
 1      19972096s  20969471s  997376s    primary  linux-swap(v1)
        20969472s  25165823s  4196352s            Free Space

Il faut donc supprimer la partition 1 :


(parted) rm
Partition number? 1                                                       
(parted) print free
Model: Unknown (unknown)
Disk /dev/nbd0: 25165824s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start      End        Size       Type     File system  Flags
        63s        2047s      1985s               Free Space
 2      2048s      19972095s  19970048s  primary  ext4         boot
        19972096s  25165823s  5193728s            Free Space

Et enfin on étend notre partition avec resizepart :


(parted) resizepart                                                       
Partition number? 2                                                       
End?  [19972095s]? 25165823s
(parted) print 
Model: Unknown (unknown)
Disk /dev/nbd0: 25165824s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start  End        Size       Type     File system  Flags
 2      2048s  25165823s  25163776s  primary  ext4         boot

Une fois que c’est fait, il ne reste plus qu’à déconnecter l’export qu’on vient d’utilisé :


qemu-nbd --disconnect /dev/nbd0 

Ajout du disque dans Proxmox

Pour cela, rien de plus simple, on va sur la VM dans l’interface de proxmox et dans le menu hardware on ajoute un nouveau disque.

Ajout disque sur VM Proxmox

Agrandissement du FS et ajout de la swap

Là c’est le moment où on croise les doigts pour que tout se soit bien déroulé car on démarre la VM, soit en passant par l’interface de proxmox, soit via qm :


qm start 102 

Une fois que la VM est remontée, on peut s’y connecter en SSH et lancer notre resize2fs :


resize2fs /dev/vda2 
resize2fs 1.42.12 (29-Aug-2014)
Filesystem at /dev/vda2 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/vda2 is now 3145472 (4k) blocks long.

On vérifie qu’on a bien nos 12Go :


df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda2        12G  1.3G  9.9G  12% /
udev             10M     0   10M   0% /dev
tmpfs           201M  4.4M  196M   3% /run
tmpfs           501M     0  501M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           501M     0  501M   0% /sys/fs/cgroup

De ce coté, c’est impeccable, il ne reste plus qu’à s’occuper de la swap car pour le moment la VM n’en a plus :


free -h
             total       used       free     shared    buffers     cached
Mem:          1.0G       149M       850M       4.4M        11M        60M
-/+ buffers/cache:        77M       923M
Swap:           0B         0B         0B

On commence par créer la partition swap avec parted ou fdisk, dans mon cas j’ai pris fdisk pour varier les plaisirs :


fdisk /dev/vdb

Welcome to fdisk (util-linux 2.25.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): p
Disk /dev/vdb: 1 GiB, 1073741824 bytes, 2097152 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: gpt
Disk identifier: 3B3097E2-9F78-42AB-AF3F-8572E63A3B49

Command (m for help): n
Partition number (1-128, default 1): 
First sector (34-2097118, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-2097118, default 2097118): 

Created a new partition 1 of type 'Linux filesystem' and of size 1023 MiB.

Command (m for help): t
Selected partition 1

Partition type (type L to list all types): 14
Changed type of partition 'Linux filesystem' to 'Linux swap'.

Command (m for help): p
Disk /dev/vdb: 1 GiB, 1073741824 bytes, 2097152 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: gpt
Disk identifier: 3B3097E2-9F78-42AB-AF3F-8572E63A3B49

Device     Start     End Sectors  Size Type
/dev/vdb1   2048 2097118 2095071 1023M Linux swap


Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Je vous passe les détails sur l’utilisation de fdisk, on trouve ça partout sur internet...

On déclare la swap sur /dev/vdb1 qu'on vient tout juste de créer :


mkswap /dev/vdb1 
Setting up swapspace version 1, size = 1047528 KiB
no label, UUID=17093191-f57b-42c2-bf4c-93012a849a0f

On copie l’UUID pour le remplacer dans /etc/fstab :


cat /etc/fstab 
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/vda2 during installation
UUID=13948be5-7dd8-410b-bf80-3f77dbef88a2 /               ext4    errors=remount-ro 0       1
UUID=17093191-f57b-42c2-bf4c-93012a849a0f none            swap    sw              0       0
/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0

Et enfin on active la swap et on vérifie qu’elle est bien en service :


swapon -a
free -h
             total       used       free     shared    buffers     cached
Mem:          1.0G       260M       739M       4.4M        34M       101M
-/+ buffers/cache:       125M       875M
Swap:         1.0G         0B       1.0G

Done !

Source : http://ask.xmodulo.com/mount-qcow2-disk-image-linux.html

♥ Partage sur tes réseaux sociaux ♥
Kévin MET
Kévin MET

Auteur de ce blog et gérant de la société MNT-TECH, je publie sur ce blog lorsque le temps me le permet et lorsqu'un sujet qui me parait intéressant n'a pas encore été abordé en français. Toutes les informations techniques présentes sur cette page peuvent être réutilisées moyennant le fait de citer la source.