Il y a quelques jours j’ai eu besoin d’accéder au disque d’une VM pour réaliser une synchronisation de fichiers pour une migration depuis un serveur physique vers une machine virtuelle gérée avec Bhyve sur FreeBSD.
La configuration de disque que j’utilise pour l’hyperviseur Bhyve est basée sur ZFS plutôt que sur des images raw qui permet de créer un volume dédié à chaque VM, optimisant l’espace disque avec la compression, le chiffrement, les snapshots et tous les avantages que peut apporter ZFS (et les inconvénients). On peut également opter pour le format qcow en Linux/KVM et chaque technologie apporte ses avantages et inconvénients.
Mais concentrons-nous sur le titre de l’article. La mémoire est fragile et avec tant d’options infinies qu’offre chaque technologie, on oublie parfois certaines options et configurations.
Pour réaliser la synchronisation des fichiers sur la VM de destination mon objectif était de monter le volume de la VM sur l’hyperviseur et depuis lui réaliser un rsync depuis l’ancienne machine (encore en production) vers le volume monté avec l’idée de minimiser le temps d’arrêt pendant que les changements d’IP et tout le reste sont effectués.
Dans ZFS pour chaque dataset de type volume qui est créé, dans le répertoire /dev apparaîtra un périphérique pour pouvoir y accéder comme s’il s’agissait d’un disque comme un autre :
# ls -la /dev/zvol/zroot/bhyve/testvm/disk0
crw-r----- 1 root operator 0xe3 10 nov. 17:16 /dev/zvol/zroot/bhyve/testvm/disk0
Cette caractéristique de ZFS est très pratique pour pouvoir manipuler et réaliser des actions sur le volume comme sur n’importe quel autre périphérique.
Le problème qui m’est arrivé (et qui me sert de mémo) est que l’accès au périphérique n’était initialement pas possible :
# gpart show /dev/zvol/zroot/bhyve/testvm/disk0
gpart: No such geom: /dev/zvol/zroot/bhyve/testvm/disk0.
La raison est que par défaut, quand vm-bhyve crée le volume ZFS il établit le volmode comme « dev » et ce mode ne permet pas d’avoir une vue complète du périphérique créé dans le système :
volmode=default|full|geom|dev|none
This property specifies how volumes should be exposed to the OS.
Setting it to full exposes volumes as fully fledged block devices,
providing maximal functionality. The value geom is just an alias for
full and is kept for compatibility. Setting it to dev hides its
partitions. Volumes with property set to none are not exposed outside
ZFS, but can be snapshotted, cloned, replicated, etc, that can be
suitable for backup purposes. Value default means that volumes
exposition is controlled by system-wide tunable zvol_volmode, where
full, dev and none are encoded as 1, 2 and 3 respectively. The default
value is full.
La solution est très simple et se règle avec une simple commande :
# zfs set volmode=full zroot/bhyve/testvm/disk0
Et maintenant :
# gpart show /dev/zvol/zroot/bhyve/testvm/disk0
=> 2048 4192223 zvol/zroot/bhyve/testvm/disk0 GPT (10G) [CORRUPT]
2048 6144 14 bios-boot (3.0M)
8192 253952 15 efi (124M)
262144 3932127 1 linux-data (1.9G)
Nous avons un accès complet au disque, de plus les partitions apparaissent ce dont nous avons besoin pour pouvoir les monter sur l’hyperviseur :
# ls -la /dev/zvol/zroot/bhyve/testvm/disk0*
crw-r----- 1 root operator 0xdd 10 nov. 17:28 /dev/zvol/zroot/bhyve/testvm/disk0
crw-r----- 1 root operator 0xe2 10 nov. 17:28 /dev/zvol/zroot/bhyve/testvm/disk0p1
crw-r----- 1 root operator 0xe4 10 nov. 17:28 /dev/zvol/zroot/bhyve/testvm/disk0p14
crw-r----- 1 root operator 0xe5 10 nov. 17:28 /dev/zvol/zroot/bhyve/testvm/disk0p15
Maintenant, monter la partition souhaitée est aussi simple que :
# mkdir /mnt/testvm
# mount -t ext2fs -o rw /dev/zvol/zroot/bhyve/testvm/disk0p1 /mnt/testvm/
Ce qui nous donnera accès au disque de la VM dans /mnt/testvm.
Souviens-toi de réaliser cette opération toujours avec la VM arrêtée et ne jamais la démarrer sans vérifier que le volume a été démonté.
# umount /mnt/testvm