Passage en Debian 13 (Trixie) et problème KVM (libvirt)

Le 10 juin dernier, Debian 12 sortait en version « release » et passait de fait en version « stable ». Comme conseillé, j’attendais environ un mois avant de repasser mon PC en version « testing », afin de bénéficier des dernières versions de logiciels, l’environnement Gnome, etc… Un bon compromis, si l’on accepte d’avoir quelques soucis de temps en temps et de mettre les mains dans le cambouis…

L’opération est toute simple et consiste à modifier le fichier /etc/apt/sources.list et de remplacer le mot bookworm par testing (ou trixie), puis de lancer la commande suivante :

$ sudo apt full-upgrade

Auparavant, on aura pris soin de faire un sudo apt update ; sudo apt upgrade comme il se doit.

La mise à jour s’effectue, et après un redémarrage me voilà en Debian 13 « trixie » : 😎

$ lsb_release -a
No LSB modules are available.
Distributor ID:	Debian
Description:	Debian GNU/Linux trixie/sid
Release:	n/a
Codename:	trixie

Tout s’était bien passé apparemment… jusqu’à ce que je veuille lancer une VM : virt-manager restait en état « Connexion… » et pas moyen d’en sortir :

NOTE : même en mode commande : $ virt-manager –debug, je n’ai pas plus d’infos…
systemd logo

Le problème survient après quelques minutes de fonctionnement : au démarrage tout va bien, puis après quelques minutes, virt-manager ne se connecte plus.

Ça m’a obligé à faire pas mal de tests avec le service libvirt et permis d’apprendre à contrôler cette partie, alors voilà le résultat de mes investigations. À la fin de l’histoire, c’est apparemment un bug de systemd (régression), dont il ne reste qu’à attendre la correction. Cela fait partie des risque d’utiliser la version « testing » de Debian ! 😉 Mais au moins j’y vois désormais un peu plus clair avec KVM et surtout libvirt, l’interface réseau virbr0 et les réseaux virtuels créés pour les VMs.

Voyons voir tout cela…

Problème

Le problème survient semble-t-il après quelques minutes de fonctionnement du PC, après un redémarrage où tout est OK . Puis quelques minutes après, je lance virt-manager et il reste en état « Connexion… », alors qu’il fonctionnait juste après le démarrage.

Réinstallation

Comme je ne m’en sortais pas, j’ai d’abord décidé de désinstaller puis réinstaller les paquets les paquets nécessaires afin de repartir d’une situation saine. Étape inutile, mais bon… au moins je ne vais installer que les paquets nécessaires.

Je commence par désinstaller les paquets que j’avais installé en Debian 12 :

$ sudo apt  remove qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager
$ sudo apt  purge qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager

Puis je suis la doc Debian pour n’installer que les paquets nécessaires, auxquels j’ajoute virt-manager, l’interface graphique de libvirt :

$ sudo apt install qemu-system libvirt-daemon-system virt-manager

En fait le paquet bridge-utils n’est nécessaire que si l’on souhaite utiliser un bridge pour l’interface réseau des VMs. Ce n’est pas mon cas, en mode NAT c’est plus simple (pour accéder aux autres machines du réseau typiquement).

Ensuite, il faut s’ajouter au groupe libvirt, ainsi qu’au groupe kvm (ce dernier pour éviter d’avoir le mot de passe root à entrer au lancement de virt-manager) :

$ sudo adduser pascal libvirt
$ sudo adduser pascal kvm

Voilà, normalement tout est bon. Il est sans doute préférable de redémarrer le PC à ce moment, et on devrait être en état d’utiliser virt-manager pour créer/utiliser des VMs.

Fichier default.xml

On va beaucoup utiliser par la suite la commande virsh qui permet de gérer les réseaux virtuels créés pour les VMs. C’est l’interface de commande de libvirt. Ces réseaux virtuels sont créés à partir d’un fichier default.xml. Il est bon d’en parler un peu.

Ce fichier default.xml par défaut est situé dans le dossier /etc/libvirt/qemu/networks/. En voici un contenu typique :

On y voit que l’on utilisera le NAT, et le range d’adresse IP qui seront attribuées, ainsi que le nom de l’interface réseau sur laquelle on va s’appuyer : virbr0, soit le bridge virtuel utilisé pour le NAT fourni par libvirt.

À toutes fins utiles, une liste des commandes virsh est disponible ici. En cas de réseau manquant, on peut donc en recréer un ($ sudo virsh net-create) avec le fichier fournit par défaut. Ce n’est pas nécessaire sauf mauvaise manip, par contre il est préférable de le faire en mode ‘sudo’ : en effet, selon que l’on lance la commande virsh en mode ‘user’ ou en mode ‘sudo’, ce ne sera pas le même réseau virtuel que l’on manipulera, ce qui peut mener à des confusions.

Première analyse

Je commence donc par aller voir du côté de libvirt, avec la commande virsh en mode « sudo », mais la commande virsh ne répond pas (hang), et je suis obligé de faire un Ctrl-C pour en sortir :

$ sudo virsh net-list --all

Ctrl-C $

À ce stade, on peut dire que l’on a un souci avec le service libvirtd. Il n’est pas normal que la commande sudo virsh net-list -all ne réponde pas.

