Fonctionnalité Vhost-User pour QEMU
Vhost-User Appliqué à la Commutation Ethernet Snabbswitch
L'objectif de ce document est de présenter au lecteur la fonctionnalité vhost-user pour QEMU qui a été développée par Virtual Open Systems en utilisant le commutateur ethernet Snabbswitch. Ce document traite également de l'architecture de vhost-user et Vapp. Aussi, il sera également question de guider le lecteur vers la préparation du code binaire QEMU intégrant la fonctionnalité vhost-user pour ensuite pouvoir le tester avec l'implementation de référence Vapp.
Cas d'Usage pour Vhost-User
Une des façons pour des machines virtuelles sous QEMU/KVM d'accéder à un réseau externe est de le faire par le biais du pilote de réseau paravirtualisé virtio_net. Dans l'insfrastructure Virtio, un pilote virtio_pci exécute un 'virtio ring' (anneau virtio) qui lui même implémente un mécanisme standard pour mettre en oeuvre des pilotes paravirtualisés; ce qui signifie qu'un périphérique PCI virtuel émulé par QEMU, sert de mécanisme de transport qui implémente l'anneau virtio sur les machines virtuelles x86. En haut de cette infrastructure spécifique de la machine, les pilotes Virtio génériques utiliseront une API générique pour mettre en place virtqueues, qui seront sollicitées à chaque instance de nouvelles données.
Virtio_net est l'implementation d'un pilote réseau basé sur Virtio; Un invité exécutant le pilote réseau virtio_net, partagera un certain nombre de virtqueues avec le processus QEMU qui héberge cet invité. Ce qui fait que le processus QEMU recevra le trafic réseau de l'hôte, qu'il transmet au réseau du hôte. Cependant, ceci implique que l'ensemble du trafic invité soit assuré par le processus QEMU avant d'être traité plus en profondeur par la pile réseau de l'hôte.
La solution à ce problème est vhost qui permet au processus de l'espace utilisateur de partager directement un certain nombre de virtqueues avec un pilote noyau. Le mécanisme de transport dans ce cas, consiste en la capacité côté noyau à accéder à la mémoire d'application de l'espace utilisateur, et à un certain nombre de ioeventfds et irqfds de servir de mécanisme de lancement. Un invité QEMU utilisera encore un périphérique PCI émulé, tandis que le plan de contrôle reste toujours géré par QEMU; Ceci étant, une fois qu'un virtqueue a été mis en place, il utilisera l'API de vhost pour passer le contrôle direct d'un virtqueue à un pilote noyau. Dans ce modèle, un pilote vhost_net passera directement du trafic réseau d'invité à un périphérique TUN directement du côté noyau, tout en améliorant par la même occasion les performances de façon significative.
Cependant pour Snabbswitch qui est un commutateur ethernet logiciel fonctionnant entièrement dans l'espace utilisateur, ceci est loin d'être la solution parfaite. En effet, un Snabbswitch pilotant directement le matériel de la carte ethernet, peut afficher une haute performance réseau en s'exécutant quasi complètement dans l'espace utilisateur. Afin que le Snabbswitch puisse atteindre le même niveau de performance avec des machines virtuelles comme c'est le cas actuellement avec la couche matérielle ethernet, il aura besoin de s'interfacer directement avec une machine virtuelle QEMU/KVM par Virtio, tout en minimisant le traitement par un logiciel intermédiaire, qui comprend également le noyau.
Comme dans le cas d'une machine virtuelle QEMU/KVM qui nécessite de simplifier le processus QEMU (en tant que intermédiaire) pour accéder aux fonctionnalités réseau hôte, pareillement pour l'application Snabbswitch, qui fonctionne dans l'espace utilisateur, le traitement au niveau du noyau Linux représente une couche intermédiaire qui réduit les performances. Pour résoudre cette limitation nous allons introduire l'infrastructure Vhost-user.
Panorama de Vhost-User
Le but de vhost-user est de développer un mécanisme de transport Virtio, en restant le plus près possible du paradigme vhost d'utilisation de mémoire partagée, ioeventfds et irqfds. Un mécanisme basé sur les sockets UNIX permet de mettre en place les ressources utilisées par un certain nombre de Vrings repartis entre deux processus d'espaces utilisateurs, qui seront eux placés dans la mémoire partagée. Le mécanisme configure également les eventfds nécessaires pour signaler quand un Vring reçoit une alerte de l'autre partie.
Un vhost-user a été développé dans QEMU via un ensemble de patches, donnant ainsi la possibilité de passer directement tout virtio_net Vrings vers un autre processus de l'espace utilisateur, tout en mettant en place un backend virtio_net en dehors de QEMU. De cette façon, il est possible de réaliser une communication directe entre Snabbswitch et le virtio_net invité QEMU.
QEMU implémente déjà l'interface vhost pour une transmission zéro-copie rapide de données entre invité et noyau-hôte. La configuration de cette interface repose sur une série de ioctls qui définit le plan de contrôle. Dans ce scénario, le backend de réseau QEMU invoqué est le tap netdev. D'habitude on le lance comme ceci:
$ qemu -netdev type=tap,script=/etc/kvm/kvm-ifup,id=net0,vhost=on \
-device virtio-net-pci,netdev=net0
L'objectif des patches vhost-user pour QEMU est de fournir l'infrastructure et l'implementation d'une interface vhost d'espace d'utilisateur. Les éléments principaux de cette implementation sont:
Rajout d'une option à -mem-path pour allouer la RAM invité comme mémoire qui peut être partagée avec un autre processus.
Utilisation de socket Unix pour communiquer entre QEMU et l'implementation vhost d'espace d'utilisateur.
L'application d'espace utilisateur recevra des descripteurs de fichiers pour la RAM partagée pre-allouée d'invité. Il accédera directement aux vrings concernés dans l'espace mémoire invité.
Architecture d'ensemble de vhost-user
Dans l'implementation cible le client vhost est dans QEMU. La cible backend est Snabbswitch.
Compilation et usage
Compilation QEMU
Une version de QEMU patchée avec les derniers patches vhost-user sont disponibles à partir du dépôt de Virtual Open Systems au https://github.com/virtualopensystems/qemu.git, branche vhost-user-v5.
Pour le cloner:
$ git clone -b vhost-user-v5 https://github.com/virtualopensystems/qemu.git
La compilation est immédiate:
$ mkdir qemu/obj
$ cd qemu/obj/
$ ../configure --target-list=x86_64-softmmu
$ make -j
Ceci a pour effet de créer un code binaire QEMU nommé qemu/obj/x86_64-softmmu/qemu-system-x86_64.
Identifiant ou inscription pour visualiser l'information complète