QEMU (Français)

From ArchWiki
État de la traduction: Cet article est la version francophone de QEMU. Date de la dernière traduction: 2022-03-10. Vous pouvez aider à synchroniser la traduction s'il y a eu des changements dans la version anglaise.

Cet article ou section a besoin d'être traduit(e).

Notes: J'ai procédé à la traduction de cette page, mais je ne suis pas familier avec le sujet traité : n'hésitez pas à consulter la page anglaise en cas de doute sur le sens d'une phrase et à rectifier mes erreurs lorsque vous les rencontrerez. (Discuss in Talk:QEMU (Français)#)

Selon la page QEMU about page, "QEMU est un émulateur et un virtualiseur de machine générique et open source".

Lorsqu'il est utilisé comme émulateur de machine, QEMU peut exécuter des systèmes d'exploitation et des programmes conçus pour une machine (par exemple, une carte ARM) sur une autre machine (par exemple, votre PC x86). En utilisant une traduction dynamique, il obtient de très bonnes performances.

QEMU peut utiliser d'autres hyperviseurs comme Xen ou KVM pour utiliser des extensions de CPU (HVM) pour la virtualisation. Lorsqu'il est utilisé comme virtualiseur, QEMU atteint des performances proches de celles d'un système natif en exécutant le code invité directement sur le CPU hôte.

Installation

Installez le paquet qemu-desktop (ou qemu-base pour la version sans interface graphique) et les paquets optionnels suivants pour vos besoins :

Alternativement, qemu-user-static existe en tant que variante usermode et statique.

Variantes de QEMU

QEMU est proposé en plusieurs variantes adaptées à différents cas d'utilisation.

En première classification, QEMU est proposé en modes d'émulation «full-system» et «usermode» :

Émulation «full-system»
Dans ce mode, QEMU émule un système complet, comprenant un ou plusieurs processeurs et divers périphériques. Il est plus précis mais plus lent, et ne nécessite pas que le système d'exploitation émulé soit Linux.
Les commandes QEMU pour l'émulation d'un système complet sont nommées qemu-system-target_architecture, par exemple qemu-system-x86_64 pour l'émulation de processeurs intel 64 bits, qemu-system-i386 pour les processeurs intel 32 bits, qemu-system-arm pour ARM (32 bits), qemu-system-aarch64 pour ARM64, etc.
Si l'architecture cible correspond au CPU hôte, ce mode peut encore bénéficier d'une accélération significative en utilisant un hyperviseur comme #Activation de KVM|KVM]] ou Xen.
Émulation en mode utilisateur
Dans ce mode, QEMU est capable d'invoquer un exécutable Linux compilé pour une architecture (potentiellement) différente en exploitant les ressources du système hôte. Il peut y avoir des problèmes de compatibilité, par exemple certaines fonctionnalités peuvent ne pas être implémentées, les exécutables liés dynamiquement ne fonctionneront pas (consultez #Chrooter dans l'environnement arm/arm64 à partir de x86_64 pour résoudre ce problème) et seul Linux est pris en charge (bien que Wine peut être utilisé pour exécuter des exécutables Windows).
Les commandes QEMU pour l'émulation du mode utilisateur sont nommées qemu-target_architecture, par exemple qemu-x86_64 pour émuler les CPU intel 64 bits.

QEMU est proposé dans des variantes liées dynamiquement et statiquement :

Liée dynamiquement (par défaut)
les commandes qemu-* dépendent des bibliothèques du système d'exploitation hôte, les exécutables sont donc plus petits.
Liée de manière statique
Les commandes qemu-* peuvent être copiées sur tout système Linux ayant la même architecture.

Dans le cas d'Arch Linux, l'émulation complète du système est offerte comme :

Non-headless (par défaut)
Cette variante active les fonctionnalités de l'interface graphique qui nécessitent des dépendances supplémentaires (comme SDL ou GTK).
Headless
Il s'agit d'une variante plus légère qui ne nécessite pas d'interface graphique (elle est adaptée, par exemple, aux serveurs).

Notez que les versions headless et non-headless installent des commandes avec le même nom (par exemple qemu-system-x86_64) et ne peuvent donc pas être installées toutes les deux en même temps.

Détails sur les paquets offerts dans Arch Linux

  • Le paquet qemu-desktop fournit les émulateurs d'architecture x86_64 pour l'émulation du système complet (qemu-system-x86_64). Le paquet qemu-emulators-full fournit la variante usermode de l'architecture x86_64 (qemu-x86_64) et, pour les autres architectures prises en charge, il inclut les variantes full-system et usermode (par exemple, qemu-system-arm et qemu-arm).
  • Les versions «headless» (sans affichage) de ces paquets (uniquement applicables à l'émulation full-system) sont qemu-base (x86_64 uniquement) et qemu-emulators-full (le reste des architectures).
  • L'émulation du système complet peut être étendue avec certains modules QEMU présents dans des paquets séparés : qemu-block-gluster, qemu-block-iscsi et qemu-guest-agent.
  • Le paquet AUR non officiel qemu-user-static fournit un mode utilisateur et une variante statique pour toutes les architectures cibles prises en charge par QEMU. Les commandes QEMU installées sont nommées qemu-target_architecture-static, par exemple, qemu-x86_64-static pour les CPU intel 64 bits.
Note: À l'heure actuelle, Arch ne propose pas de mode système complet et de variante liée statiquement (ni officiellement ni via AUR), car cela n'est généralement pas nécessaire.

Interfaces graphiques pour QEMU

Contrairement à d'autres programmes de virtualisation tels que VirtualBox et VMware, QEMU ne fournit pas d'interface graphique pour gérer les machines virtuelles (autre que la fenêtre qui apparaît lors de l'exécution d'une machine virtuelle), ni de moyen de créer des machines virtuelles persistantes avec des paramètres enregistrés. Tous les paramètres permettant d'exécuter une machine virtuelle doivent être spécifiés sur la ligne de commande à chaque lancement, à moins que vous n'ayez créé un script personnalisé pour démarrer votre ou vos machines virtuelles.

Libvirt fournit un moyen pratique de gérer les machines virtuelles QEMU. Consultez liste des clients libvirt pour connaître les interfaces disponibles.

Autres interfaces graphiques pour QEMU :

  • AQEMU — QEMU GUI écrite en Qt5.
https://github.com/tobimensch/aqemu || aqemuAUR

Créer un nouveau système virtualisé

Création d'une image de disque dur

The factual accuracy of this article or section is disputed.

Reason: Si je comprends bien la page de manuel, le format brut n'alloue la taille complète que si le système de fichiers ne prend pas en charge les "trous" ou si on lui demande explicitement de préallouer. Consultez la page man qemu-img dans la section Notes. (Discuss in Talk:QEMU)
Astuce: Consultez Wikibooks:QEMU/Images pour plus d'informations sur les images QEMU.

Pour exécuter QEMU, vous aurez besoin d'une image de disque dur, à moins que vous ne démarriez un système «live» à partir d'un CD-ROM ou du réseau (et non pour installer un système d'exploitation sur une image de disque dur). Une image de disque dur est un fichier qui stocke le contenu du disque dur émulé.

Une image de disque dur peut être brute, c'est-à-dire qu'elle est littéralement identique, octet par octet, à ce que consulte l'invité, et elle utilisera toujours la pleine capacité du disque dur de l'invité sur l'hôte. Cette méthode fournit le moins de surcharge d'E/S, mais peut gaspiller beaucoup d'espace, car l'espace non utilisé sur l'invité ne peut pas être utilisé sur l'hôte.

Alternativement, l'image du disque dur peut être dans un format tel que qcow2 qui n'alloue de l'espace au fichier image que lorsque le système d'exploitation invité écrit réellement dans ces secteurs sur son disque dur virtuel. L'image apparaît comme étant de taille complète pour le système d'exploitation invité, même si elle n'occupe qu'une très petite quantité d'espace sur le système hôte. Ce format d'image prend également en charge la fonctionnalité d'instantané de QEMU (consultez #Création et gestion des snapshots via la console du moniteur pour plus de détails). Cependant, l'utilisation de ce format au lieu de raw affectera probablement les performances.

QEMU fournit la commande qemu-img pour créer des images de disque dur. Par exemple, pour créer une image de 4 Gio au format raw :

$ qemu-img create -f raw image_file 4G

Vous pouvez utiliser -f qcow2 pour créer un disque qcow2 à la place.

Note: Vous pouvez aussi simplement créer une image brute en créant un fichier de la taille requise à l'aide de dd ou fallocate.
Attention: Si vous stockez les images du disque dur sur un système de fichiers Btrfs, vous devriez envisager de désactiver Copy-on-Write pour le répertoire avant de créer des images.

Images de stockage superposées

Vous pouvez créer une image de stockage une seule fois (l'image "backing") et faire en sorte que QEMU conserve les mutations de cette image dans une image de recouvrement. Cela vous permet de revenir à un état antérieur de cette image de stockage. Vous pouvez revenir en arrière en créant une nouvelle image de recouvrement au moment où vous souhaitez revenir en arrière, basée sur l'image de sauvegarde originale.

Pour créer une image superposée, lancez une commande comme :

$ qemu-img create -o backing_file=img1.raw,backing_fmt=raw -f qcow2 img1.cow

Après cela, vous pouvez exécuter votre VM QEMU comme d'habitude (consultez #Exécution du système virtualisé) :

$ qemu-system-x86_64 img1.cow

L'image de sauvegarde sera alors laissée intacte et les mutations vers ce stockage seront enregistrées dans le fichier de l'image de recouvrement.

Lorsque le chemin vers l'image de sauvegarde change, une réparation est nécessaire.

Attention: Le chemin absolu du système de fichiers de l'image de sauvegarde est enregistré dans le fichier (binaire) de l'image superposée. La modification du chemin d'accès à l'image de sauvegarde nécessite un certain effort.

Assurez-vous que le chemin de l'image de sauvegarde d'origine mène toujours à cette image. Si nécessaire, créez un lien symbolique entre le chemin d'origine et le nouveau chemin. Ensuite, lancez une commande comme :

$ qemu-img rebase -b /new/img1.raw /new/img1.cow

Si vous le souhaitez, vous pouvez également effectuer un rebasement "non sécurisé" où l'ancien chemin vers l'image de sauvegarde n'est pas vérifié :

$ qemu-img rebase -u -b /nouvelle/img1.raw /nouvelle/img1.cow

Redimensionnement d'une image

Attention: Le redimensionnement d'une image contenant un système de fichiers de démarrage NTFS peut rendre le système d'exploitation qui y est installé non amorçable. Il est recommandé de créer d'abord une sauvegarde.

L'exécutable qemu-img possède l'option resize, qui permet de redimensionner facilement une image de disque dur. Elle fonctionne à la fois pour raw et qcow2. Par exemple, pour augmenter l'espace de l'image de 10 Gio, exécutez :

$ qemu-img resize disk_image +10G

Après avoir agrandi l'image disque, vous devez utiliser le système de fichiers et les outils de partitionnement dans la machine virtuelle pour commencer à utiliser le nouvel espace. Lors du rétrécissement d'une image disque, vous devez 'd'abord réduire les tailles des systèmes de fichiers et des partitions alloués à l'aide des outils de système de fichiers et de partitionnement dans la machine virtuelle, puis rétrécir l'image disque en conséquence, sinon le rétrécissement de l'image disque entraînera une perte de données ! Pour un Windows virtualisé, ouvrez le panneau de contrôle "créer et formater les partitions du disque dur".

Convertir une image

Vous pouvez convertir une image dans d'autres formats en utilisant qemu-img convert. Cet exemple montre comment convertir une image raw en qcow2 :

$ qemu-img convert -f raw -O qcow2 input.img output.qcow2

Ceci ne supprimera pas le fichier d'entrée original.

Préparation du support d'installation

Pour installer un système d'exploitation dans votre image disque, vous avez besoin du support d'installation (par exemple, un disque optique, une clé USB ou une image ISO) pour le système d'exploitation. Le support d'installation ne doit pas être monté car QEMU accède directement au support.

Astuce: Si vous utilisez un disque optique, c'est une bonne idée de commencer par vider le support dans un fichier car cela améliore les performances et ne nécessite pas d'accès direct aux périphériques (c'est-à-dire que vous pouvez exécuter QEMU en tant qu'utilisateur normal sans avoir à modifier les autorisations d'accès sur le fichier de périphérique du support). Par exemple, si le nœud de périphérique CD-ROM est nommé /dev/cdrom, vous pouvez le vider dans un fichier avec la commande :
$ dd if=/dev/cdrom of=cd_image.iso bs=4k

Installation du système d'exploitation

C'est la première fois que vous devrez démarrer l'émulateur. Pour installer le système d'exploitation sur l'image disque, vous devez attacher l'image disque et le média d'installation à la machine virtuelle, et la faire démarrer à partir du média d'installation.

Par exemple, sur les invités i386, pour installer à partir d'un fichier ISO amorçable comme CD-ROM et une image disque brute :

$ qemu-system-x86_64 -cdrom iso_image -boot order=d -drive file=disk_image,format=raw

Consultez qemu(1) pour plus d'informations sur le chargement d'autres types de supports (tels que des disquettes, des images de disques ou des lecteurs physiques) et #Exécution du système virtualisé pour d'autres options utiles.

Une fois l'installation du système d'exploitation terminée, l'image QEMU peut être démarrée directement (consultez #Exécution du système virtualisé).

Note: Par défaut, seul 128 Mio de mémoire est attribuée à la machine. La quantité de mémoire peut être ajustée avec le paramètre -m, par exemple -m 512M ou -m 2G.
Astuce:
  • Au lieu de spécifier -boot order=x, certains utilisateurs peuvent se sentir plus à l'aise en utilisant un menu de démarrage : -boot menu=on, au moins pendant la configuration et l'expérimentation.
  • Lorsque QEMU est exécuté en mode sans affichage, il démarre un serveur VNC local sur le port 5900 par défaut. Vous pouvez utiliser TigerVNC pour vous connecter à l'OS invité : vncviewer :5900
  • Si vous devez remplacer des disquettes ou des CD dans le cadre du processus d'installation, vous pouvez utiliser le moniteur de machine QEMU (appuyez sur Ctrl+Alt+2 dans la fenêtre de la machine virtuelle) pour supprimer et attacher des périphériques de stockage à une machine virtuelle. Tapez info block pour consulter les périphériques de bloc, et utilisez la commande change pour échanger un périphérique. Appuyez sur Ctrl+Alt+1 pour revenir à la machine virtuelle.

Exécution du système virtualisé

Les binaires qemu-system-* (par exemple qemu-system-i386 ou qemu-system-x86_64, selon l'architecture de l'invité) sont utilisés pour exécuter l'invité virtualisé. L'utilisation est la suivante :

$ qemu-system-x86_64 options disk_image

Les options sont les mêmes pour tous les binaires qemu-system-*, consultez qemu(1) pour la documentation de toutes les options.

Par défaut, QEMU affichera la sortie vidéo de la machine virtuelle dans une fenêtre. Une chose à garder à l'esprit : lorsque vous cliquez dans la fenêtre de QEMU, le pointeur de la souris est saisi. Pour le relâcher, appuyez sur Ctrl+Alt+g.

Attention: QEMU ne doit jamais être lancé en tant que root. Si vous devez le lancer dans un script en tant que root, vous devez utiliser l'option -runas pour que QEMU abandonne les privilèges de root.

Activation de KVM

La virtualisation complète KVM (Kernel-based Virtual Machine) doit être prise en charge par votre noyau Linux et votre matériel, et les modules du noyau nécessaires doivent être chargés. Consultez KVM pour plus d'informations.

Pour démarrer QEMU en mode KVM, ajoutez -enable-kvm aux options de démarrage supplémentaires. Pour vérifier si KVM est activé pour une VM en cours d'exécution, entrez dans le #Moniteur de QEMU et tapez info kvm.

Note:
  • L'argument accel=kvm de l'option -machine est équivalent à l'option -enable-kvm ou -accel kvm}.
  • Le modèle de CPU host nécessite KVM
  • Si vous démarrez votre VM avec un outil GUI et que les performances sont très mauvaises, vous devez vérifier la prise en charge KVM, car QEMU peut se rabattre sur l'émulation logicielle.
  • KVM doit être activé afin de démarrer Windows 7 et Windows 8 correctement sans écran bleu.

Activation du support IOMMU (Intel VT-d/AMD-Vi)

Activez d'abord IOMMU, consultez PCI passthrough via OVMF#Setting up IOMMU.

Ajoutez -device intel-iommu pour créer le périphérique IOMMU :

$ qemu-system-x86_64 -enable-kvm -machine q35 -device intel-iommu -cpu host ...
Note: Sur les systèmes basés sur un CPU Intel, la création d'un périphérique IOMMU dans un invité QEMU avec -device intel-iommu désactivera le passage PCI avec une erreur du type :
Device at bus pcie.0 addr 09.0 requires iommu notifier which is currently not supported by intel-iommu emulation
Bien que l'ajout du paramètre du noyau intel_iommu=on soit toujours nécessaire pour le remappage des E/S (par exemple, PCI passthrough with vfio-pci), -device intel-iommu ne doit pas être défini si le PCI passthrough est requis.

Partage des données entre l'hôte et l'invité

Réseau

Les données peuvent être partagées entre le système d'exploitation hôte et le système d'exploitation invité en utilisant n'importe quel protocole réseau capable de transférer des fichiers, comme NFS, SMB, NBD, HTTP, FTP, ou SSH, à condition que vous ayez configuré le réseau de manière appropriée et activé les services adéquats.

La mise en réseau en mode utilisateur par défaut permet à l'invité d'accéder au système d'exploitation hôte à l'adresse IP 10.0.2.2. Tous les serveurs que vous exécutez sur votre système d'exploitation hôte, comme un serveur SSH ou un serveur SMB, seront accessibles à cette adresse IP. Ainsi, sur les invités, vous pouvez monter des répertoires exportés sur l'hôte via SMB ou NFS, ou vous pouvez accéder au serveur HTTP de l'hôte, etc. Il ne sera pas possible pour le système d'exploitation hôte d'accéder aux serveurs fonctionnant sur le système d'exploitation invité, mais cela peut être fait avec d'autres configurations réseau (consultez #Mise en réseau avec tap pour QEMU).

La redirection de port de QEMU

Note: La redirection de port de QEMU est uniquement IPv4. La redirection de port IPv6 n'est pas implémentée et les derniers correctifs ont été proposés en 2018.[1]

QEMU peut transférer des ports de l'hôte vers l'invité pour permettre, par exemple, la connexion de l'hôte à un serveur SSH fonctionnant sur l'invité.

Par exemple, pour lier le port 60022 sur l'hôte avec le port 22 (SSH) sur l'invité, démarrez QEMU avec une commande comme :

$ qemu-system-x86_64 disk_image -nic user,hostfwd=tcp::60022-:22

Assurez-vous que le sshd fonctionne sur l'invité et connectez-vous avec :

$ ssh guest-user@127.0.0.1 -p 60022

Vous pouvez utiliser SSHFS pour monter le système de fichiers de l'invité sur l'hôte pour un accès partagé en lecture et en écriture.

Pour transférer plusieurs ports, il suffit de répéter le hostfwd dans l'argument -nic, par exemple pour le port VNC :

$ qemu-system-x86_64 disk_image -nic user,hostfwd=tcp::60022-:22,hostfwd=tcp::5900-:5900

Le serveur SMB intégré de QEMU

La documentation de QEMU indique qu'il dispose d'un serveur SMB "intégré", mais en fait il ne fait que démarrer Samba sur l'hôte avec un fichier smb.conf généré automatiquement et situé dans /tmp/qemu-smb.random_string et le rend accessible à l'invité à une adresse IP différente (10.0.2.4 par défaut). Cela ne fonctionne que pour les réseaux d'utilisateurs, et est utile lorsque vous ne voulez pas démarrer le service Samba normal sur l'hôte, auquel l'invité peut également accéder si vous avez configuré des partages sur celui-ci.

Un seul répertoire peut être défini comme partagé avec l'option smb=, mais ajouter d'autres répertoires (même lorsque la machine virtuelle est en cours d'exécution) pourrait être aussi facile que de créer des liens symboliques dans le répertoire partagé si QEMU configurait SMB pour suivre les liens symboliques. Il ne le fait pas, mais la configuration du serveur SMB en cours d'exécution peut être modifiée comme décrit ci-dessous.

Samba doit être installé sur l'hôte. Pour activer cette fonctionnalité, démarrez QEMU avec une commande comme :

$ qemu-system-x86_64 -nic user,id=nic0,smb=shared_dir_path' disk_image

shared_dir_path est un répertoire que vous voulez partager entre l'invité et l'hôte.

Ensuite, dans l'invité, vous pourrez accéder au répertoire partagé sur l'hôte 10.0.2.4 avec le nom de partage "qemu". Par exemple, dans l'Explorateur Windows, vous accédez à \\\10.0.2.4\qemu.

Note:
  • Si vous utilisez plusieurs fois les options de partage comme -net user,smb=shared_dir_path1 -net user,smb=shared_dir_path2 ou -net user,smb=shared_dir_path1,smb=shared_dir_path2 alors il ne partagera que le dernier défini.
  • Si vous ne pouvez pas accéder au dossier partagé et que le système invité est Windows, vérifiez que le protocole NetBIOS est activé[dead link 2023-05-06 ⓘ] et qu'un pare-feu ne bloque pas les ports utilisés par le protocole NetBIOS.
  • Si vous ne pouvez pas accéder au dossier partagé et que le système invité est Windows 10 Entreprise ou Éducation ou Windows Server 2016, activer l'accès invité.
  • Si vous utilisez la #Mise en réseau avec tap pour QEMU, utilisez -device virtio-net,netdev=vmnic -netdev user,id=vmnic,smb=shared_dir_path pour obtenir SMB.

Une façon de partager plusieurs répertoires et de les ajouter ou de les supprimer pendant l'exécution de la machine virtuelle, consiste à partager un répertoire vide et à créer/supprimer des liens symboliques vers les répertoires du répertoire partagé. Pour que cela fonctionne, la configuration du serveur SMB en cours d'exécution peut être modifiée avec le script suivant, qui permet également l'exécution de fichiers sur l'invité qui ne sont pas définis comme exécutables sur l'hôte :

#!/bin/sh
eval $(ps h -C smbd -o pid,args | grep /tmp/qemu-smb | gawk '{print "pid="$1";conf="$6}')
echo "[global]
allow insecure wide links = yes
[qemu]
follow symlinks = yes
wide links = yes
acl allow execute always = yes" >> "$conf"
# in case the change is not detected automatically:
smbcontrol --configfile="$conf" "$pid" reload-config

Ceci peut être appliqué au serveur en cours d'exécution démarré par qemu seulement après que l'invité se soit connecté au lecteur réseau pour la première fois. Une alternative à cette méthode est d'ajouter des partages additionnels au fichier de configuration comme ceci :

echo "[myshare]
path=another_path
read only=no
guest ok=yes
force user=username" >> $conf

Ce partage sera disponible sur l'invité en tant que \10.0.2.4\myshare.

Utiliser le passage de système de fichiers et VirtFS

Consultez la documentation QEMU.

Partage de fichiers avec virtiofsd

virtiofsd est livré avec le paquet QEMU. La documentation est disponible online[dead link 2023-05-06 ⓘ] ou /usr/share/doc/qemu/tools/virtiofsd.html sur le système de fichiers local avec QEMU installé.

Ajoutez l'utilisateur qui exécute qemu au groupe 'kvm', car il doit accéder à la socket virtiofsd. Vous devrez peut-être vous déconnecter pour que le changement prenne effet.

The factual accuracy of this article or section is disputed.

Reason: L'exécution de services en tant que root n'est pas sécurisée. Aussi, le processus devrait être enveloppé dans un service systemd. (Discuss in Talk:QEMU)

Démarrez virtiofsd en tant que root :

# /usr/lib/qemu/virtiofsd --socket-path=/var/run/qemu-vm-001.sock -o source=/tmp/vm-001 -o cache=always

  • /var/run/qemu-vm-001.sock est un fichier socket,
  • /tmp/vm-001 est un répertoire partagé entre l'hôte et le vm invité.

Le fichier socket créé a la permission d'accès de root seulement. Donnez au groupe kvm l'accès à ce fichier avec :

# chgrp kvm qemu-vm-001.sock ; chmod g+rxw qemu-vm-001.sock

Ajoutez les options de configuration suivantes lors du démarrage de VM :

-objet memory-backend-memfd,id=mem,size=4G,share=on \
-numa node,memdev=mem \
-chardev socket,id=char0,path=/var/run/qemu-vm-001.sock \
-device vhost-user-fs-pci,chardev=char0,tag=myfs

This article or section needs expansion.

Reason: Expliquer les options restantes (ou les supprimer si elles ne sont pas nécessaires). (Discuss in Talk:QEMU)
  • size=4G doit correspondre à la taille spécifiée avec l'option -m 4G,
  • /var/run/qemu-vm-001.sock pointe vers le fichier de socket démarré précédemment,

Rappelez-vous que l'invité doit être configuré pour permettre le partage. Pour Windows, il existe instructions. Une fois configuré, Windows aura le lecteur Z : mappé automatiquement avec le contenu du répertoire partagé.

Votre système invité Windows 10 est correctement configuré s'il possède :

  • Le service Windows VirtioFSSService,
  • Le service Windows WinFsp.Launcher,
  • le pilote de périphérique VirtIO FS sous "Périphériques système" dans le "Gestionnaire de périphériques" de Windows.

Si les éléments ci-dessus sont installés et que le lecteur Z: n'est toujours pas listé, essayez de réparer "Virtio-win-guest-tools" dans l'ajout/suppression de programmes de Windows.

Montage d'une partition de l'invité sur l'hôte

Il peut être utile de monter une image de disque sous le système hôte, cela peut être un moyen de transférer des fichiers dans et hors de l'invité. Cela doit être fait lorsque la machine virtuelle n'est pas en cours d'exécution.

La procédure pour monter le disque sur l'hôte dépend du type d'image qemu, raw ou qcow2. Nous détaillons par la suite les étapes pour monter un disque dans les deux formats dans #Montage d'une partition à partir d'une image brute et #Montage d'une partition à partir d'une image qcow2. Pour la documentation complète, consultez Wikibooks:QEMU/Images#Mounting an image on the host.

Attention: Vous devez démonter les partitions avant de relancer la machine virtuelle. Sinon, la corruption des données est très probable.

Montage d'une partition à partir d'une image brute

Il est possible de monter des partitions qui se trouvent à l'intérieur d'un fichier image disque brut en les configurant comme des périphériques de bouclage.

En spécifiant manuellement le décalage des octets

Une façon de monter une partition d'image disque est de monter l'image disque à un certain décalage en utilisant une commande comme la suivante :

# mount -o loop,offset=32256 image_de_disque mountpoint

L'option offset=32256 est en fait passée au programme losetup pour configurer un périphérique de bouclage qui commence à l'octet 32256 du fichier et continue jusqu'à la fin. Ce périphérique de bouclage est ensuite monté. Vous pouvez également utiliser l'option sizelimit pour spécifier la taille exacte de la partition, mais cela n'est généralement pas nécessaire.

Selon votre image disque, la partition nécessaire peut ne pas commencer à l'offset 32256. Exécutez fdisk -l disk_image pour consulter les partitions dans l'image. fdisk donne les décalages de début et de fin en secteurs de 512 octets, donc multipliez par 512 pour obtenir le décalage correct à passer à mount.

Avec le module loop autodétectant les partitions

Le pilote de boucle Linux prend en charge les partitions dans les périphériques de bouclage, mais il est pris en charge par défaut. Pour l'activer, faites ce qui suit :

  • Débarrassez-vous de tous vos périphériques de bouclage (démontez toutes les images montées, etc.).
  • Déchargez le module noyau loop, et chargez-le avec le paramètre max_part=15. De plus, le nombre maximum de boucles peut être contrôlé avec le paramètre max_loop.
Astuce: Vous pouvez mettre une entrée dans /etc/modprobe.d pour charger le module loop avec max_part=15 à chaque fois, ou vous pouvez mettre loop.max_part=15 sur la ligne de commande du noyau, selon que vous avez ou non le module loop.ko intégré dans votre noyau.

Configurez votre image comme un périphérique de bouclage :

# losetup -f -P disk_image

Ensuite, si le périphérique créé était /dev/loop0, des périphériques supplémentaires /dev/loop0pX auront été automatiquement créés, où X est le numéro de la partition. Ces périphériques de bouclage de partition peuvent être montés directement. Par exemple :

# mount /dev/loop0p1 mountpoint

Pour monter l'image disque avec udisksctl, consultez Udisks#Mount loop devices.

Avec kpartx

kpartx du paquet multipath-tools peut lire une table de partition sur un périphérique et créer un nouveau périphérique pour chaque partition. Par exemple :

# kpartx -a disk_image

Ceci configurera le périphérique de bouclage et créera le(s) périphérique(s) de partition nécessaire(s) dans /dev/mapper/.

Montage d'une partition à partir d'une image qcow2

Nous allons utiliser qemu-nbd, qui permet d'utiliser le protocole NBD (network block device) pour partager l'image disque.

Tout d'abord, nous devons charger le module nbd :

# modprobe nbd max_part=16

Ensuite, nous pouvons partager le disque et créer les entrées du périphérique :

# qemu-nbd -c /dev/nbd0 /chemin/vers/image.qcow2

Découvrez les partitions :

# partprobe /dev/nbd0

fdisk peut être utilisé pour obtenir des informations sur les différentes partitions de nbd0 :

# fdisk -l /dev/nbd0
Disk /dev/nbd0: 25.2 GiB, 27074281472 bytes, 52879456 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: 0xa6a4d542

Device      Boot   Start      End  Sectors  Size Id Type
/dev/nbd0p1 *       2048  1026047  1024000  500M  7 HPFS/NTFS/exFAT
/dev/nbd0p2      1026048 52877311 51851264 24.7G  7 HPFS/NTFS/exFAT

Ensuite, montez n'importe quelle partition de l'image du disque, par exemple la partition 2 :

# mount /dev/nbd0p2 mountpoint

Après l'utilisation, il est important de démonter l'image et d'inverser les étapes précédentes, c'est-à-dire démonter la partition et déconnecter le périphérique nbd :

# umount mountpoint
# qemu-nbd -d /dev/nbd0

Utilisation de n'importe quelle partition réelle comme partition primaire unique d'une image de disque dur

Parfois, vous pouvez souhaiter utiliser l'une de vos partitions système à partir de QEMU. L'utilisation d'une partition brute pour une machine virtuelle améliorera les performances, car les opérations de lecture et d'écriture ne passent pas par la couche du système de fichiers sur l'hôte physique. Une telle partition fournit également un moyen de partager des données entre l'hôte et l'invité.

Dans Arch Linux, les fichiers de périphérique pour les partitions brutes sont, par défaut, la propriété de root et du groupe disk. Si vous souhaitez qu'un utilisateur non root puisse lire et écrire sur une partition brute, vous devez soit changer le propriétaire du fichier de périphérique de la partition pour cet utilisateur, ajouter cet utilisateur au groupe disk, ou utiliser ACL pour un contrôle d'accès plus fin.

Attention:
  • Bien que cela soit possible, il n'est pas recommandé de permettre aux machines virtuelles de modifier des données critiques sur le système hôte, comme la partition racine.
  • Vous ne devez pas monter un système de fichiers sur une partition en lecture-écriture sur l'hôte et l'invité en même temps. Sinon, il y aura corruption des données.

Après avoir fait cela, vous pouvez attacher la partition à une machine virtuelle QEMU comme un disque virtuel.

Cependant, les choses sont un peu plus compliquées si vous souhaitez que la machine virtuelle entière soit contenue dans une partition. Dans ce cas, il n'y aura pas de fichier image de disque pour démarrer la machine virtuelle puisque vous ne pouvez pas installer un chargeur d'amorçage sur une partition qui est elle-même formatée comme un système de fichiers et non comme un périphérique partitionné avec un MBR. Une telle machine virtuelle peut être démarrée soit par : #Spécifier le noyau et l'initrd manuellement, #Simulation d'un disque virtuel avec MBR, #Utilisation du device-mapper, #Utilisation d'un RAID linéaire ou #Utilisation d'un périphérique de bloc en réseau.

Spécifier le noyau et l'initrd manuellement

QEMU prend en charge le chargement direct des noyaux Linux et des init ramdisks, contournant ainsi les chargeurs d'amorçage tels que GRUB. Il peut ensuite être lancé avec la partition physique contenant le système de fichiers racine comme disque virtuel, qui ne semblera pas être partitionné. Pour ce faire, il suffit de lancer une commande similaire à la suivante :

Note: Dans cet exemple, ce sont les images de l'hôte qui sont utilisées, pas celles de l'invité. Si vous souhaitez utiliser les images de l'invité, montez /dev/sda3 en lecture seule (pour protéger le système de fichiers de l'hôte) et spécifiez le /full/path/to/images ou utilisez des astuces de kexec dans l'invité pour recharger le noyau de l'invité (prolonge le temps de démarrage).
$ qemu-system-x86_64 -kernel /boot/vmlinuz-linux -initrd /boot/initramfs-linux.img -append root=/dev/sda /dev/sda3

Dans l'exemple ci-dessus, la partition physique utilisée pour le système de fichiers racine de l'invité est /dev/sda3 sur l'hôte, mais elle apparaît comme /dev/sda sur l'invité.

Vous pouvez, bien sûr, spécifier n'importe quel noyau et initrd que vous voulez, et pas seulement ceux qui sont fournis avec Arch Linux.

Quand il y a plusieurs paramètres du noyau à passer à l'option -append, ils doivent être cités en utilisant des guillemets simples ou doubles. Par exemple :

... -append 'root=/dev/sda1 console=ttyS0

Simulation d'un disque virtuel avec MBR

Une manière plus compliquée de faire en sorte qu'une machine virtuelle utilise une partition physique, tout en gardant cette partition formatée en tant que système de fichiers et en ne faisant pas simplement en sorte que l'invité partitionne la partition comme s'il s'agissait d'un disque, est de simuler un MBR pour celle-ci afin qu'elle puisse démarrer à l'aide d'un chargeur d'amorçage tel que GRUB.

Pour ce qui suit, supposons que vous ayez une partition non montée /dev/hdaN avec un système de fichiers sur laquelle vous souhaitez faire partie d'une image disque QEMU. L'astuce consiste à faire précéder dynamiquement d'un master boot record (MBR) la partition réelle que vous souhaitez intégrer dans une image disque brute QEMU. Plus généralement, la partition peut être n'importe quelle partie d'un disque simulé plus grand, en particulier un périphérique de bloc qui simule le disque physique original mais qui n'expose /dev/hdaN que la machine virtuelle.

Un disque virtuel de ce type peut être représenté par un fichier VMDK qui contient des références au MBR et à la partition (une copie de ceux-ci), mais QEMU ne prend pas en charge ce format VMDK. Par exemple, un disque virtuel créé par

$ VBoxManage internalcommands createrawvmdk -filename /path/to/file.vmdk -rawdisk /dev/hda

sera rejetée par QEMU avec le message d'erreur suivant

Type d'image non supporté 'partitionedDevice'

Notez que VBoxManage crée deux fichiers, file.vmdk et file-pt.vmdk, ce dernier étant une copie du MBR, vers lequel pointe le fichier texte file.vmdk. Les opérations de lecture en dehors de la partition cible ou du MBR donneraient des zéros, tandis que les données écrites seraient rejetées.

Utilisation du device-mapper

Une méthode similaire à l'utilisation d'un fichier descripteur VMDK utilise le device-mapper pour ajouter un périphérique en boucle attaché au fichier MBR à la partition cible. Dans le cas où nous n'avons pas besoin que notre disque virtuel ait la même taille que l'original, nous créons d'abord un fichier pour contenir le MBR :

$ dd if=/dev/zero of=/path/to/mbr count=2048

Ici, un fichier de 1 Mio (2048 * 512 octets) est créé conformément aux politiques d'alignement des partitions utilisées par les outils modernes de partitionnement de disques. Pour des raisons de compatibilité avec les anciens logiciels de partitionnement, 63 secteurs au lieu de 2048 peuvent être nécessaires. Le MBR ne nécessite qu'un seul bloc de 512 octets, l'espace libre supplémentaire peut être utilisé pour une partition de démarrage du BIOS et, dans le cas d'un schéma de partitionnement hybride, pour une table de partition GUID. Ensuite, nous attachons un périphérique en boucle au fichier MBR :

# losetup --show -f /path/to/mbr - /dev/loop0
/dev/loop0

Dans cet exemple, le périphérique résultant est /dev/loop0. Le mappeur de périphériques est maintenant utilisé pour joindre le MBR et la partition :

# echo "0 2048 linear /dev/loop0 0
2048 `blockdev --getsz /dev/hda' 'N` linear /dev/hda' 'N 0" | dmsetup create qemu

Le résultat /dev/mapper/qemu est ce que nous allons utiliser comme image disque brute QEMU. Des étapes supplémentaires sont nécessaires pour créer une table de partition (consultez la section qui décrit l'utilisation d'un RAID linéaire pour un exemple) et le code du chargeur d'amorçage sur le disque virtuel (qui sera stocké dans /path/to/mbr).

La configuration suivante est un exemple où la position de /dev/hdaN sur le disque virtuel doit être la même que sur le disque physique et le reste du disque est caché, à l'exception du MBR, qui est fourni en copie :

# dd if=/dev/hda count=1 of=/path/to/mbr
# loop=`losetup --show -f /path/to/mbr`
# start=`blockdev --report /dev/hdaN | tail -1 | awk '{print $5}'`
# size=`blockdev --getsz /dev/hdaN`
# disksize=`blockdev --getsz /dev/hda`
# echo "0 1 linear $loop 0
1 $((start-1)) zero
$start $size linear /dev/hdaN 0
$((start+size)) $((disksize-start-size)) zero" | dmsetup create qemu

La table fournie en entrée standard à dmsetup a un format similaire à celui de la table d'un fichier descripteur VMDK produit par VBoxManage et peut également être chargée à partir d'un fichier avec dmsetup create qemu --table table_file. Pour la machine virtuelle, seul /dev/hdaN est accessible, tandis que le reste du disque dur est lu comme des zéros et rejette les données écrites, sauf pour le premier secteur. Nous pouvons imprimer la table pour /dev/mapper/qemu avec dmsetup table qemu. (utilisez udevadm info -rq name /sys/dev/block/major:minor pour traduire major:minor au nom correspondant /dev/blockdevice). Utilisez dmsetup remove qemu et losetup -d $loop pour supprimer les périphériques créés.

Une situation où cet exemple serait utile est une installation existante de Windows XP dans une configuration multi-boot et peut-être un schéma de partitionnement hybride (sur le matériel physique, Windows XP pourrait être le seul système d'exploitation qui utilise la table de partition MBR, tandis que des systèmes d'exploitation plus modernes installés sur le même ordinateur pourraient utiliser la table de partition GUID). Windows XP prend en charge les profils matériels, de sorte que la même installation peut être utilisée alternativement avec différentes configurations matérielles (dans ce cas, bare metal et virtuel), Windows n'ayant besoin d'installer les pilotes pour le matériel nouvellement détecté qu'une seule fois pour chaque profil. Notez que dans cet exemple, le code du chargeur d'amorçage dans le MBR copié doit être mis à jour pour charger directement Windows XP à partir de /dev/hdaN au lieu d'essayer de lancer le chargeur d'amorçage multi-boot (comme GRUB) présent dans le système d'origine. Alternativement, une copie de la partition de démarrage contenant l'installation du chargeur d'amorçage peut être incluse dans le disque virtuel de la même manière que le MBR.

Utilisation d'un RAID linéaire

Vous pouvez également le faire en utilisant un RAID logiciel en mode linéaire (vous avez besoin du pilote du noyau linear.ko) et d'un périphérique de bouclage :

D'abord, vous créez un petit fichier pour contenir le MBR :

$ dd if=/dev/zero of=/path/to/mbr count=32

Ici, un fichier de 16 Kio (32 * 512 octets) est créé. Il est important de ne pas le rendre trop petit (même si le MBR n'a besoin que d'un seul bloc de 512 octets), car plus il sera petit, plus la taille des morceaux du dispositif RAID logiciel devra être petite, ce qui pourrait avoir un impact sur les performances. Ensuite, vous configurez un périphérique de bouclage vers le fichier MBR :

# losetup -f /path/to/mbr.

Supposons que le périphérique résultant soit /dev/loop0, car nous n'aurions pas déjà utilisé d'autres boucles. L'étape suivante consiste à créer l'image disque MBR + /dev/hdaN "fusionnée" en utilisant le RAID logiciel :

# modprobe linear
# mdadm --build --verbose /dev/md0 --chunk=16 --level=linear --raid-devices=2 /dev/loop0 /dev/hdaN'

Le résultat /dev/md0 est ce que vous utiliserez comme image disque brute QEMU (n'oubliez pas de définir les permissions pour que l'émulateur puisse y accéder). La dernière étape (et quelque peu délicate) consiste à définir la configuration du disque (géométrie du disque et table des partitions) de sorte que le point de départ de la partition primaire dans le MBR corresponde à celui de /dev/hdaN à l'intérieur de /dev/md0. (un décalage d'exactement 16 * 512 = 16384 octets dans cet exemple). Faites ceci en utilisant fdisk sur la machine hôte, pas dans l'émulateur : la routine de détection de disque brut par défaut de QEMU résulte souvent en des décalages non arrondissables en kilooctets (comme 31,5 Kio, comme dans la section précédente) qui ne peuvent pas être gérés par le code RAID logiciel. Par conséquent, depuis l'hôte :

# fdisk /dev/md0

Appuyez sur X pour accéder au menu expert. Définissez le nombre de secteurs par piste de sorte que la taille d'un cylindre corresponde à la taille de votre fichier MBR. Pour deux têtes et une taille de secteur de 512, le nombre de secteurs par piste doit être de 16, ce qui donne des cylindres de taille 2x16x512=16k.

Maintenant, appuyez sur R pour revenir au menu principal.

Appuyez sur P et vérifiez que la taille du cylindre est maintenant de 16k.

Maintenant, créez une partition primaire unique correspondant à /dev/hdaN. Elle doit commencer au cylindre 2 et se terminer à la fin du disque (notez que le nombre de cylindres diffère maintenant de ce qu'il était lorsque vous avez entré fdisk.

Enfin, écrivez le résultat dans le fichier : vous avez terminé. Vous avez maintenant une partition que vous pouvez monter directement depuis votre hôte, ainsi qu'une partie d'une image disque QEMU :

$ qemu-system-x86_64 -hdc /dev/md0 [...]'.

Vous pouvez, bien sûr, installer en toute sécurité n'importe quel chargeur d'amorçage sur cette image disque à l'aide de QEMU, à condition que la partition originale /dev/hdaN contienne les outils nécessaires.

Utilisation d'un périphérique de bloc en réseau

Avec Network Block Device, Linux peut utiliser un serveur distant comme l'un de ses périphériques de bloc. Vous pouvez utiliser nbd-server (du paquet nbd) pour créer une enveloppe MBR pour QEMU.

En supposant que vous avez déjà configuré votre fichier de wrapper MBR comme ci-dessus, renommez-le en wrapper.img.0. Créez ensuite un lien symbolique nommé wrapper.img.1 dans le même répertoire, pointant vers votre partition. Ensuite, mettez le script suivant dans le même répertoire :

#!/bin/sh
dir="$(realpath "$(dirname "$0")")"
cat >wrapper.conf <<EOF
[generic]
allowlist = true
listenaddr = 127.713705
port = 10809

[wrap]
exportname = $dir/wrapper.img
multifile = true
EOF

nbd-server \
    -C wrapper.conf \
    -p wrapper.pid \
    "$@"

Les suffixes .0 et .1 sont essentiels ; le reste peut être modifié. Après avoir exécuté le script ci-dessus (que vous devrez peut-être faire en tant que root pour vous assurer que nbd-server est capable d'accéder à la partition), vous pouvez lancer QEMU avec :

qemu-system-x86_64 -drive file=nbd:127.713705:10809:exportname=wrap [...]".

Utilisation d'un périphérique de disque physique entier à l'intérieur de la VM

Vous pouvez avoir un deuxième disque dur avec un système d'exploitation différent (comme Windows) et vous voulez avoir la possibilité de le démarrer dans une VM. Comme l'accès au disque est brut, le disque fonctionnera très bien à l'intérieur de la VM.

prérequis pour le démarrage de la VM Windows

Assurez-vous d'installer les drivers virtio dans le système d'exploitation sur ce disque avant d'essayer de le démarrer dans la VM. Pour Win 7, utilisez la version 0.1.173-4. Certains pilotes singuliers de versions plus récentes de virtio peuvent être utilisés sur Win 7 mais vous devrez les installer manuellement via le gestionnaire de périphériques. Pour Win 10, vous pouvez utiliser la dernière version de virtio.

configurer les pilotes de l'interface disque de windows

Il se peut que vous obteniez un écran bleu 0x0000007B lorsque vous essayez de démarrer la VM. Cela signifie que Windows ne peut pas accéder au lecteur pendant la phase de démarrage précoce parce que le pilote d'interface de disque dont il aurait besoin pour cela n'est pas chargé / est configuré pour démarrer manuellement.

La solution consiste à activer ces pilotes pour qu'ils démarrent au démarrage.

Dans HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services, trouvez les dossiers aliide, amdide, atapi, cmdide, iastor (peut ne pas exister), iastorV, intelide, LSI_SAS, msahci, pciide et viaide. Dans chacun d'entre eux, définissez toutes les valeurs de "start" à 0 afin de les activer au démarrage. Si votre disque est un disque PCIe NVMe, activez également ce pilote (s'il existe).

trouver le chemin unique de votre disque

Exécutez ls /dev/disk/by-id/. Là, vous choisissez l'ID du disque que vous voulez insérer dans la VM, mon ID de disque est ata-TS512GMTS930L_C199211383. Ajoutez maintenant cet ID à /dev/disk/by-id/ pour obtenir /dev/disk/by-id/ata-TS512GMTS930L_C199211383. C'est le chemin unique vers ce disque.

ajouter le disque dans la CLI QEMU

Dans la CLI de QEMU, ce serait probablement :

-drive file=/dev/disk/by-id/ata-TS512GMTS930L_C199211383,format=raw,media=disk

Modifiez simplement "file=" pour qu'il soit le chemin unique de votre disque.

ajouter le disque dans libvirt

Dans le xml de libvirt, cela se traduit par

$ virsh edit vmname
...
    <disk type="block" device="disk">
      <driver name="qemu" type="raw" cache="none" io="native"/>
      <source dev="/dev/disk/by-id/ata-TS512GMTS930L_C199211383"/>
      <target dev="sda" bus="sata"/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>
...

Modifiez simplement "source dev" pour qu'il soit le chemin unique de votre disque.

ajouter le disque dans virt-manager

Lorsque vous créez une VM, sélectionnez "import existing drive" et collez simplement ce chemin unique. Si vous avez déjà la VM, ajoutez un périphérique, un stockage, puis sélectionnez ou créez un stockage personnalisé. Collez ensuite le chemin d'accès unique.

Mise en réseau

Les performances de la mise en réseau virtuelle devraient être meilleures avec les périphériques tap et les ponts qu'avec la mise en réseau en mode utilisateur ou vde car les périphériques tap et les ponts sont implémentés dans le noyau.

En outre, les performances de mise en réseau peuvent être améliorées en assignant aux machines virtuelles un périphérique réseau virtio plutôt que l'émulation par défaut d'une carte réseau e1000. Consultez #Installation des pilotes virtio pour plus d'informations.

Mise en garde concernant l'adresse au niveau du lien

En donnant l'argument -net nic à QEMU, celui-ci attribuera, par défaut, à une machine virtuelle une interface réseau avec l'adresse de niveau lien 52:54:00:12:34:56. Cependant, lors de l'utilisation d'une mise en réseau pontée avec plusieurs machines virtuelles, il est essentiel que chaque machine virtuelle ait une adresse unique de niveau lien (MAC) du côté de la machine virtuelle du périphérique de connexion. Sinon, le pont ne fonctionnera pas correctement, car il recevra des paquets de plusieurs sources ayant la même adresse de niveau de liaison. Ce problème se produit même si les périphériques de dérivation eux-mêmes ont des adresses de niveau de lien uniques car l'adresse de niveau de lien source n'est pas réécrite lorsque les paquets passent par le périphérique de dérivation.

Assurez-vous que chaque machine virtuelle possède une adresse de niveau lien unique, mais elle doit toujours commencer par 52:54:. Utilisez l'option suivante, remplacez X par un chiffre hexadécimal arbitraire :

$ qemu-system-x86_64 -net nic,macaddr=52:54:XX:XX:XX:XX -net vde disk_image -net vde disk_image.

La génération d'adresses uniques au niveau des liens peut se faire de plusieurs manières :

  • Spécifier manuellement une adresse unique de niveau lien pour chaque NIC. L'avantage est que le serveur DHCP attribuera la même adresse IP à chaque fois que la machine virtuelle est exécutée, mais cette méthode est inutilisable pour un grand nombre de machines virtuelles.
  • Générer une adresse aléatoire au niveau du lien à chaque fois que la machine virtuelle est exécutée. La probabilité de collisions est pratiquement nulle, mais l'inconvénient est que le serveur DHCP attribuera une adresse IP différente à chaque fois. Vous pouvez utiliser la commande suivante dans un script pour générer une adresse de niveau lien aléatoire dans une variable macaddr :
printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff ))
qemu-system-x86_64 -net nic,macaddr="$macaddr" -net vde disk_image
  • Utilisez le script suivant qemu-mac-hasher.py pour générer l'adresse de niveau lien à partir du nom de la machine virtuelle en utilisant une fonction de hachage. Étant donné que les noms des machines virtuelles sont uniques, cette méthode combine les avantages des méthodes susmentionnées : elle génère la même adresse de niveau lien à chaque exécution du script, tout en préservant la probabilité pratiquement nulle de collisions.
qemu-mac-hasher.py
#!/usr/bin/env python
# utilisation : qemu-mac-hasher.py <VMName>

import sys
import zlib

crc = str(hex(zlib.crc32(sys.argv[1].encode("utf-8")))).replace("x", "")[-8 :]
print("52:54:%s%s:%s%s:%s%s:%s%s" % tuple(crc))

Dans un script, vous pouvez utiliser par exemple :

vm_name="Nom de la VM"
qemu-system-x86_64 -name $vm_name -net nic,macaddr=$(qemu-mac-hasher.py $vm_name) -net vde disk_image 

Mise en réseau en mode utilisateur

Par défaut, sans aucun argument -netdev, QEMU utilisera un réseau en mode utilisateur avec un serveur DHCP intégré. Vos machines virtuelles se verront attribuer une adresse IP lorsqu'elles exécuteront leur client DHCP, et elles pourront accéder au réseau de l'hôte physique grâce au masquage d'IP effectué par QEMU.

Note: ICMPv6 ne fonctionnera pas, car sa prise en charge n'est pas implémentée : Slirp : external icmpv6 not supported yet. Le ping d'une adresse IPv6 ne fonctionnera pas.

Cette configuration par défaut permet à vos machines virtuelles d'accéder facilement à Internet, à condition que l'hôte y soit connecté, mais les machines virtuelles ne seront pas directement visibles sur le réseau externe, et les machines virtuelles ne pourront pas parler entre elles si vous en démarrez plusieurs simultanément.

La mise en réseau en mode utilisateur de QEMU peut offrir plus de possibilités, comme des serveurs TFTP ou SMB intégrés, la redirection des ports de l'hôte vers l'invité (par exemple pour permettre des connexions SSH vers l'invité) ou l'attachement des invités à des VLAN afin qu'ils puissent se parler entre eux. Consultez la documentation de QEMU sur l'option -net user pour plus de détails.

Cependant, la mise en réseau en mode utilisateur a des limites à la fois en termes d'utilité et de performance. Les configurations de réseau plus avancées nécessitent l'utilisation de périphériques de connexion ou d'autres méthodes.

Note: Si le système hôte utilise systemd-networkd, assurez-vous de faire un lien symbolique au fichier /etc/resolv.conf comme décrit dans systemd-networkd (Français)#Services requis et configuration, sinon la recherche DNS dans le système invité ne fonctionnera pas.
Astuce: Pour utiliser le pilote virtio avec une mise en réseau en mode utilisateur, l'option est : -nic user,model=virtio-net-pci.

Mise en réseau avec tap pour QEMU

Les périphériques tap sont une fonctionnalité du noyau Linux qui vous permet de créer des interfaces réseau virtuelles qui apparaissent comme des interfaces réseau réelles. Les paquets envoyés à une interface tap sont délivrés à un programme en espace utilisateur, tel que QEMU, qui s'est lié à l'interface.

QEMU peut utiliser la mise en réseau par tap pour une machine virtuelle afin que les paquets envoyés à l'interface tap soient envoyés à la machine virtuelle et apparaissent comme provenant d'une interface réseau (généralement une interface Ethernet) dans la machine virtuelle. Inversement, tout ce que la machine virtuelle envoie via son interface réseau apparaîtra sur l'interface tap.

Les périphériques tap sont pris en charge par les pilotes de pontage Linux, il est donc possible de relier les périphériques tap entre eux et éventuellement avec d'autres interfaces hôtes telles que eth0. Ceci est souhaitable si vous voulez que vos machines virtuelles puissent se parler entre elles ou si vous voulez que d'autres machines sur votre LAN puissent parler aux machines virtuelles.

Attention: Si vous établissez un pont entre le périphérique de claquage et une interface hôte, telle que eth0, vos machines virtuelles apparaîtront directement sur le réseau externe, ce qui les exposera à une éventuelle attaque. En fonction des ressources auxquelles vos machines virtuelles ont accès, vous devrez peut-être prendre toutes les précautions que vous prendriez normalement pour sécuriser un ordinateur afin de sécuriser vos machines virtuelles. Si le risque est trop grand, que les machines virtuelles ont peu de ressources ou que vous configurez plusieurs machines virtuelles, une meilleure solution pourrait être d'utiliser mise en réseau avec l'hôte uniquement et de configurer la NAT. Dans ce cas, vous n'avez besoin que d'un seul pare-feu sur l'hôte au lieu de plusieurs pare-feu pour chaque invité.

Comme indiqué dans la section sur la mise en réseau en mode utilisateur, les périphériques tap offrent des performances de mise en réseau plus élevées qu'en mode utilisateur. Si le système d'exploitation invité prend en charge le pilote réseau virtio, les performances réseau seront également considérablement améliorées. En supposant l'utilisation du périphérique tap0, que le pilote virtio est utilisé sur l'invité, et qu'aucun script n'est utilisé pour aider à démarrer/arrêter la mise en réseau, voici une partie de la commande qemu que l'on devrait consulter :

-device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no

Mais si vous utilisez déjà un périphérique tap avec le pilote réseau de virtio, vous pouvez encore améliorer les performances réseau en activant vhost, comme suit :

-device virtio-net,netdev=network0 -netdev tap,id=network0,ifname=tap0,script=no,downscript=no,vhost=on

Consultez [2] pour plus d'informations.

Mise en réseau uniquement avec l'hôte

Si une adresse IP est attribuée au pont et que le trafic qui lui est destiné est autorisé, mais qu'aucune interface réelle (par exemple, eth0) n'est connectée au pont, les machines virtuelles pourront communiquer entre elles et avec le système hôte. Cependant, elles ne pourront pas parler à quoi que ce soit sur le réseau externe, à condition que vous ne configuriez pas de masquage d'IP sur l'hôte physique. Cette configuration est appelée mise en réseau de l'hôte uniquement par d'autres logiciels de virtualisation tels que VirtualBox.

Astuce:
  • Si vous souhaitez configurer le masquage d'adresses IP, par exemple le NAT pour les machines virtuelles, consultez la page Internet sharing (Français)#Activer le NAT.
  • Consultez la page Network bridge pour obtenir des informations sur la création de ponts.
  • Il se peut que vous souhaitiez qu'un serveur DHCP fonctionne sur l'interface du pont pour desservir le réseau virtuel. Par exemple, pour utiliser le sous-réseau 172.20.0.1/16 avec dnsmasq comme serveur DHCP :
# ip addr add 172.20.0.1/16 dev br0
# ip link set br0 up
# dnsmasq --interface=br0 --bind-interfaces --dhcp-range=172.20.0.2,172.20.255.254

Réseau interne

Si vous ne donnez pas d'adresse IP au pont et que vous ajoutez une règle iptables pour supprimer tout le trafic vers le pont dans la chaîne INPUT, les machines virtuelles pourront communiquer entre elles, mais pas avec l'hôte physique ni avec le réseau extérieur. Cette configuration est appelée réseau interne par d'autres logiciels de virtualisation tels que VirtualBox. Vous devrez soit attribuer des adresses IP statiques aux machines virtuelles, soit exécuter un serveur DHCP sur l'une d'entre elles.

Par défaut, iptables laisse tomber les paquets dans le réseau ponté. Vous devrez peut-être utiliser une telle règle iptables pour autoriser les paquets dans un réseau ponté :

# iptables -I FORWARD -m physdev --physdev-is-bridged -j ACCEPT

Réseau ponté utilisant qemu-bridge-helper

Cette méthode ne nécessite pas de script de démarrage et s'adapte facilement à des prises multiples et à des ponts multiples. Elle utilise le binaire /usr/lib/qemu/qemu-bridge-helper, qui permet de créer des périphériques de prise sur un pont existant.

Astuce:

Tout d'abord, créez un fichier de configuration contenant les noms de tous les ponts à utiliser par QEMU :

/etc/qemu/bridge.conf
allow br0 (autoriser)
allow br1 (autoriser br1)
...

Assurez-vous que /etc/qemu/ a 755 permissions. Si ce n'est pas le cas, des problèmes avec QEMU et problèmes avec GNS3 peuvent survenir.

Maintenant démarrez la VM ; l'utilisation la plus basique est d'exécuter QEMU avec l'aide réseau par défaut et le pont par défaut br0 :

$ qemu-system-x86_64 -nic bridge [...]'.

En utilisant le pont br1 et le pilote virtio :

$ qemu-system-x86_64 -nic bridge,br=br1,model=virtio-net-pci [...]'

Créer un pont manuellement

Astuce: Depuis QEMU 1.1, le network bridge helper peut configurer tun/tap pour vous sans avoir besoin de script supplémentaire. Consultez #Réseau ponté utilisant qemu-bridge-helper.

Ce qui suit décrit comment établir un pont entre une machine virtuelle et une interface hôte telle que eth0, qui est probablement la configuration la plus courante. Cette configuration donne l'impression que la machine virtuelle est située directement sur le réseau externe, sur le même segment Ethernet que la machine hôte physique.

Nous allons remplacer l'adaptateur Ethernet normal par un adaptateur pont et lier l'adaptateur Ethernet normal à celui-ci.

  • Installer bridge-utils, qui fournit brctl pour manipuler les ponts.
  • Activez le transfert d'IPv4 :
# sysctl -w net.ipv4.ip_forward=1

Pour rendre le changement permanent, changez net.ipv4.ip_forward = 0 en net.ipv4.ip_forward = 1 dans /etc/sysctl.d/99-sysctl.conf.

  • Chargez le module tun et configurez-le pour qu'il soit chargé au démarrage. Consultez Modules du noyau pour plus de détails.
  • Créez maintenant le pont. Consultez Bridge with netctl pour plus de détails. N'oubliez pas de nommer votre pont comme br0, ou changez les scripts ci-dessous avec le nom de votre pont.
  • Créez le script que QEMU utilise pour faire apparaître l'adaptateur de robinet avec root:kvm, permissions 750 :
/etc/qemu-ifup
#!/bin/sh

echo "Executing /etc/qemu-ifup"
echo "Bringing up $1 for bridged mode..."
sudo /usr/bin/ip link set $1 up promisc on
echo "Adding $1 to br0..."
sudo /usr/bin/brctl addif br0 $1
sleep 2
  • Créez le script que QEMU utilise pour mettre hors service l'adaptateur tap dans /etc/qemu-ifdown avec root:kvm permissions 750 :
/etc/qemu-ifdown
#!/bin/sh

echo "Executing /etc/qemu-ifdown"
sudo /usr/bin/ip link set $1 down
sudo /usr/bin/brctl delif br0 $1
sudo /usr/bin/ip link delete dev $1
  • Utilisez visudo pour ajouter les éléments suivants à votre fichier sudoers :
Cmnd_Alias QEMU=/usr/bin/ip,/usr/bin/modprobe,/usr/bin/brctl
%kvm ALL=NOPASSWD : QEMU
  • Vous lancez QEMU en utilisant le script run-qemu suivant :
run-qemu
#!/bin/bash
USERID=$(whoami)

# Obtenir le nom du périphérique TAP nouvellement créé ; consultez https://bbs.archlinux.org/viewtopic.php?pid=1285079#p1285079
precreationg=$(/usr/bin/ip tuntap list | /usr/bin/cut -d : -f1 | /usr/bin/sort)
sudo /usr/bin/ip tuntap add user $USERID mode tap
postcreation=$(/usr/bin/ip tuntap list | /usr/bin/cut -d : -f1 | /usr/bin/sort)
IFACE=$(comm -13 <(echo "$precreationg") <(echo "$postcreation"))

# Cette ligne crée une adresse MAC aléatoire. L'inconvénient est que le serveur DHCP assignera une adresse IP différente à chaque fois
printf -v macaddr "52:54:%02x:%02x:%02x:%02x" $(( $RANDOM & 0xff)) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff )) $(( $RANDOM & 0xff ))
# Au lieu de cela, décommentez et modifiez cette ligne pour définir une adresse MAC statique. L'avantage est que le serveur DHCP attribuera la même adresse IP.
# macaddr='52:54:be:36:42:a9'

qemu-system-x86_64 -net nic,macaddr=$macaddr -net tap,ifname="$IFACE" $*

sudo ip link set dev $IFACE down &> /dev/null
sudo ip tuntap del $IFACE mode tap &> /dev/null

Ensuite, pour lancer une VM, faites quelque chose comme ceci

$ run-qemu -hda myvm.img -m 512
  • Il est recommandé, pour des raisons de performance et de sécurité, de désactiver le pare-feu sur le pont :
/etc/sysctl.d/10-disable-firewall-on-bridge.conf
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

Exécutez sysctl -p /etc/sysctl.d/10-disable-firewall-on-bridge.conf pour appliquer les modifications immédiatement.

Consultez le wiki de libvirt et bug de Fedora n°512206. Si vous obtenez des erreurs par sysctl pendant le démarrage à propos de fichiers inexistants, faites en sorte que le module bridge soit chargé au démarrage. Consultez Kernel module (Français)#Chargement automatique des modules.

Alternativement, vous pouvez configurer iptables pour permettre à tout le trafic d'être transféré à travers le pont en ajoutant une règle comme celle-ci :

-I FORWARD -m physdev --physdev-is-bridged -j ACCEPT

Partage de réseau entre un périphérique physique et un périphérique Tap via iptables

Le réseau ponté fonctionne bien entre une interface câblée (par exemple eth0), et il est facile à configurer. Cependant, si l'hôte est connecté au réseau par un périphérique sans fil, le pontage n'est pas possible.

Consultez Network bridge#Wireless interface on a bridge comme référence.

Une façon de surmonter ce problème est de configurer un périphérique de connexion avec une IP statique, en faisant en sorte que linux gère automatiquement le routage pour lui, puis de transférer le trafic entre l'interface de connexion et le périphérique connecté au réseau par le biais de règles iptables.

Consultez Internet sharing (Français) comme référence.

Vous y trouverez tout ce qui est nécessaire pour partager le réseau entre les appareils, y compris les appareils tap et tun. Ce qui suit ne fait que donner des indications supplémentaires sur certaines des configurations d'hôtes requises. Comme indiqué dans la référence ci-dessus, le client doit être configuré pour une IP statique, en utilisant l'IP assignée à l'interface tap comme passerelle. La mise en garde est que les serveurs DNS sur le client peuvent devoir être édités manuellement s'ils changent lors du passage d'un périphérique hôte connecté au réseau à un autre.

Pour autoriser la redirection IP à chaque démarrage, il faut ajouter les lignes suivantes au fichier de configuration sysctl dans /etc/sysctl.d :

net.ipv4.ip_forward = 1
net.ipv6.conf.default.forwarding = 1
net.ipv6.conf.all.forwarding = 1

Les règles iptables peuvent ressembler à ceci :

# Transfert de/vers l'extérieur
iptables -A FORWARD -i ${INT} -o ${EXT_0} -j ACCEPT
iptables -A FORWARD -i ${INT} -o ${EXT_1} -j ACCEPT
iptables -A FORWARD -i ${INT} -o ${EXT_2} -j ACCEPT
iptables -A FORWARD -i ${EXT_0} -o ${INT} -j ACCEPT
iptables -A FORWARD -i ${EXT_1} -o ${INT} -j ACCEPT
iptables -A FORWARD -i ${EXT_2} -o ${INT} -j ACCEPT
# NAT/Masquerade (traduction d'adresse réseau)
iptables -t nat -A POSTROUTING -o ${EXT_0} -j MASQUERADE
iptables -t nat -A POSTROUTING -o ${EXT_1} -j MASQUERADE
iptables -t nat -A POSTROUTING -o ${EXT_2} -j MASQUERADE

L'antérieur suppose qu'il y a 3 dispositifs connectés au réseau partageant le trafic avec un dispositif interne, où par exemple :

INT=tap0
EXT_0=eth0
EXT_1=wlan0
EXT_2=tun0

L'exemple précédent montre une redirection qui permettrait de partager des connexions câblées et sans fil avec le périphérique tap.

Les règles de transfert présentées sont sans état, et pour un transfert pur. On pourrait penser à restreindre un trafic spécifique, en mettant en place un pare-feu pour protéger l'invité et les autres. Cependant, ces mesures réduiraient les performances du réseau, alors qu'un simple pont n'inclut rien de tout cela.

Bonus : que la connexion soit filaire ou sans fil, si l'on se connecte par VPN à un site distant avec un périphérique tun, en supposant que le périphérique tun ouvert pour cette connexion est tun0, et que les règles iptables précédentes sont appliquées, alors la connexion distante est également partagée avec l'invité. Cela évite à l'invité d'avoir à ouvrir également une connexion VPN. Encore une fois, comme le réseau de l'invité doit être statique, si l'on connecte l'hôte à distance de cette façon, il faudra très probablement modifier les serveurs DNS de l'invité.

Mise en réseau avec VDE2

Qu'est-ce que VDE ?

VDE est l'abréviation de Virtual Distributed Ethernet. Il a commencé comme une amélioration de uml_switch. Il s'agit d'une boîte à outils pour gérer les réseaux virtuels.

L'idée est de créer des commutateurs virtuels, qui sont en fait des prises, et d'y "brancher" des machines physiques et virtuelles. La configuration que nous montrons ici est assez simple ; cependant, VDE est beaucoup plus puissant que cela, il peut brancher des commutateurs virtuels ensemble, les faire fonctionner sur différents hôtes et surveiller le trafic dans les commutateurs. Vous êtes invités à lire la documentation du projet.

L'avantage de cette méthode est que vous ne devez pas ajouter les privilèges sudo à vos utilisateurs. Les utilisateurs ordinaires ne doivent pas être autorisés à exécuter modprobe.

Notions de base

Installez le paquet vde2 si vous souhaitez la prise en charge de VDE.

Dans notre configuration, nous utilisons tun/tap pour créer une interface virtuelle sur mon hôte. Chargez le module tun (consultez Modules du noyau pour plus de détails) :

# modprobe tun

Créez maintenant le commutateur virtuel :

# vde_switch -tap tap0 -daemon -mod 660 -group users

Cette ligne crée le commutateur, crée tap0, le "branche", et permet aux utilisateurs du groupe users de l'utiliser.

L'interface est branchée mais pas encore configurée. Pour la configurer, exécutez cette commande :

# ip addr add 192.168.100.254/24 dev tap0

Maintenant, il vous suffit de lancer KVM avec ces options -net comme un utilisateur normal :

$ qemu-system-x86_64 -net nic -net vde -hda [...]'.

Configurez le réseau pour votre invité comme vous le feriez dans un réseau physique.

Astuce: Vous voudrez peut-être configurer NAT sur le périphérique de robinet pour accéder à l'Internet à partir de la machine virtuelle. Consultez Internet sharing (Français)#Activer le NAT pour plus d'informations.

Scripts de démarrage

Exemple de script principal démarrant VDE :

/etc/systemd/scripts/qemu-network-env
#!/bin/sh
# QEMU/VDE network environment preparation script

# The IP configuration for the tap device that will be used for
# the virtual machine network:

TAP_DEV=tap0
TAP_IP=192.168.100.254
TAP_MASK=24
TAP_NETWORK=192.168.100.0

# Host interface
NIC=eth0

case "$1" in
  start)
        echo -n "Starting VDE network for QEMU: "

        # If you want tun kernel module to be loaded by script uncomment here
	#modprobe tun 2>/dev/null
	## Wait for the module to be loaded
 	#while ! lsmod | grep -q "^tun"; do echo "Waiting for tun device"; sleep 1; done

        # Start tap switch
        vde_switch -tap "$TAP_DEV" -daemon -mod 660 -group users

        # Bring tap interface up
        ip address add "$TAP_IP"/"$TAP_MASK" dev "$TAP_DEV"
        ip link set "$TAP_DEV" up

        # Start IP Forwarding
        echo "1" > /proc/sys/net/ipv4/ip_forward
        iptables -t nat -A POSTROUTING -s "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE
        ;;
  stop)
        echo -n "Stopping VDE network for QEMU: "
        # Delete the NAT rules
        iptables -t nat -D POSTROUTING -s "$TAP_NETWORK"/"$TAP_MASK" -o "$NIC" -j MASQUERADE

        # Bring tap interface down
        ip link set "$TAP_DEV" down

        # Kill VDE switch
        pgrep vde_switch | xargs kill -TERM
        ;;
  restart|reload)
        $0 stop
        sleep 1
        $0 start
        ;;
  *)
        echo "Usage: $0 {start|stop|restart|reload}"
        exit 1
esac
exit 0

Exemple de service systemd utilisant le script ci-dessus :

/etc/systemd/system/qemu-network-env.service
[Unit]
Description=Manage VDE Switch

[Service]
Type=oneshot
ExecStart=/etc/systemd/scripts/qemu-network-env start
ExecStop=/etc/systemd/scripts/qemu-network-env stop
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Changez les permissions pour que qemu-network-env soit exécutable.

Démarrez qemu-network-env.service comme d'habitude.

Méthode alternative

Si la méthode ci-dessus ne fonctionne pas ou si vous ne voulez pas vous embêter avec les configurations du noyau, TUN, dnsmasq, et iptables, vous pouvez faire ce qui suit pour le même résultat.

# vde_switch -daemon -mod 660 -group users
# slirpvde --dhcp --daemon

Ensuite, pour démarrer la VM avec une connexion au réseau de l'hôte :

$ qemu-system-x86_64 -net nic,macaddr=52:54:00:00:EE:03 -net vde disk_image

Pont VDE2

Basé sur le graphique tutoriel rapide : mise en réseau de qemu avec vde, tun/tap, et pont. Toute machine virtuelle connectée à vde est exposée à l'extérieur. Par exemple, chaque machine virtuelle peut recevoir une configuration DHCP directement de votre routeur ADSL.

Notions de base

Rappelez-vous que vous avez besoin du module tun et du paquet bridge-utils.

Créez le périphérique vde2/tap :

# vde_switch -tap tap0 -daemon -mod 660 -group users
# ip link set tap0 up

Créez un pont :

# brctl addbr br0

Ajouter des périphériques :

# brctl addif br0 eth0
# brctl addif br0 tap0

Et configurez l'interface du pont :

# dhcpcd br0

Scripts de démarrage

Tous les périphériques doivent être configurés. Et seul le pont a besoin d'une adresse IP. Pour les périphériques physiques sur le pont (par exemple eth0), cela peut être fait avec netctl en utilisant un profil Ethernet personnalisé avec :

/etc/netctl/ethernet-noip
Description='A more versatile static Ethernet connection'
Interface=eth0
Connection=ethernet
IP=no

Le service systemd personnalisé suivant peut être utilisé pour créer et activer une interface de connexion VDE2 pour les utilisateurs du groupe users.

/etc/systemd/system/vde2@.service
[Unit]
Description=Network Connectivity for %i
Wants=network.target
Before=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/vde_switch -tap %i -daemon -mod 660 -group users
ExecStart=/usr/bin/ip link set dev %i up
ExecStop=/usr/bin/ip addr flush dev %i
ExecStop=/usr/bin/ip link set dev %i down

[Install]
WantedBy=multi-user.target

Et enfin, vous pouvez créer l'interface bridge avec netctl.

Configuration abrégée

Si vous utilisez souvent QEMU avec diverses options de réseau, vous avez probablement créé beaucoup de paires d'arguments -netdev et -device, ce qui devient assez répétitif. Vous pouvez plutôt utiliser l'argument -nic pour combiner -netdev et -device ensemble, de sorte que, par exemple, ces arguments :

-netdev tap,id=network0,ifname=tap0,script=no,downscript=no,vhost=on -device virtio-net-pci,netdev=network0

devient :

-nic tap,script=no,downscript=no,vhost=on,model=virtio-net-pci

Remarquez l'absence d'ID de réseau, et que le périphérique a été créé avec model=. La première moitié des paramètres -nic sont des paramètres -netdev, tandis que la seconde moitié (après model=) est liée au périphérique. Les mêmes paramètres (par exemple, smb=) sont utilisés. Pour désactiver complètement la mise en réseau, utilisez -nic none.

Consultez documentation sur la mise en réseau de QEMU pour plus d'informations sur les paramètres que vous pouvez utiliser.

Carte graphique

QEMU peut émuler le mode texte d'une carte graphique standard en utilisant l'option de ligne de commande -curses. Cela permet de taper du texte et de consulter la sortie texte directement dans un terminal texte. Alternativement, -nographic sert un but similaire.

QEMU peut émuler plusieurs types de cartes VGA. Le type de carte est passé dans l'option de ligne de commande -vga type et peut être std, qxl, vmware, virtio, cirrus ou none.

std

Avec -vga std, vous pouvez obtenir une résolution allant jusqu'à 2560 x 1600 pixels sans avoir besoin de pilotes invités. C'est la valeur par défaut depuis QEMU 2.2.

qxl

QXL est un pilote graphique paravirtuel avec un support 2D. Pour l'utiliser, passez l'option -vga qxl et installez les pilotes dans l'invité. Vous pouvez utiliser #SPICE pour améliorer les performances graphiques en utilisant QXL.

Sur les invités Linux, les modules noyau qxl et bochs_drm doivent être chargés afin d'obtenir des performances décentes.

La taille par défaut de la mémoire VGA pour les périphériques QXL est de 16M, ce qui est suffisant pour gérer des résolutions allant jusqu'à QHD (2560x1440). Pour permettre des résolutions plus élevées, increase vga_memmb.

vmware

Bien qu'il soit un peu bogué, il est plus performant que std et cirrus. Installez les pilotes VMware xf86-video-vmware et xf86-input-vmmouse pour les invités Arch Linux.

virtio

virtio-vga / virtio-gpu est un pilote graphique 3D paravirtuel basé sur virgl. Actuellement en cours de développement, il ne prend en charge que les hôtes Linux très récents (>= 4.4) avec mesa. (>=11.2) compilé avec l'option gallium-drivers=virgl.

Pour activer l'accélération 3D sur le système invité, sélectionnez ce vga avec -device virtio-vga-gl et activez le contexte opengl dans le périphérique d'affichage avec -display sdl,gl=on ou -display gtk,gl=on pour les sorties d'affichage sdl et gtk respectivement. Une configuration réussie peut être confirmée en regardant le journal du noyau dans l'invité :

# dmesg | grep drm 
[drm] pci : virtio-vga détecté
[drm] accélération 3d virgl activée

cirrus

L'adaptateur graphique cirrus était l'adaptateur par défaut avant 2.2. Il ne devrait pas être utilisé sur les systèmes modernes.

none

C'est comme un PC qui n'a pas de carte VGA du tout. Vous ne pourriez même pas y accéder avec l'option -vnc. En outre, ceci est différent de l'option -nographic qui permet à QEMU d'émuler une carte VGA, mais désactive l'affichage SDL.

SPICE

Le SPICE project vise à fournir une solution open source complète pour l'accès à distance aux machines virtuelles de manière transparente.

Activation du support SPICE sur l'hôte

Voici un exemple de démarrage avec SPICE comme protocole de bureau à distance, y compris la prise en charge du copier-coller depuis l'hôte :

$ qemu-system-x86_64 -vga qxl -device virtio-serial-pci -spice port=5930,disable-ticketing=on -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent

Les paramètres ont la signification suivante :

  1. -device virtio-serial-pci ajoute un périphérique virtio-serial
  2. -spice port=5930,disable-ticketing=on définit le port TCP 5930 pour l'écoute des canaux spice et permet au client de se connecter sans authentification
    Astuce: L'utilisation de Unix sockets au lieu des ports TCP n'implique pas l'utilisation de la pile réseau sur le système hôte. Elle n'implique pas que les paquets soient encapsulés et décapsulés pour utiliser le réseau et le protocole correspondant. Les sockets sont identifiés uniquement par les inodes du disque dur. Il est donc considéré comme meilleur pour les performances. Utilisez plutôt -spice unix=on,addr=/tmp/vm_spice.socket,disable-ticketing=on.
  3. -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 ouvre un port pour spice vdagent dans le périphérique virtio-serial,
  4. -chardev spicevmc,id=spicechannel0,name=vdagent ajoute une chardev spicevmc pour ce port. Il est important que l'option chardev= du dispositif virtserialport corresponde à l'option id= donnée à l'option chardev (spicechannel0 dans cet exemple). Il est également important que le nom du port soit com.redhat.spice.0, car c'est l'espace de nom que vdagent recherche dans l'invité. Et enfin, spécifiez name=vdagent pour que spice sache à quoi sert ce canal.

Se connecter à l'invité avec un client SPICE

Un client SPICE est nécessaire pour se connecter à l'invité. Dans Arch, les clients suivants sont disponibles :

virt-viewer — client SPICE recommandé par les développeurs du protocole, un sous-ensemble du projet virt-manager.

https://virt-manager.org/ || virt-viewer

spice-gtk — Client SPICE GTK, un sous-ensemble du projet SPICE. Intégré dans d'autres applications en tant que widget.

https://www.spice-space.org/ || spice-gtk

Pour les clients fonctionnant sur smartphone ou sur d'autres plateformes, reportez-vous à la section Autres clients de spice-space download.

Exécution manuelle d'un client SPICE

Une façon de se connecter à un invité écoutant sur le socket Unix /tmp/vm_spice.socket est d'exécuter manuellement le client SPICE en utilisant $ remote-viewer spice+unix:///tmp/vm_spice.socket ou $ spicy --uri="spice+unix:///tmp/vm_spice.socket", selon le client souhaité. Comme QEMU en mode SPICE agit de la même manière qu'un serveur de bureau à distance, il peut être plus pratique d'exécuter QEMU en mode daemon avec le paramètre -daemonize.

Astuce: Pour se connecter à l'invité par tuning SSH, le type de commande suivant peut être utilisé :
$ ssh -fL 5999:localhost:5930 my.domain.org sleep 10 ; spicy -h 127.0.0.1 -p 5999

Cet exemple connecte spicy au port local 5999 qui est transféré par SSH au serveur SPICE de l'invité situé à l'adresse my.domain.org, port 5930. Notez l'option -f qui demande à ssh d'exécuter la commande sleep 10 en arrière-plan. De cette façon, la session ssh s'exécute tant que le client est actif et se ferme automatiquement lorsque le client se termine.

Exécuter un client SPICE avec QEMU

QEMU peut automatiquement démarrer un client SPICE avec un socket approprié, si l'affichage est défini sur SPICE avec le paramètre -display spice-app. Cela utilisera le client SPICE par défaut du système comme visualisateur, déterminé par vos fichiers mimeapps.list.

Activation du support SPICE sur l'invité

Pour les invités Arch Linux, pour une meilleure prise en charge de plusieurs moniteurs ou du partage du presse-papiers, les paquets suivants doivent être installés :

  • spice-vdagent : Agent Spice client xorg qui permet le copier/coller entre le client et la session X et plus encore.
  • xf86-video-qxl : Pilote vidéo Xorg X11 qxl

Pour les invités sous d'autres systèmes d'exploitation, référez-vous à la section Invité dans téléchargement de spice-space.

Authentification par mot de passe avec SPICE

Si vous voulez activer l'authentification par mot de passe avec SPICE, vous devez supprimer disable-ticketing de l'argument -spice et ajouter à la place password=yourpassword. Par exemple :

$ qemu-system-x86_64 -vga qxl -spice port=5900,password=yourpassword -device virtio-serial-pci -device virtserialport,chardev=spicechannel0,name=com.redhat.spice.0 -chardev spicevmc,id=spicechannel0,name=vdagent

Votre client SPICE devrait maintenant demander le mot de passe pour pouvoir se connecter au serveur SPICE.

Communication chiffrée TLS avec SPICE

Vous pouvez également configurer le chiffrement TLS pour communiquer avec le serveur SPICE. Tout d'abord, vous devez avoir un répertoire qui contient les fichiers suivants (les noms doivent être exactement comme indiqués) :

  • ca-cert.pem : le certificat maître de l'AC.
  • server-cert.pem : le certificat du serveur signé avec ca-cert.pem.
  • server-key.pem : la clé privée du serveur.

Un exemple de génération de certificats auto-signés avec votre propre CA pour votre serveur est montré dans le Manuel de l'utilisateur de Spice.

Ensuite, vous pouvez exécuter QEMU avec SPICE comme expliqué ci-dessus mais en utilisant l'argument -spice suivant : -spice tls-port=5901,password=yourpassword,x509-dir=/path/to/pki_certs, où /path/to/pki_certs est le chemin du répertoire qui contient les trois fichiers nécessaires montrés précédemment.

Il est maintenant possible de se connecter au serveur en utilisant virt-viewer :

$ remote-viewer spice://hostname?tls-port=5901 --spice-ca-file=/path/to/ca-cert.pem --spice-host-subject="C=XX,L=city,O=organization,CN=hostname" --spice-secure-channels=all

N'oubliez pas que le paramètre --spice-host-subject doit être défini en fonction de votre sujet server-cert.pem. Vous devez également copier ca-cert.pem sur chaque client pour vérifier le certificat du serveur.

Astuce: Vous pouvez obtenir l'objet du certificat du serveur dans le format correct de --spice-host-subject (avec les entrées séparées par des virgules) en utilisant la commande suivante :
$ openssl x509 -noout -subject -in server-cert.pem | cut -d' ' -f2- | sed 's/\///' | sed 's/\/,/g'

La commande équivalente spice-gtk est :

$ spicy -h hostname -s 5901 --spice-ca-file=ca-cert.pem --spice-host-subject="C=XX,L=city,O=organization,CN=hostname" --spice-secure-channels=all

VNC

On peut ajouter l'option -vnc :X pour que QEMU redirige l'écran VGA vers la session VNC. Remplacez X par le numéro de l'écran (0 écoutera alors sur 5900, 1 sur 5901...).

$ qemu-system-x86_64 -vnc :0

Un exemple est également fourni dans la section #Démarrer des machines virtuelles QEMU au démarrage.

Attention: La configuration par défaut du serveur VNC n'utilise aucune forme d'authentification. Tout utilisateur peut se connecter à partir de n'importe quel hôte.

Authentification par mot de passe de base

Un mot de passe d'accès peut être configuré facilement en utilisant l'option password. Le mot de passe doit être indiqué dans le moniteur QEMU et la connexion n'est possible que lorsque le mot de passe est fourni.

$ qemu-system-x86_64 -vnc :0,password -monitor stdio

Dans le moniteur QEMU, le mot de passe est défini en utilisant la commande change vnc password et en indiquant ensuite le mot de passe.

La ligne de commande suivante lance directement vnc avec un mot de passe :

$ printf "change vnc password\n%s\n" MYPASSWORD | qemu-system-x86_64 -vnc :0,password -monitor stdio
Note: Le mot de passe est limité à 8 caractères et peut être deviné par une attaque par force brute. Une protection plus élaborée est fortement recommandée pour les réseaux publics.

Audio

Créer un backend audio

L'option -audiodev définit le pilote dubackend audio et ses options. La liste des pilotes audio disponibles et leurs paramètres optionnels est détaillée dans la page de manuel de qemu(1).

Au minimum, vous devez choisir un backend et définir un id, pour PulseAudio par exemple :

-audiodev pa,id=snd0

Utiliser le backend audio

Intel HD Audio

Pour l'émulation Intel HD Audio, ajoutez les périphériques contrôleur et codec. Pour lister les périphériques audio Intel HDA disponibles :

$ qemu-system-x86_64 -device help | grep hda

Ajoutez le contrôleur audio:

-device ich9-intel-hda

Ajoutez également le codec audio et mappez-le à un id de backend audio hôte:

-device hda-output,audiodev=snd0
Intel 82801AA AC97

Pour l'émulation AC97, il suffit d'ajouter le périphérique de la carte audio et de l'associer à un identifiant de backend audio hôte.

-périphérique AC97, audiodev=snd0
Note:
  • Si le backend audiodev n'est pas fourni, QEMU le recherche et l'ajoute automatiquement, cela ne fonctionne que pour un seul audiodev. Par exemple, -device intel-hda -device hda-duplex émulera intel-hda sur l'invité en utilisant le backend audiodev par défaut.
  • Les pilotes émulés de carte graphique vidéo pour la machine invitée peuvent également causer un problème de qualité sonore. Testez-les un par un pour qu'ils fonctionnent. Vous pouvez lister les options possibles avec qemu-system-x86_64 -h | grep vga.

Installation des pilotes virtio

QEMU offre aux invités la possibilité d'utiliser des périphériques bloc et réseau paravirtualisés à l'aide des pilotes virtio, qui offrent de meilleures performances et une plus faible surcharge.

  • Un périphérique de type bloc virtio nécessite l'option -drive pour passer une image disque, avec le paramètre if=virtio :
$ qemu-system-x86_64 -drive file=disk_image,if=virtio
  • Il en va presque de même pour le réseau :
$ qemu-system-x86_64 -nic user,model=virtio-net-pci'
Note: Ceci ne fonctionnera que si la machine invitée possède des pilotes pour les périphériques virtio. Linux en a, et les pilotes requis sont inclus dans Arch Linux, mais il n'y a aucune garantie que les périphériques virtio fonctionneront avec d'autres systèmes d'exploitation.

Préparer un invité Arch Linux

Pour utiliser les périphériques virtio après l'installation d'un invité Arch Linux, les modules suivants doivent être chargés dans l'invité : virtio, virtio_pci, virtio_blk, virtio_net, et virtio_ring. Pour les invités 32 bits, le module spécifique "virtio" n'est pas nécessaire.

Si vous voulez démarrer à partir d'un disque virtio, le ramdisk initial doit contenir les modules nécessaires. Par défaut, ceci est géré par le hook autodetect de mkinitcpio. Sinon, utilisez le tableau MODULES dans /etc/mkinitcpio.conf pour inclure les modules nécessaires et reconstruire le ramdisk initial.

/etc/mkinitcpio.conf
MODULES=(virtio virtio_blk virtio_pci virtio_net)

Les disques Virtio sont reconnus avec le préfixe v (par exemple, vda, vdb, etc.) ; par conséquent, des modifications doivent être apportées au moins dans /etc/fstab et /boot/grub/grub.cfg lors du démarrage à partir d'un disque virtio.

Astuce: Lorsque l'on référence les disques par UUID dans /etc/fstab et dans le chargeur d'amorçage, il n'y a rien à faire.

Vous trouverez de plus amples informations sur la paravirtualisation avec KVM ici.

Vous pouvez également installer qemu-guest-agent pour implémenter la prise en charge des commandes QMP qui amélioreront les capacités de gestion de l'hyperviseur. Après avoir installé le paquet, vous pouvez activer et démarrer le qemu-guest-agent.service.

Préparation d'un invité Windows

Pilotes Virtio pour Windows

Windows n'est pas livré avec les pilotes virtio. Les dernières versions stables des pilotes sont régulièrement construites par Fedora, les détails sur le téléchargement des pilotes sont donnés sur virtio-win on GitHub. Dans les sections suivantes, nous utiliserons principalement le fichier ISO stable fourni ici : virtio-win.iso. Vous pouvez également utiliser virtio-winAUR.

Pilotes de périphérique de bloc

Nouvelle installation de Windows

Les pilotes doivent être chargés pendant l'installation, la procédure est de charger l'image ISO avec les pilotes virtio dans un cdrom avec le disque primaire et le média d'installation ISO de Windows :

$ qemu-system-x86_64 ... \
-drive file=disk_image,index=0,media=disk,if=virtio \
-drive file=windows.iso,index=2,media=cdrom \
-drive file=virtio-win.iso,index=3,media=cdrom \
...

Pendant l'installation, à un moment donné, le programme d'installation de Windows demandera "Où voulez-vous installer Windows ?", il émettra un avertissement indiquant qu'aucun disque n'a été trouvé. Suivez les instructions de l'exemple ci-dessous (basé sur Windows Server 2012 R2 avec Update) .

  • Sélectionnez l'option Load Drivers.
  • Décochez la case pour Masquer les pilotes qui ne sont pas compatibles avec le matériel de cet ordinateur.
  • Cliquez sur le bouton Parcourir et ouvrez le CDROM pour l'iso virtio, généralement nommé "virtio-win-XX".
  • Naviguez maintenant jusqu'à E:\viostor\[your-os]\d64, sélectionnez-le et confirmez.

Vous devriez maintenant consulter la liste de vos disques virtio, prêts à être sélectionnés, formatés et installés.

Modifier une VM Windows existante pour utiliser virtio

Modifier une VM Windows existante pour démarrer à partir d'un disque virtio nécessite que le pilote virtio soit chargé par l'invité au moment du démarrage. Nous devrons donc apprendre à Windows à charger le pilote virtio au démarrage avant de pouvoir démarrer une image disque en mode virtio.

Pour cela, il faut d'abord créer une nouvelle image disque qui sera attachée en mode virtio et déclencher la recherche du pilote :

$ qemu-img create -f qcow2 dummy.qcow2 1G

Exécutez l'invité Windows original avec le disque de démarrage toujours en mode IDE, le faux disque en mode virtio et l'image ISO du pilote.

$ qemu-system-x86_64 -m 4G -drive file=disk_image,if=ide -drive file=dummy.qcow2,if=virtio -cdrom virtio-win.iso

Windows détectera le faux disque et cherchera un pilote approprié. S'il échoue, allez dans le Gestionnaire de périphériques, localisez le lecteur SCSI avec une icône en forme de point d'exclamation (il devrait être ouvert), cliquez sur Mettre à jour le pilote et sélectionnez le CD-ROM virtuel. Ne naviguez pas jusqu'au dossier du pilote dans le CD-ROM, sélectionnez simplement le lecteur de CD-ROM et Windows trouvera automatiquement le pilote approprié (testé pour Windows 7 SP1).

Demandez à Windows de démarrer en mode sans échec lors de son prochain démarrage. Vous pouvez le faire en utilisant l'outil msconfig.exe de Windows. En mode sans échec, tous les pilotes seront chargés au démarrage, y compris le nouveau pilote virtio. Une fois que Windows sait que le pilote virtio est nécessaire au démarrage, il le mémorisera pour les démarrages futurs.

Une fois que vous avez reçu l'instruction de démarrer en mode sans échec, vous pouvez éteindre la machine virtuelle et la relancer, maintenant avec le disque de démarrage attaché en mode virtio :

$ qemu-system-x86_64 -m 4G -drive file=disk_image,if=virtio

Vous devriez démarrer en mode sans échec avec le pilote virtio chargé, vous pouvez maintenant retourner à msconfig.exe pour désactiver le démarrage en mode sans échec et redémarrer Windows.

Note: Si vous rencontrez l'écran bleu de la mort en utilisant le paramètre if=virtio, cela signifie probablement que le pilote du disque virtio n'est pas installé ou n'est pas chargé au démarrage, redémarrez en mode sans échec et vérifiez la configuration de votre pilote.

Pilotes réseau

L'installation des pilotes réseau de virtio est un peu plus simple, il suffit d'ajouter l'argument -nic.

$ qemu-system-x86_64 -m 4G -drive file=windows_disk_image,if=virtio -nic user,model=virtio-net-pci -cdrom virtio-win.iso

Windows va détecter l'adaptateur réseau et essayer de trouver un pilote pour celui-ci. S'il échoue, allez dans le Gestionnaire de périphériques, localisez l'adaptateur réseau avec une icône en forme de point d'exclamation (il devrait être ouvert), cliquez sur Mettre à jour le pilote et sélectionnez le CD-ROM virtuel. N'oubliez pas de cocher la case qui dit de rechercher les répertoires de manière récursive.

Pilote de ballon

Si vous souhaitez suivre l'état de la mémoire de votre invité (par exemple via la commande virsh dommemstat) ou modifier la taille de la mémoire de l'invité en cours d'exécution (vous ne pourrez toujours pas modifier la taille de la mémoire, mais vous pourrez limiter l'utilisation de la mémoire en gonflant le pilote ballon), vous devrez installer le pilote ballon de l'invité.

Pour cela, vous devez aller dans le Gestionnaire de périphériques, localiser PCI standard RAM Controller dans System devices (ou un contrôleur PCI non reconnu dans Other devices) et choisir Update driver. Dans la fenêtre ouverte, vous devrez choisir Browse my computer... et sélectionner le CD-ROM (et n'oubliez pas de cocher la case Include subdirectories). Redémarrez après l'installation. Cela installera le pilote et vous pourrez gonfler le ballon (par exemple via la commande hmp balloon memory_size, qui fera en sorte que le ballon prenne autant de mémoire que possible afin de réduire la taille de la mémoire disponible de l'invité à memory_size). Cependant, vous ne serez toujours pas en mesure de suivre l'état de la mémoire de l'invité. Pour ce faire, vous devez installer correctement le service Balloon. Pour cela ouvrez la ligne de commande en tant qu'administrateur, allez sur le CD-ROM, dans le répertoire Balloon et plus profondément, en fonction de votre système et de votre architecture. Une fois dans le répertoire amd64 (x86), exécutez blnsrv.exe -i qui fera l'installation. Après cela, la commande virsh dommemstat devrait afficher toutes les valeurs prises en charge.

Préparer un invité FreeBSD

Installez le port emulators/virtio-kmod si vous utilisez FreeBSD 8.3 ou plus jusqu'à 10.0-CURRENT où ils sont inclus dans le noyau. Après l'installation, ajoutez ce qui suit à votre fichier /boot/loader.conf :

virtio_load="YES"
virtio_pci_load="YES" (en anglais)
virtio_blk_load="YES"
if_vtnet_load="YES"
virtio_balloon_load="YES"

Puis modifiez votre /etc/fstab en faisant ce qui suit :

# sed -ibak "s/ada/vtbd/g" /etc/fstab

Et vérifiez que /etc/fstab est cohérent. Si quelque chose ne va pas, démarrez simplement sur un CD de secours et copiez /etc/fstab.bak vers /etc/fstab.

Moniteur de QEMU

Lorsque QEMU est en cours d'exécution, une console de surveillance est fournie afin d'offrir plusieurs façons d'interagir avec la machine virtuelle en cours d'exécution. Le moniteur QEMU offre des capacités intéressantes telles que l'obtention d'informations sur la machine virtuelle en cours, le branchement à chaud de périphériques, la création d'instantanés de l'état actuel de la machine virtuelle, etc. Pour consulter la liste de toutes les commandes, exécutez help ou ? dans la console du moniteur QEMU ou consultez la section correspondante de la documentation officielle QEMU.

Accès à la console de surveillance

Vue graphique

Lorsque l'option graphique par défaut std est utilisée, on peut accéder au moniteur QEMU en appuyant sur Ctrl+Alt+2 ou en cliquant sur View > compatmonitor0 dans la fenêtre QEMU. Pour revenir à la vue graphique de la machine virtuelle, appuyez sur Ctrl+Alt+1 ou cliquez sur View > VGA.

Cependant, la méthode standard d'accès au moniteur n'est pas toujours pratique et ne fonctionne pas avec toutes les sorties graphiques prises en charge par QEMU.

Telnet

Pour activer telnet, exécutez QEMU avec le paramètre -monitor telnet:127.0.0.1:port,server,nowait. Lorsque la machine virtuelle est démarrée, vous pourrez accéder au moniteur via telnet :

$ telnet 127.0.0.1 : port
Note: Si 127.0.0.1 est spécifié comme l'IP à écouter, il ne sera possible de se connecter au moniteur qu'à partir du même hôte sur lequel QEMU fonctionne. Si la connexion à partir d'hôtes distants est souhaitée, il faut indiquer à QEMU d'écouter 0.0.0.0 comme suit : -monitor telnet:0.0.0.0:port,server,nowait. Gardez à l'esprit qu'il est recommandé d'avoir un pare-feu configuré dans ce cas ou de s'assurer que votre réseau local est totalement digne de confiance puisque cette connexion est totalement non authentifiée et non chiffré.

Socket UNIX

Lancez QEMU avec le paramètre -monitor unix:socketfile,server,nowait. Vous pouvez ensuite vous connecter avec soit socat, nmap ou openbsd-netcat.

Par exemple, si QEMU est lancé via :

$ qemu-system-x86_64 -monitor unix:/tmp/monitor.sock,server,nowait [...]'.

Il est possible de se connecter au moniteur avec :

$ socat - UNIX-CONNECT:/tmp/monitor.sock

Ou avec :

$ nc -U /tmp/monitor.sock

Alternativement avec nmap :

$ ncat -U /tmp/monitor.sock

TCP

Vous pouvez exposer le moniteur sur TCP avec l'argument -monitor tcp:127.0.0.1 : port,server,nowait. Ensuite, connectez-vous avec netcat, soit openbsd-netcat ou gnu-netcat en exécutant :

$ nc 127.0.0.1 port
Note: Pour pouvoir se connecter à la socket tcp à partir d'autres périphériques que l'hôte sur lequel QEMU est exécuté, vous devez écouter 0.0.0.0 comme expliqué dans le cas de telnet. Les mêmes avertissements de sécurité s'appliquent également dans ce cas.

E/S standard

Il est possible d'accéder automatiquement au moniteur à partir du même terminal que celui où QEMU est exécuté en le lançant avec l'argument -monitor stdio.

Envoyer les frappes du clavier à la machine virtuelle en utilisant la console du moniteur

Certaines combinaisons de touches peuvent être difficiles à exécuter sur les machines virtuelles car l'hôte les intercepte à la place dans certaines configurations (un exemple notable est la combinaison de touches Ctrl+Alt+F*, qui change le tty actif). Pour éviter ce problème, la combinaison de touches problématique peut être envoyée via la console du moniteur. Passez au moniteur et utilisez la commande sendkey pour transmettre les pressions de touche nécessaires à la machine virtuelle. Par exemple :

(qemu) sendkey ctrl-alt-f2

Création et gestion des snapshots via la console du moniteur

Note: Cette fonctionnalité fonctionnera uniquement lorsque l'image disque de la machine virtuelle est au format qcow2. Elle ne fonctionnera pas avec les images brutes.

Il est parfois souhaitable de sauvegarder l'état actuel d'une machine virtuelle et d'avoir la possibilité de revenir à l'état de la machine virtuelle à celui d'un snapshot précédemment sauvegardé à tout moment. La console de surveillance QEMU fournit à l'utilisateur les utilitaires nécessaires pour créer des snapshots, les gérer et rétablir l'état de la machine à un snapshot sauvegardé.

  • Utilisez savevm name pour créer un instantané avec l'étiquette name.
  • Utilisez loadvm name pour ramener la machine virtuelle à l'état du snapshot name.
  • Utilisez delvm name pour supprimer le snapshot marqué comme name.
  • Utilisez info snapshots pour consulter une liste des instantanés sauvegardés. Les snapshots sont identifiés à la fois par un numéro d'identification auto-incrémenté et une balise texte (définie par l'utilisateur lors de la création du snapshot).

Exécuter la machine virtuelle en mode immuable

Il est possible d'exécuter une machine virtuelle dans un état figé de sorte que tous les changements seront supprimés lorsque la machine virtuelle est mise hors tension, simplement en exécutant QEMU avec le paramètre -snapshot. Lorsque l'image disque est écrite par l'invité, les changements seront enregistrés dans un fichier temporaire dans /tmp et seront supprimés lorsque QEMU s'arrêtera.

Cependant, si une machine fonctionne en mode gelé, il est toujours possible de sauvegarder les changements dans l'image disque si on le souhaite par la suite en utilisant la console de surveillance et en exécutant la commande suivante :

(qemu) commit all

Si des snapshots sont créés lors d'une exécution en mode gelé, ils seront supprimés dès que QEMU sera quitté, à moins que les changements ne soient explicitement commités sur le disque, également.

Options de pause et d'alimentation via la console du moniteur

Certaines opérations d'une machine physique peuvent être émulées par QEMU en utilisant certaines commandes de la console de surveillance :

  • system_powerdown enverra une demande d'arrêt ACPI à la machine virtuelle. Cet effet est similaire au bouton d'alimentation dans une machine physique.
  • system_reset réinitialisera la machine virtuelle de manière similaire à un bouton de réinitialisation dans une machine physique. Cette opération peut entraîner une perte de données et une corruption du système de fichiers puisque la machine virtuelle n'est pas redémarrée proprement.
  • stop mettra en pause la machine virtuelle.
  • cont reprendra une machine virtuelle précédemment mise en pause.

Prendre des captures d'écran de la machine virtuelle

Les captures d'écran de l'affichage graphique de la machine virtuelle peuvent être obtenues au format PPM en exécutant la commande suivante dans la console du moniteur :

(qemu) screendump file.ppm

Protocole machine QEMU

Le protocole machine QEMU (QMP) est un protocole basé sur JSON qui permet aux applications de contrôler une instance QEMU. Comme le #Moniteur de QEMU, il offre des moyens d'interagir avec une machine en fonctionnement et le protocole JSON permet de le faire de manière programmatique. La description de toutes les commandes QMP se trouve dans qmp-commands.

Démarrer QMP

La manière habituelle de contrôler l'invité en utilisant le protocole QMP, est d'ouvrir un socket TCP lors du lancement de la machine en utilisant l'option -qmp. Ici, on utilise par exemple le port TCP 4444 :

$ qemu-system-x86_64 [...] -qmp tcp:localhost:4444,server,nowait

Ensuite, une façon de communiquer avec l'agent QMP est d'utiliser netcat :

nc localhost 4444
{"QMP" : {"version" : {"qemu" : {"micro" : 0, "minor" : 1, "major" : 3}, "package" : ""}, "capabilities" : []} } 

À ce stade, la seule commande qui peut être reconnue est qmp_capabilities, de sorte que QMP passe en mode commande. Type :

{"execute" : "qmp_capabilities"}

Maintenant, QMP est prêt à recevoir des commandes, pour récupérer la liste des commandes reconnues, utilisez :

{"execute" : "query-commands"}

Fusion en direct de l'image enfant dans l'image parent

Il est possible de fusionner un instantané en cours dans son parent en émettant une commande block-commit. Dans sa forme la plus simple, la ligne suivante commet l'enfant dans son parent :

{"execute" : "block-commit", "arguments" : {"device" : "devicename"}}

À la réception de cette commande, le gestionnaire recherche l'image de base et la convertit du mode lecture seule au mode lecture-écriture, puis exécute le travail de validation.

Une fois l'opération de block-commit terminée, l'événement BLOCK_JOB_READY sera émis, signalant que la synchronisation est terminée. Le travail peut alors être terminé en douceur en émettant la commande block-job-complete :

{"execute" : "block-job-complete", "arguments" : {"device" : "devicename"}}

Jusqu'à ce qu'une telle commande soit émise, l'opération commit reste active. Une fois l'opération terminée avec succès, l'image de base reste en mode lecture-écriture et devient la nouvelle couche active. En revanche, l'image enfant devient invalide et il incombe à l'utilisateur de la nettoyer.

Astuce: La liste des périphériques et leurs noms peuvent être récupérés en exécutant la commande query-block et en analysant les résultats. Le nom du périphérique se trouve dans le champ device, par exemple ide0-hd0 pour le disque dur dans cet exemple :
{"execute" : "query-block"}
{"return" : [{"io-status" : "ok", "device" : "ide0-hd0", "locked" : false, "removable" : false, "inserted" : {"iops_rd" : 0, "detect_zeroes" : "off", "image" : {"backing-image" : {"virtual-size" : 27074281472, "filename" : "parent.qcow2", ... } 

Création en direct d'un nouvel instantané

Pour créer un nouvel instantané à partir d'une image en cours d'exécution, exécutez la commande :

{"execute" : "blockdev-snapshot-sync", "arguments" : {"device" : "devicename", "snapshot-file" : "new_snapshot_name.qcow2"}}

Cela crée un fichier de superposition nommé new_snapshot_name.qcow2 qui devient alors la nouvelle couche active.

Trucs et astuces

Améliorer les performances de la machine virtuelle

Il existe un certain nombre de techniques que vous pouvez utiliser pour améliorer les performances de la machine virtuelle. Par exemple :

  • Appliquez #Activation de KVM pour une virtualisation complète.
  • Utilisez l'option -cpu host pour que QEMU émule le CPU exact de l'hôte plutôt qu'un CPU plus générique.
  • Surtout pour les invités Windows, activez Hyper-V enlightenments : -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time.
  • Si la machine hôte a plusieurs cœurs, assignez à l'invité plus de cœurs en utilisant l'option -smp.
  • Assurez-vous que vous avez attribué suffisamment de mémoire à la machine virtuelle. Par défaut, QEMU n'attribue que 128 MiB de mémoire à chaque machine virtuelle. Utilisez l'option -m pour attribuer plus de mémoire. Par exemple, -m 1024 exécute une machine virtuelle avec 1024 MiB de mémoire.
  • Si les pilotes du système d'exploitation invité le prennent en charge, utilisez virtio pour les périphériques réseau et/ou de bloc, consultez #Installation des pilotes virtio.
  • Utilisez les périphériques TAP au lieu de la mise en réseau en mode utilisateur, consultez #Mise en réseau avec tap pour QEMU.
  • Si le système d'exploitation invité écrit beaucoup sur son disque, vous pouvez bénéficier de certaines options de montage sur le système de fichiers de l'hôte. Par exemple, vous pouvez monter un système de fichiers ext4 avec l'option barrier=0. Vous devez lire la documentation de toutes les options que vous modifiez, car parfois, les options d'amélioration des performances des systèmes de fichiers se font au détriment de l'intégrité des données.
  • Si vous avez une image disque brute, vous pouvez vouloir désactiver le cache :
    $ qemu-system-x86_64 -drive file=disk_image,if=virtio,cache=none
  • Utiliser l'AIO native de Linux :
    $ qemu-system-x86_64 -drive file=disk_image,if=virtio,aio=native,cache.direct=on'
  • Si vous exécutez simultanément plusieurs machines virtuelles qui ont toutes le même système d'exploitation installé, vous pouvez économiser de la mémoire en activant kernel same-page merging. Consultez #Activation de KSM.
  • Dans certains cas, la mémoire peut être récupérée des machines virtuelles en cours d'exécution en exécutant un pilote de ballon de mémoire dans le système d'exploitation invité et en lançant QEMU à l'aide de -device virtio-balloon.
  • Il est possible d'utiliser une couche d'émulation pour un contrôleur ICH-9 AHCI (bien que cela puisse être instable). L'émulation AHCI prend en charge NCQ, ainsi plusieurs requêtes de lecture ou d'écriture peuvent être en cours en même temps :
    $ qemu-system-x86_64 -drive id=disk,file=disk_image,if=none -device ich9-ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0

Consultez https://www.linux-kvm.org/page/Tuning_KVM pour plus d'informations.

Démarrer des machines virtuelles QEMU au démarrage

Avec libvirt

Si une machine virtuelle est configurée avec libvirt, elle peut être configurée avec virsh autostart ou via l'interface graphique virt-manager pour démarrer au démarrage de l'hôte en allant dans les options de démarrage de la machine virtuelle et en sélectionnant "Start virtual machine on host boot up".

Avec le service systemd

Pour exécuter les VM QEMU au démarrage, vous pouvez utiliser l'unité et la configuration systemd suivantes.

/etc/systemd/system/qemu@.service
[Unit]
Description=QEMU virtual machine

[Service]
Environment="haltcmd=kill -INT $MAINPID"
EnvironmentFile=/etc/conf.d/qemu.d/%i
ExecStart=/usr/bin/qemu-system-x86_64 -name %i -enable-kvm -m 512 -nographic $args
ExecStop=/usr/bin/bash -c ${haltcmd}
ExecStop=/usr/bin/bash -c 'while nc localhost 7100; do sleep 1; done'

[Install]
WantedBy=multi-user.target
Note: Ce service attendra que le port console soit libéré, ce qui signifie que la VM a été arrêtée, pour se terminer gracieusement.

Créez ensuite des fichiers de configuration par VM, nommés /etc/conf.d/qemu.d/vm_name, avec les variables args et haltcmd définies. Exemples de configurations :

/etc/conf.d/qemu.d/one
args="-hda /dev/vg0/vm1 -serial telnet:localhost:7000,server,nowait,nodelay \
 -monitor telnet:localhost:7100,server,nowait,nodelay -vnc :0"

haltcmd="echo 'system_powerdown' | nc localhost 7100" # ou netcat/ncat
/etc/conf.d/qemu.d/two
args="-hda /srv/kvm/vm2 -serial telnet:localhost:7001,server,nowait,nodelay -vnc :1"

haltcmd="ssh powermanager@vm2 sudo poweroff"

La description des variables est la suivante :

  • args - Arguments de ligne de commande QEMU à utiliser.
  • haltcmd - Commande permettant d'éteindre une VM en toute sécurité. Dans le premier exemple, le moniteur QEMU est exposé via telnet en utilisant -monitor telnet :.. et les VMs sont mises hors tension via ACPI en envoyant system_powerdown au moniteur avec la commande nc. Dans l'autre exemple, SSH est utilisé.

Pour définir quelles machines virtuelles démarreront au démarrage, activez l'unité systemd qemu@vm_name.service.

Intégration de la souris

Pour éviter que la souris soit saisie lors d'un clic sur la fenêtre du système d'exploitation invité, ajoutez les options -usb -device usb-tablet. Cela signifie que QEMU est capable de signaler la position de la souris sans avoir à la saisir. Cela remplace également l'émulation de la souris PS/2 lorsqu'elle est activée. Par exemple :

$ qemu-system-x86_64 -hda disk_image -m 512 -usb -device usb-tablet

Si cela ne fonctionne pas, essayez d'utiliser le paramètre -vga qxl, consultez également les instructions #Le curseur de la souris est instable ou erratique.

Pass-through host USB device

Il est possible d'accéder au périphérique physique connecté à un port USB de l'hôte depuis l'invité. La première étape consiste à identifier où le périphérique est connecté, ce qui peut être trouvé en exécutant la commande lsusb. Par exemple :

$ lsusb
...
Bus 003 Device 007 : ID 0781:5406 SanDisk Corp. Cruzer Micro U3

Les sorties en gras ci-dessus seront utiles pour identifier respectivement le host_bus et le host_addr ou le vendor_id et le product_id.

Dans qemu, l'idée est d'émuler un contrôleur EHCI (USB 2) ou XHCI (USB 1.1 USB 2 USB 3) avec l'option -device usb-ehci,id=ehci ou -device qemu-xhci,id=xhci respectivement, puis d'y attacher le périphérique physique avec l'option -device usb-host,... Nous considérerons que controller_id est soit ehci soit xhci pour le reste de cette section.

Ensuite, il y a deux façons de se connecter à l'USB de l'hôte avec qemu :

  1. Identifiez le périphérique et se connecter à lui sur n'importe quel bus et adresse auquel il est attaché sur l'hôte, la syntaxe générique est :
    -device usb-host,bus=controller_id.0,vendorid=0xvendor_id,productid=0xproduct_id
    Appliquée au périphérique utilisé dans l'exemple ci-dessus, elle devient:
    -device usb-ehci,id=ehci -device usb-host,bus=ehci.0, vendorid=0x'0781,productid=0x5406
    On peut également ajouter le paramètre ...,port=port_number à l'option précédente pour spécifier dans quel port physique du contrôleur virtuel le périphérique doit être attaché, utile dans le cas où l'on veut ajouter plusieurs périphériques usb à la VM. Une autre option est d'utiliser la nouvelle propriété hostdevice de usb-host qui est disponible depuis QEMU 5.1.0, la syntaxe est :
    -device qemu-xhci,id=xhci -device usb-host,hostdevice=/dev/bus/usb/003/007
  2. Attachez ce qui est connecté à un bus USB et une adresse donnés, la syntaxe est:
    -device usb-host,bus=controller_id.0,hostbus=host_bus,host_addr=host_addr
    Appliqué au bus et à l'adresse dans l'exemple ci-dessus, cela devient:
    -device usb-ehci,id=ehci -device usb-host,bus=ehci.0, hostbus=3,hostaddr=7

Consultez émulation QEMU/USB pour plus d'informations.

Note: Si vous rencontrez des erreurs de permission lors de l'exécution de QEMU, consultez udev (Français)#À propos des règles udev pour savoir comment définir les permissions du périphérique.

Redirection USB avec SPICE

En utilisant #SPICE, il est possible de rediriger les périphériques USB du client vers la machine virtuelle sans avoir besoin de les spécifier dans la commande QEMU. Il est possible de configurer le nombre de slots USB disponibles pour les périphériques redirigés (le nombre de slots déterminera le nombre maximum de périphériques pouvant être redirigés simultanément). Les principaux avantages de l'utilisation de SPICE pour la redirection par rapport à la méthode -usbdevice mentionnée précédemment est la possibilité de remplacer à chaud les périphériques USB après le démarrage de la machine virtuelle, sans avoir besoin de l'arrêter pour supprimer les périphériques USB de la redirection ou en ajouter de nouveaux. Cette méthode de redirection USB nous permet également de rediriger les périphériques USB sur le réseau, du client au serveur. En résumé, c'est la méthode la plus flexible pour utiliser les périphériques USB dans une machine virtuelle QEMU.

Nous devons ajouter un contrôleur EHCI/UHCI par slot de redirection USB disponible souhaité ainsi qu'un canal de redirection SPICE par slot. Par exemple, en ajoutant les arguments suivants à la commande QEMU que vous utilisez pour démarrer la machine virtuelle en mode SPICE, la machine virtuelle démarrera avec trois slots USB disponibles pour la redirection :

-device ich9-usb-ehci1,id=usb \
-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on \\
-dispositif ich9-usb-uhci2,masterbus=usb.0,firstport=2 \
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4 \
-chardev spicevmc,name=usbredir,id=usbredirchardev1 -device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \
-chardev spicevmc,name=usbredir,id=usbredirchardev2 -device usb-redir,chardev=usbredirchardev2,id=usbredirdev2 \
-chardev spicevmc,name=usbredir,id=usbredirchardev3 -device usb-redir,chardev=usbredirchardev3,id=usbredirdev3

Consultez SPICE/usbredir pour plus d'informations.

Les deux spicy de spice-gtk (Entrée > Sélectionner les périphériques USB pour la redirection) et remote-viewer de virt-viewer (File > USB device selection) prennent en charge cette fonctionnalité. Veuillez vous assurer que vous avez installé les outils SPICE Guest Tools nécessaires sur la machine virtuelle pour que cette fonctionnalité fonctionne comme prévu (consultez la section #SPICE pour plus d'informations).

Attention: Ne perdez pas de vue que lorsqu'un périphérique USB est redirigé depuis le client, il ne sera pas utilisable depuis le système d'exploitation client lui-même jusqu'à ce que la redirection soit arrêtée. Il est particulièrement important de ne jamais rediriger les périphériques d'entrée (à savoir la souris et le clavier), car il sera alors difficile d'accéder aux menus du client SPICE pour rétablir la situation, car le client ne répondra pas aux périphériques d'entrée après avoir été redirigé vers la machine virtuelle.

Redirection USB automatique avec udev

Normalement, les périphériques transférés doivent être disponibles au moment du démarrage de la VM pour être transférés. Si ce périphérique est déconnecté, il ne sera plus transféré.

Vous pouvez utiliser des règles udev pour attacher automatiquement un périphérique lorsqu'il est en ligne. Créez une entrée hostdev quelque part sur le disque. chown à root pour empêcher les autres utilisateurs de la modifier.

/usr/local/hostdev-mydevice.xml
<hostdev mode='subsystem' type='usb'>
  <source>
    <vendor id='0x03f0'/>
    <product id='0x4217'/>
  </source>
</hostdev>

Créez ensuite une règle udev qui attachera/détachera le périphérique :

/usr/lib/udev/rules.d/90-libvirt-mydevice
ACTION=="add", \
    SUBSYSTEM=="usb", \
    ENV{ID_VENDOR_ID}=="03f0", \
    ENV{ID_MODEL_ID}=="4217", \
    RUN+="/usr/bin/virsh attach-device GUESTNAME /usr/local/hostdev-mydevice.xml"
ACTION=="remove", \
    SUBSYSTEM=="usb", \
    ENV{ID_VENDOR_ID}=="03f0", \
    ENV{ID_MODEL_ID}=="4217", \
    RUN+="/usr/bin/virsh detach-device GUESTNAME /usr/local/hostdev-mydevice.xml"

Source et lecture complémentaire.

Activation de KSM

KSM (Kernel Samepage Merging) est une fonctionnalité du noyau Linux qui permet à une application de s'enregistrer auprès du noyau pour que ses pages soient fusionnées avec d'autres processus qui s'enregistrent également pour que leurs pages soient fusionnées. Le mécanisme KSM permet aux machines virtuelles invitées de partager des pages entre elles. Dans un environnement où de nombreux systèmes d'exploitation invités sont similaires, cela peut permettre de réaliser d'importantes économies de mémoire.

Note: Bien que KSM puisse réduire l'utilisation de la mémoire, il peut augmenter l'utilisation du CPU. Notez également que certains problèmes de sécurité peuvent survenir, consultez Wikipedia:Kernel same-page merging.

Pour activer KSM :

# echo 1 > /sys/kernel/mm/ksm/run

Pour le rendre permanent, utilisez les fichiers temporaires de systemd :

/etc/tmpfiles.d/ksm.conf
w /sys/kernel/mm/ksm/run - - - - 1

Si KSM est en cours d'exécution et que des pages doivent être fusionnées (c'est-à-dire qu'au moins deux VM similaires sont en cours d'exécution), alors /sys/kernel/mm/ksm/pages_shared doit être différent de zéro. Consultez https://docs.kernel.org/admin-guide/mm/ksm.html pour plus d'informations.

Astuce: Une façon simple de consulter les performances de KSM est d'afficher le contenu de tous les fichiers du répertoire :
$ grep -r . /sys/kernel/mm/ksm/

Prise en charge de plusieurs moniteurs

Le pilote Linux QXL prend en charge quatre têtes (écrans virtuels) par défaut. Ceci peut être modifié par le paramètre noyau qxl.heads=N.

La taille de la mémoire VGA par défaut pour les périphériques QXL est de 16M (la taille de la VRAM est de 64M). Ce n'est pas suffisant si vous souhaitez activer deux moniteurs 1920x1200 car cela nécessite 2 × 1920 × 4 (profondeur de couleur) × 1200 = 17,6 Mio de mémoire VGA. Ceci peut être modifié en remplaçant -vga qxl par -vga none -device qxl-vga,vgamem_mb=32. Si vous augmentez vgamem_mb au-delà de 64M, vous devez également augmenter l'option vram_size_mb.

Résolution d'affichage personnalisée

Une résolution d'affichage personnalisée peut être définie avec -device VGA,edid=on,xres=1280,yres=720. (consultez EDID et display resolution).

Copier et coller

Une façon de partager le presse-papiers entre l'hôte et l'invité est d'activer le protocole de bureau à distance SPICE et d'accéder au client avec un client SPICE. Il faut suivre les étapes décrites dans #SPICE. Un invité exécuté de cette façon prendra en charge le copier-coller avec l'hôte.

Notes spécifiques à Windows

QEMU peut exécuter toute version de Windows, de Windows 95 à Windows 10.

Il est possible d'exécuter Windows PE dans QEMU.

Démarrage rapide

Note: Un compte administrateur est nécessaire pour modifier les paramètres d'alimentation

Pour les invités Windows 8 (ou ultérieur), il est préférable de désactiver l'option "Activer le démarrage rapide (recommandé)" dans les Options d'alimentation du Panneau de configuration, comme expliqué dans la [page du forum https://www.tenforums.com/tutorials/4189-turn-off-fast-startup-windows-10-a.html] suivante, car elle provoque le blocage de l'invité lors de chaque démarrage.

Le démarrage rapide peut également devoir être désactivé pour que les modifications apportées à l'option -smp soient correctement appliquées.

Protocole de bureau à distance

Si vous utilisez un invité MS Windows, vous voudrez peut-être utiliser RDP pour vous connecter à votre VM invitée. Si vous utilisez un VLAN ou si vous n'êtes pas dans le même réseau que l'invité, utilisez :

$ qemu-system-x86_64 -nographic -nic user,hostfwd=tcp::5555-:3389

Ensuite, connectez-vous avec rdesktop ou freerdp à l'invité. Par exemple :

$ xfreerdp -g 2048x1152 localhost:5555 -z -x lan

Cloner un système Linux installé sur un équipement physique

Le système Linux installé sur un équipement physique peut être cloné pour fonctionner sur une vm QEMU. Consultez Cloner le système Linux à partir du matériel pour la machine virtuelle QEMU.

Chrooter dans l'environnement arm/arm64 à partir de x86_64

Parfois, il est plus facile de travailler directement sur une image disque plutôt que sur le dispositif réel basé sur ARM. Ceci peut être réalisé en montant une carte SD/stockage contenant la partition root et en s'y connectant.

Un autre cas d'utilisation pour un chroot ARM est la construction de paquets ARM sur une machine x86_64. Ici, l'environnement chroot peut être créé à partir d'une image tarball de Arch Linux ARM - consultez [3] pour une description détaillée de cette approche.

Dans tous les cas, à partir du chroot, il devrait être possible d'exécuter pacman et d'installer plus de paquets, de compiler de grandes bibliothèques, etc. Comme les exécutables sont pour l'architecture ARM, la traduction en x86 doit être effectuée par QEMU.

Installez qemu-user-static sur la machine/hôte x86_64 et qemu-user-static-binfmt se chargera d'enregistrer les binaires qemu au service binfmt.

Redémarrez systemd-binfmt.service

qemu-user-static est nécessaire pour permettre l'exécution de programmes compilés provenant d'autres architectures. C'est similaire à ce qui est fourni par qemu-emulators-full, mais la variante "static" est requise pour chroot. Exemples :

qemu-arm-static path_to_sdcard/usr/bin/ls
qemu-aarch64-static chemin_vers_sdcard/usr/bin/ls

Ces deux lignes exécutent la commande ls compilée pour ARM 32 bits et ARM 64 bits respectivement. Notez que cela ne fonctionnera pas sans chrooting, car il cherchera des bibliothèques non présentes dans le système hôte.

qemu-user-static permet de préfixer automatiquement l'exécutable ARM avec qemu-arm-static ou qemu-aarch64-static.

Assurez-vous que le support de l'exécutable ARM est actif :

$ ls /proc/sys/fs/binfmt_misc
].
qemu-aarch64 qemu-arm qemu-cris qemu-microblaze qemu-mipsel qemu-ppc64 qemu-riscv64 qemu-sh4 qemu-sparc qemu-sparc64 status
qemu-alpha qemu-armeb qemu-m68k qemu-mips qemu-ppc qemu-ppc64abi32 qemu-s390x qemu-sh4eb qemu-sparc32plus register

Chaque exécutable doit être listé.

S'il n'est pas actif, redémarrez systemd-binfmt.service.

Montez la carte SD sur /mnt/sdcard. (le nom du périphérique peut être différent).

# mkdir -p /mnt/sdcard
# mount /dev/mmcblk0p2 /mnt/sdcard

Montez la partition de démarrage si nécessaire (encore une fois, utilisez le nom de périphérique approprié) :

# mount /dev/mmcblk0p1 /mnt/sdcard/boot

Enfin, chroot dans la racine de la carte SD comme décrit dans Chroot (Français)#Avec chroot :

# chroot /mnt/sdcard /bin/bash

Alternativement, vous pouvez utiliser arch-chroot à partir de arch-install-scripts, car il fournira un moyen plus facile d'obtenir un support réseau :

# arch-chroot /mnt/sdcard /bin/bash

Vous pouvez également utiliser systemd-nspawn pour chrooter dans l'environnement ARM :

# systemd-nspawn -D /mnt/sdcard -M myARMMachine --bind-ro=/etc/resolv.conf

--bind-ro=/etc/resolv.conf est optionnel et donne un DNS réseau fonctionnel dans le chroot.

Ne pas saisir l'entrée de la souris

Le mode tablette a pour effet secondaire de ne pas saisir l'entrée de la souris dans la fenêtre QEMU :

-usb -device usb-tablet

Cela fonctionne avec plusieurs backends -vga dont l'un est virtio.

Dépannage

Le curseur de la souris est instable ou erratique

Si le curseur saute à l'écran de manière incontrôlée, entrer ceci dans le terminal avant de démarrer QEMU peut aider :

$ export SDL_VIDEO_X11_DGAMOUSE=0

Si cela aide, vous pouvez ajouter ceci à votre fichier ~/.bashrc.

Pas de curseur visible

Ajoutez -display default,show-cursor=on aux options de QEMU pour consulter un curseur de souris.

Si cela ne fonctionne toujours pas, vérifiez que vous avez configuré votre périphérique d'affichage de manière appropriée, par exemple : -vga qxl.

Une autre option à essayer est -usb -device usb-tablet comme mentionné dans #Intégration de la souris. Cela remplace l'émulation de la souris PS/2 par défaut et synchronise l'emplacement du pointeur entre l'hôte et l'invité comme un bonus supplémentaire.

Deux curseurs de souris différents sont visibles

Appliquez l'astuce #Intégration de la souris.

Problèmes de clavier lors de l'utilisation de VNC

Lors de l'utilisation de VNC, vous pouvez rencontrer des problèmes de clavier décrits (dans les détails sanglants) ici. La solution est de ne pas utiliser l'option -k sur QEMU, et d'utiliser gvncviewer de gtk-vnc. Consultez également le message this posté sur la liste de diffusion de libvirt.

Le clavier semble cassé ou les touches fléchées ne fonctionnent pas

Si vous trouvez que certaines de vos touches ne fonctionnent pas ou "appuient" sur la mauvaise touche (en particulier, les touches fléchées), vous devez probablement spécifier votre disposition de clavier en option. Les dispositions de clavier peuvent être trouvées dans /usr/share/qemu/keymaps/.

$ qemu-system-x86_64 -k keymap disk_image

Impossible de lire le fichier keymap

qemu-system-x86_64 : -display vnc=0.0.0.0:0 : could not read keymap file : 'en'.

est causée par un keymap invalide passé à l'argument -k. Par exemple, en est invalide, mais en-us est valide - consultez /usr/share/qemu/keymaps/.

L'affichage invité s'étire lors du redimensionnement de la fenêtre

Pour restaurer la taille de fenêtre par défaut, appuyez sur Ctrl+Alt+u.

ioctl(KVM_CREATE_VM) failed : 16 Device or resource busy

Si un message d'erreur comme celui-ci est imprimé au démarrage de QEMU avec l'option -enable-kvm :

ioctl(KVM_CREATE_VM) failed : 16 Périphérique ou ressource occupée
échec de l'initialisation de KVM : Périphérique ou ressource occupée

cela signifie qu'un autre hyperviseur est en cours d'exécution. Il n'est pas recommandé ou possible d'exécuter plusieurs hyperviseurs en parallèle.

message d'erreur libgfapi

Le message d'erreur affiché au démarrage :

Failed to open module : libgfapi.so.0 : cannot open shared object file : No such file or directory

Installez glusterfs ou ignorez le message d'erreur car GlusterFS est une dépendance facultative.

Panique du noyau sur les environnements LIVE

Si vous démarrez un environnement vivant (ou mieux : si vous démarrez un système), vous pouvez rencontrer ceci :

[ end Panique du noyau - pas de synchronisation : VFS : Impossible de monter le fs racine sur un bloc inconnu(0,0)

ou tout autre processus entravant le démarrage (par exemple, impossible de décompresser initramfs, impossible de démarrer le service foo). Essayez de démarrer la VM avec le paramètre -m VALUE et une quantité appropriée de RAM, si la RAM est trop faible, vous rencontrerez probablement les mêmes problèmes que ci-dessus/sans le paramètre de mémoire.

L'invité Windows 7 souffre d'un son de mauvaise qualité

L'utilisation du pilote audio hda pour l'invité Windows 7 peut entraîner un son de mauvaise qualité. Changer le pilote audio pour ac97 en passant les arguments -soundhw ac97 à QEMU et installer le pilote AC97 de Realtek AC'97 Audio Codecs dans l'invité peut résoudre le problème. Consultez Red Hat Bugzilla - Bug 1176761 pour plus d'informations.

Impossible d'accéder au module du noyau KVM : Permission refusée

Si vous rencontrez l'erreur suivante :

libvirtError : internal error : process exited while connecting to monitor : Could not access KVM kernel module : Permission refusée failed to initialize KVM : Permission refusée

Systemd 234 attribue un ID dynamique pour le groupe kvm (consultez FS#54943). Pour éviter cette erreur, vous devez éditer le fichier /etc/libvirt/qemu.conf et changer la ligne avec group = "78" en group = "kvm".

"System Thread Exception Not Handled" lors du démarrage d'une VM Windows

Les invités Windows 8 ou Windows 10 peuvent soulever une exception de compatibilité générique au démarrage, à savoir "System Thread Exception Not Handled", qui tend à être causée par des pilotes hérités agissant étrangement sur des machines réelles. Sur les machines KVM, ce problème peut généralement être résolu en définissant le modèle de CPU sur core2duo.

Certains jeux/applications Windows se plantent/provoquent un écran bleu

Il arrive que des applications exécutées dans la VM se plantent de manière inattendue, alors qu'elles fonctionneraient normalement sur une machine physique. Si, lors de l'exécution de dmesg -wH en tant que root, vous rencontrez une erreur mentionnant MSR, la raison de ces plantages est que KVM injecte une General protection fault (GPF) lorsque l'invité tente d'accéder à des Model-specific registers non pris en charge. (MSRs) - cela entraîne souvent le plantage des applications/OS invités. Un certain nombre de ces problèmes peuvent être résolus en passant l'option ignore_msrs=1 au module KVM, qui ignorera les MSRs non implémentés.

/etc/modprobe.d/kvm.conf
...
options kvm ignore_msrs=1
...

Cas où l'ajout de cette option peut aider :

  • GeForce Experience se plaignant de la présence d'un CPU non pris en charge.
  • StarCraft 2 et L.A. Noire affichent un écran bleu fiable sous Windows 10 avec KMODE_EXCEPTION_NOT_HANDLED. Les informations de l'écran bleu n'identifient pas de fichier pilote dans ces cas.
Attention: Bien que cela soit normalement sans danger et que certaines applications puissent ne pas fonctionner sans cela, ignorer silencieusement des accès MSR inconnus pourrait potentiellement casser d'autres logiciels dans la VM ou d'autres VM.

Les applications dans la VM subissent des retards importants ou prennent beaucoup de temps à démarrer

Cela peut être dû à une entropie disponible insuffisante dans la VM. Envisagez d'autoriser l'invité à accéder au pool d'entropie des hôtes en ajoutant un VirtIO RNG device à la VM, ou en installant un daemon de génération d'entropie tel que Haveged.

Anecdotiquement, OpenSSH prend un certain temps avant de commencer à accepter des connexions lorsque l'entropie est insuffisante, sans que les journaux ne révèlent pourquoi.

Latence élevée des interruptions et microstuttering

Ce problème se manifeste par de petites pauses (bégaiements) et est particulièrement visible dans les applications à forte intensité graphique, comme les jeux.

La vidéo QXL cause une basse résolution

QEMU 4.1.0 a introduit une régression où la vidéo QXL peut retomber à de basses résolutions, lorsqu'elle est affichée via spice. [4] Par exemple, lorsque KMS démarre, la résolution du texte peut devenir aussi basse que 4x10 caractères. Lorsque vous essayez d'augmenter la résolution de l'interface graphique, elle peut passer à la résolution la plus faible prise en charge.

Comme solution de contournement, créez votre périphérique sous cette forme :

-device qxl-vga,max_outputs=1...

Hang pendant VM initramfs

Linux 5.2.11 a introduit une régression KVM où, dans certaines circonstances, une VM peut se bloquer de manière permanente pendant la phase de démarrage précoce, lorsque l'initramfs est chargé ou exécuté. [5] Linux 5.3 a corrigé la régression. L'hôte montre que qemu utilise 100% du CPU * nombre de CPU virtuels. Le cas rapporté est celui d'un hôte utilisant l'hyperthreading, et d'une VM à qui l'on donne plus que les nproc}/2 CPU virtuels de l'hôte. On ignore quelles circonstances exactes déclenchent la suppression d'une région de mémoire par l'un des threads pour provoquer ce problème. Les solutions de contournement sont les suivantes :

  • Mettre à jour vers Linux 5.3.
  • Mise à jour vers Linux 5.2.10.
  • Jusqu'à ce que le problème soit résolu, essayez de ne pas donner à la VM plus que les nproc/2 CPU virtuels de l'hôte.
  • Compilation personnalisée de Linux, rétablissement du commit 2ad350fb4c (notez que cela réintroduit une régression déclenchée lors de la suppression d'un memslot).

La VM ne démarre pas lorsqu'on utilise un OVMF activé par Secure Boot

/usr/share/edk2-ovmf/x64/OVMF_CODE.secboot.fd de edk2-ovmf est construit avec le support SMM. Si le support S3 n'est pas pris en charge dans la VM, la VM peut ne pas démarrer du tout.

Ajoutez l'option -global ICH9-LPC.disable_s3=1 à la commande qemu.

Consultez FS#59465 et https://github.com/tianocore/edk2/blob/master/OvmfPkg/README pour plus de détails et les options requises pour utiliser Secure Boot dans QEMU.

Les interruptions du CPU invité ne se déclenchent pas

Si vous écrivez votre propre système d'exploitation en suivant le OSDev wiki, ou si vous vous promenez simplement dans le code d'assemblage de l'architecture invitée en utilisant l'interface gdb de QEMU en utilisant l'option -s, il est utile de savoir que de nombreux émulateurs, y compris QEMU, implémentent généralement certaines interruptions du CPU laissant de nombreuses interruptions matérielles non implémentées. Une façon de savoir si votre code déclenche une interruption, est d'utiliser :

-d int

pour activer l'affichage des interruptions/exceptions sur stdout.

Pour consulter les autres fonctionnalités de débogage des invités que QEMU a à offrir, consultez :

qemu-system-x86_64 -d help

ou remplacez x86_64 par l'architecture invitée de votre choix.

Voir aussi