Dépannage

Je redémarre donc le service libvirtd pour voir et regarde le status :

$ sudo systemctl restart libvirtd.service
$ sudo systemctl status libvirtd.service
● libvirtd.service - Virtualization daemon
     Loaded: loaded (/lib/systemd/system/libvirtd.service; enabled; preset: enabled)
     Active: active (running) since Sun 2023-07-16 18:38:08 CEST; 6s ago
TriggeredBy: ● libvirtd-ro.socket
             ● libvirtd-admin.socket
             ● libvirtd.socket
       Docs: man:libvirtd(8)
             https://libvirt.org
   Main PID: 68342 (libvirtd)
      Tasks: 21 (limit: 32768)
     Memory: 39.6M
        CPU: 248ms
     CGroup: /system.slice/libvirtd.service
             ├─ 1654 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/lib>
             ├─ 1655 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/lib>
             └─68342 /usr/sbin/libvirtd --timeout 120

juil. 16 18:38:08 Ryzen7-5700G systemd[1]: Starting libvirtd.service - Virtualization daemon...
juil. 16 18:38:08 Ryzen7-5700G systemd[1]: Started libvirtd.service - Virtualization daemon.
juil. 16 18:38:09 Ryzen7-5700G dnsmasq[1654]: read /etc/hosts - 7 names
juil. 16 18:38:09 Ryzen7-5700G dnsmasq[1654]: read /var/lib/libvirt/dnsmasq/default.addnhosts - 0 names
juil. 16 18:38:09 Ryzen7-5700G dnsmasq-dhcp[1654]: read /var/lib/libvirt/dnsmasq/default.hostsfile

Tout a l’air OK, je ne vois aucune erreur significative. Je relance alorsune commande virsh et Bingo ! cette fois elle répond, le réseau virtuel est actif et démarré :

$ sudo virsh net-list
* Nom       État    Démarrage automatique   Persistant
-------------------------------------------------------
 default   actif   oui                     oui

Et virt-manager démarre , se connecte, affiche mes VMs, et je peux lancer celles-ci, tout fonctionne comme attendu :

Tout va bien, sauf que… si je ferme virt-manager, quelques minutes plus tard, le problème est réapparu à l’identique ! 🙁 Par contre, la bonne nouvelle, c’est que je sais désormais qu’un simple redémarrage du service libvirtd résout le problème.

Solution

Ça ressemble tout de même furieusement à un bug de libvirt… après tout je suis sous Debian « testing », c’est le prix à payer…

J’envoie donc un mail au support libvirt chez redhat, comme je l’avais déjà fait une fois pour un problème avec iptables. Et le soir même, j’ai une réponse :

Likely the systemd issue already mentioned on this list
https://listman.redhat.com/archives/virt-tools-list/2023-July/017724.html
Regards, Jim

Génial, réponse courte mais précise : c’est un problème connu, et ce n’est pas libvirt qui est en cause, mais systemd.

À la lecture des différents threads, on arrive à ce bug, et il en ressort que :

Dans sa configuration par défaut, libvirtd.service lance un processus libvirtd qui s’arrête après 120 secondes d’inactivité (aucun domaine en cours d’exécution et aucun client connecté). Le service reste actif et libvirtd est réactivé à la demande via l’activation de la socket systemd.

Après la mise à jour de systemd 253.4 à 253.5, l’activation des sockets a cessé de fonctionner. Tenter de se connecter à libvirtd via une socket après qu’elle se soit arrêtée ne donne rien.

Voyons dans quelle version de systemd je suis :

$ sudo apt policy systemd
systemd:
  Installé : 253.5-1

Ok, tout concorde, ce bien ce bug. Il est indiqué en « closed » depuis aujourd’hui (15/07) et la version de systemd prévue pour intégrer cette correction est la v254.

Cela ne devrait donc pas tarder, il ne reste plus qu’à attendre ! Je surveillerai les packages mis à jour ces prochaines semaines, en attendant d’y voir systemd ! 😎

Conclusion

Bonne expérience, j’ai appris plein de commandes concernant la partie réseau virtuel des VMs… et j’en maîtrise mieux désormais le fonctionnement.

La réactivité du support libvirt de redhat est vraiment top et de vraiment bonne qualité. Du coup j’en ai profité pour partager l’info sur le forum debian où un type faisait face au même problème (ici).

Voilà un petit résumé de commandes utiles pour investiguer le problème :

$ sudo systemctl stop libvirtd     !! Arrêt du service libvirt
$ sudo systemctl disable libvirtd     !! Déactivation du service libvirt pour démarrer "propre"

$ sudo ip link delete virbr0     !! Suppression de l'interface réseau 

$ sudo virsh net-list --all     !! vérifier l'état du réseau virtuel

$ sudo virsh net-autostart default --disable     !! mettre le réseau en démarrage manuel
$ sudo virsh net-autostart default     !! mettre le réseau en démarrage automatique

$ sudo systemctl start libvirtd     !! démarrer le service
$ sudo systemctl enable libvirtd     !! réactiver le service
$ sudo virsh net-start default     !! démarrer le réseau

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *