Google concernant Linux et les mises à jour du noyau sans redémarrer le serveur

Google concernant Linux et les mises à jour du noyau sans redémarrer le serveur

Depuis plusieurs années, Linux permet d’appliquer certains correctifs de sécurité au kernel sans avoir à arrêter la machine. Cependant, remplacer l’intégralité du kernel par une version différente tout en maintenant en vie des charges comme des machines virtuelles, des bases de données ou des services en mémoire constitue un défi bien plus complexe. Deux technologies, en grande partie développées pour répondre aux besoins de Google, Kexec HandOver (KHO) et Live Update Orchestrator (LUO), rapprochent cette possibilité du kernel standard et pourraient transformer la gestion de l’infrastructure Linux à haute disponibilité.

Les clés de KHO et LUO en 20 secondes

  • KHO est arrivé dans le kernel Linux 6.16 et permet de conserver certaines régions de mémoire lors d’une transition via kexec.
  • LUO a été intégré ultérieurement dans Linux 6.19 et organise la conservation et la récupération des ressources entre deux kernels.
  • Son cas d’usage principal concerne les hyperviseurs dans le cloud, où un redémarrage de l’hôte impacterait les machines virtuelles.
  • Systemd 261 intègre déjà LUO pour conserver les descripteurs de fichiers de services.
  • Cependant, c’est encore une technologie en cours de développement : changer de kernel sans redémarrage classique ne signifie pas encore que tout serveur puisse effectuer une mise à jour de façon totalement transparente.

Il est important de faire la distinction : LUO ne se limite pas à un simple live patching. Ksplice, kpatch ou KernelCare permettent de modifier le code d’un kernel en cours d’exécution. Ils sont très utiles pour corriger rapidement une vulnérabilité sans redémarrage, mais le kernel reste essentiellement le même.

KHO et LUO proposent une opération différente : lancer réellement un autre kernel via kexec, tout en cherchant à transférer une partie de l’état nécessaire à la charge de travail.

La documentation du kernel décrit le Live Update comme un processus de redémarrage spécialisé basé sur kexec. Il permet de passer d’une version de kernel à une autre tout en conservant certains ressources et en maintenant opérationnels les dispositifs compatibles durant la transition. La situation qui a motivé leur développement est précisément l’usage de Linux comme hyperviseur dans de grands environnements cloud.

KHO, le pont de mémoire entre deux kernels

kexec n’est pas une technologie nouvelle. Linux permet depuis des années de charger un nouveau kernel depuis le kernel en cours, évitant une partie du processus du démarrage traditionnel et sans passer à nouveau par le firmware de la machine.

Le vrai défi réside dans l’état.

Un nouveau kernel démarre généralement dans un état vierge. La mémoire et certains ressources de l’ancien kernel ne peuvent être simplement considérés comme valides.

Kexec HandOver (KHO) introduit précisément une infrastructure pour conserver des régions spécifiques de mémoire lors de cette transition.

Intégré dans Linux 6.16 en 2025, KHO est défini par la documentation du kernel comme un mécanisme capable de préserver des régions de mémoire, pouvant contenir des états sérialisés du système, en utilisant une exécution via kexec.

Son fonctionnement s’appuie sur une structure appelée Flattened Device Tree (FDT). L’ancien kernel décrit quelles régions doivent être conservées, et cette information accompagne la transition. Le nouveau kernel peut ensuite localiser ces blocs et reconstituer l’état correspondant.

Pour faire simple, le flux se résume à :

Kernel Linux A
      │
      ├── État pouvant être abandonné
      │
      └── Mémoire à conserver
                    │
                    ▼
                  KHO
                    │
                 kexec
                    │
                    ▼
Kernel Linux B
      │
      └── Récupère les régions sauvegardées

La documentation indique que le kernel doit être compilé avec :

CONFIG_KEXEC_HANDOVER=y

Et que KHO doit être activé lors du démarrage avec :

kho=on

Il est aussi possible de réserver des zones mémoire via kho_scratch. Un exemple donné dans la documentation du kernel est :

kho_scratch=16M,512M,256M

Ce qui réserve des espaces spécifiques qui restent disponibles durant les opérations de kexec.

Ensuite, le nouveau kernel est chargé avec le chargeur kexec_file du kernel lui-même :

kexec -l /chemin/vers/bzImage --initrd /chemin/vers/initrd -s

et la transition se fait avec :

kexec -e

La option -s est importante : la documentation indique que les outils utilisateur ne disposent pas encore d’un support KHO équivalent avec le chargeur traditionnel.

Mais KHO seul ne résout pas tout.

Il peut fournir de la mémoire au kernel suivant. Reste à savoir ce que cette mémoire représente, quels processus l’utilisent et comment reconstruire les ressources qui en dépendent.

C’est ici qu’intervient LUO.

LUO, tenter de garder en vie la charge lors du changement de kernel

Live Update Orchestrator a été intégré dans le kernel principal à partir de Linux 6.19, basé notamment sur les fondations posées par KHO.

Son objectif est de coordonner tout le processus de sauvegarde.

LUO dispose de sessions qui rassemblent des ressources devant survivre à la transition. Un agent en espace utilisateur crée une session, y inclut les ressources à préserver, et, lorsque le kexec intervient, le kernel sérialise les informations nécessaires.

Après le démarrage du nouveau kernel, la même session peut être récupérée par son nom.

Le cycle de base est :

1. Créer une session LUO
2. Enregistrer les ressources
3. Sauvegarder l’état
4. Geler les éléments nécessaires
5. Exécuter kexec
6. Démarrer le nouveau kernel
7. Récupérer la session
8. Reconstruire les ressources
9. Continuer la charge de travail

L’interface est généralement accessible via :

/dev/liveupdate

et contrôlée par des appels ioctl. Il est aussi important de noter qu’un seul processus peut maintenir ouvert /dev/liveupdate à la fois, afin d’éviter que plusieurs orchestrateurs tentent d’intervenir simultanément.

Pour activer LUO, le kernel doit être lancé avec :

liveupdate=on

La documentation mentionne explicitement la prise en charge par des sous-systèmes tels que KVM, IOMMU, interruptions, VFIO, mémoire, ainsi que certains systèmes de fichiers, pour participer au processus.

Ce qui explique en partie l’intérêt que Google porte à ce projet.

Le défi difficile : mettre à jour l’hôte sans arrêter ses machines virtuelles

Supposons un serveur physique hébergeant des dizaines de machines virtuelles.

Une vulnérabilité du kernel nécessite une mise à jour vers une nouvelle version.

La méthode traditionnelle serait de migrer les VM vers d’autres nœuds ou de les éteindre, mettre à jour l’hôte, puis le redémarrer.

Dans de grandes clouds, ces opérations représentent un coût élevé.

Ce n’est pas uniquement une question d’interruption visible. Cela implique aussi une capacité supplémentaire pour accueillir les migrations, le trafic réseau, la disponibilité opérationnelle, et une coordination précise entre des milliers d’hôtes.

LUO vise un autre scénario.

Une VM gérée par QEMU/KVM en mémoire, utilisant des ressources du kernel telles que memfd, VFIO ou IOMMU, pourrait, si ces éléments sont préservés lors du kexec, permettre :

Kernel ancien
    │
    ├── QEMU
    │    └── VM en cours d'exécution
    │
    ▼
Préserver mémoire et ressources
    │
    ▼
kexec
    │
    ▼
Kernel nouveau
    │
    ├── Récupérer ressources
    │
    └── Réassocier à la VM

La documentation de LUO indique explicitement son objectif de permettre à des charges telles que les VM utilisant vfio, memfd ou iommufd de conserver leurs ressources critiques durant la transition. Certains dispositifs peuvent même continuer leur activité DMA pendant le changement de kernel.

Du point de vue de la VM, l’idéal serait que le changement de kernel de l’hyperviseur soit quasi imperceptible ou avec une interruption minime.

C’est bien différent d’un simple patch logiciel pour quelques fonctions.

En réalité, le serveur dans ce scénario finirait par exécuter un autre kernel.

Google publie également le luo-agent pour gérer le processus

Le kernel fournit l’infrastructure, mais c’est en espace utilisateur qu’il faut la coordonner.

Google maintient le projet open googleprodkernel/luo-agent, principalement écrit en C et publié sous licence GPL-2.0.

Le projet comprend deux composants principaux :

luod

luoctl

L’architecture vise à éviter que chaque application doive gérer elle-même tout le processus.

Par exemple, luod maintient la session, tandis que les clients comme un processus QEMU s’y abonnent via un socket Unix.

Le flux prévu ressemble à :

Administrateur
     │
   luoctl
     │
     ▼
    luod
     │
     ├── Client QEMU
     ├── Base de données
     └── Autre service compatible
              │
              ▼
         Sessions LUO
              │
              ▼
           Kernel

Selon la documentation, les clients se connectent à :

/run/luod/liveupdate.sock

et peuvent recevoir des descripteurs de session via SCM_RIGHTS, mécanisme Unix permettant de transférer des descripteurs de fichiers entre processus.

Avant le redémarrage, le client demande la sauvegarde, stocke ses ressources et indique qu’il est prêt.

Après le kexec, il se reconnecte avec le même identifiant et réclame sa session.

Ce modèle est particulièrement intéressant car il évite d’imposer un format unique d’état pour toutes les applications. Chaque client connaît mieux que l’orchestrateur quels ressources il doit préserver.

LUO supporté par systemd 261 pour la conservation des descripteurs

LUO n’est pas limité à l’agent expérimental de Google.

La documentation indique que systemd, à partir de la version 261, intègre le support de LUO et peut préserver ses descripteurs de fichiers par service lors d’une mise à jour basée sur kexec.

Les services peuvent utiliser les options :

FileDescriptorStoreMax=

et :

FileDescriptorStorePreserve=

pour préciser quels descripteurs sont conservés par systemd.

Cela est crucial car les descripteurs ne sont pas que des nombres : ils peuvent représenter :

  • des fichiers ouverts ;
  • des pipes ;
  • certains sockets ;
  • de la mémoire via memfd ;
  • des ressources de périphériques ;
  • des sessions LUO.

Les conserver permet à un service démarré après la transition de récupérer des ressources appartenant au processus précédent.

Par exemple, une application de cache mémoire comme memcached pourrait stocker ses gigaoctets de données dans un memfd, conserver cette mémoire lors du changement et la récupérer sans reconstruire toute la cache depuis le stockage.

Cela accroît considérablement l’intérêt pour LUO au-delà des hyperviseurs.

Bases de données, conteneurs et réseaux : des secteurs à suivre

La documentation souligne une conception indépendante de la charge de travail.

Elle mentionne explicitement :

  • machines virtuelles ;
  • conteneurs ;
  • bases de données haute performance ;
  • services réseau ;
  • caches mémoire.

Cependant, il y a une différence importante entre la capacité de cette architecture à supporter ces charges et la possibilité pour chaque application actuelle d’y survivre automatiquement à un changement de kernel.

LUO requiert des pilotes capables de préserver ces différents types de ressources.

C’est pourquoi son architecture inclut des opérations telles que :

can_preserve()
preserve()
freeze()
retrieve()
finish()

Le kernel ancien doit savoir comment sérialiser l’état, le nouvel kernel comment le reconstruire.

Ce système est une infrastructure extensible, pas une machine à voyager dans le temps pour tout processus Linux.

Il peut se compléter avec une autre technologie connue : CRIU (Checkpoint/Restore in Userspace).

CRIU permet de capturer l’état de processus et de le restaurer ultérieurement. Son utilisation inclut la migration ou le checkpoint de conteneurs.

KHO, LUO et CRIU opèrent à des couches différentes, mais leur combinaison permet d’envisager des scénarios où une partie de l’état reste en RAM, tandis qu’une autre est sérialisée et restituée depuis l’espace utilisateur.

Il reste encore du travail avant que cela devienne transparent pour toutes les applications.

Ce n’est pas exactement une mise à jour « sans redémarrage »

Il est important d’introduire une nuance à ce propos.

Dire que LUO permet de changer de kernel « sans redémarrer » peut sembler simpliste, mais cela peut aussi induire en erreur sur le plan technique.

Un redémarrage du kernel est bel et bien effectué.

LUO utilise kexec.

Le kernel ancien cesse de s’exécuter et un nouveau démarre.

Ce que l’on souhaite éviter, c’est le redémarrage complet traditionnel, c’est-à-dire tout le cycle habituel :

éteindre
BIOS/UEFI
firmware
bootloader
kernel
services
applications

À la place, il s’agit de :

kernel ancien
      │
    kexec
      │
kernel nouveau

en tentant de transférer assez d’état entre les deux.

Cette précision est essentielle car elle définit aussi les limites de la technologie.

Un changement de firmware, certaines modifications matérielles ou des problèmes nécessitant une réinitialisation physique continueront à demander un autre type de maintenance.

LUO ne remplace pas le live patching

Kpatch, Ksplice et autres technologies similaires restent pertinentes.

Les deux approches répondent à des besoins différents :

Le live patching serait :

Kernel 6.x
   │
appliquer un patch
   │
Kernel 6.x modifié

Alors que LUO propose :

Kernel A
   │
préserver l’état
   │
kexec
   │
Kernel B

Pour une vulnérabilité mineure, modifier quelques fonctions par patch peut être plus simple et moins risqué que de remplacer tout le kernel.

Mais le live patching présente aussi ses limites.

Toutes les modifications ne peuvent pas facilement être patchées à chaud. Au fil du temps, les divergences entre le kernel initial et la version patchée peuvent se creuser.

Une transition complète permet d’exécuter un kernel intégralement corrigé.

C’est pourquoi ces deux stratégies pourraient coexister : le live patching pour gagner du temps, et LUO pour une mise à jour complète lors d’une interruption largement minimisée.

Il ne faut pas activer cette technologie à l’aveugle en production

Malgré son intégration dans le kernel principal, cette technologie reste en développement.

La documentation officielle de l’API de Live Update précise que elle est encore en cours d’évolution, et la compatibilité lors de transitions entre différentes versions de kernel n’est pas encore garantie. Sa stabilité devra être assurée dans une phase ultérieure.

KHO conserve également des interfaces de débogage susceptibles d’évoluer au fur et à mesure de la stabilisation du sous-système.

En conséquence, voir CONFIG_KEXEC_HANDOVER ou le support LUO dans une distribution ne signifie pas que cette mécanique est prête pour tout serveur critique.

Par exemple, le dépôt actuel de luo-agent exige un kernel ≥ 6.19 avec CONFIG_LIVEUPDATE activé.

Une configuration de démarrage en test pourrait comporter :

kho=on
kho_scratch=16M,512M,256M
liveupdate=on

mais cela ne suffit pas : il faut aussi que la charge à préserver soit compatible et supportée.

Pourquoi cette technologie devient-elle plus importante que jamais ?

Les problèmes liés aux redémarrages de kernel ne sont pas nouveaux.

Ce qui a changé, c’est l’ampleur de l’infrastructure dépendante de Linux.

Un fournisseur cloud peut gérer des milliers d’hyperviseurs physiques, et un seul hôte peut héberger des dizaines voire des centaines de VM.

Lorsqu’une vulnérabilité critique apparaît, une mise à jour ne consiste pas simplement à programmer un redémarrage nocturne.

Il faut :

  • déloger les VM ;
  • les migrer vers d’autres hôtes ;
  • maintenir une capacité suffisante pour gérer ces migrations ;
  • coordonner les opérations de mise à jour ;
  • surveiller les erreurs ;
  • restaurer les charges ultérieurement.

Dans des centres de données équipés de GPU, la complexité augmente en raison du coût des ressources et des caractéristiques des dispositifs utilisant passthrough ou VFIO.

En outre, la détection automatique des vulnérabilités accélère la découverte de nouvelles failles logicielles. L’IA joue un rôle croissant dans cette recherche, même si elle ne peut à elle seule expliquer l’ensemble du volume de vulnérabilités du kernel à un instant T.

Plus le coût opérationnel pour appliquer rapidement un kernel corrigé sera faible, plus grande sera la pression pour éviter de repousser les mises à jour.

C’est probablement là que réside la véritable importance de KHO et LUO.

Il ne s’agit pas de prétendre que Linux ne doit jamais être redémarré.

Il s’agit de tenter de séparer deux processus jadis indissociables :

mettre à jour le système d’exploitation de l’hôte et arrêter la charge de travail en cours.

Si cette séparation devient fiable avec des machines virtuelles, dispositifs, conteneurs, réseaux et bases de données, une mise à jour du kernel pourrait devenir aussi courante qu’une opération de maintenance classique.

Nous n’en sommes pas encore là, mais à partir de Linux 6.16 avec KHO, Linux 6.19 avec LUO, et systemd 261 avec gestion des descripteurs, les éléments essentiels ne sont plus uniquement des expérimentations diffusées sur une mailing list. Ils entrent progressivement dans l’infrastructure standard de Linux.

Questions fréquentes

Linux peut-il déjà mettre à jour n’importe quel kernel sans arrêter le serveur ?

Pas encore complètement de manière transparente. KHO et LUO permettent une transition via kexec en conservant certains états, mais nécessitent un support spécifique du kernel, de l’espace utilisateur, et des applications concernées.

Quelle différence entre LUO et Kpatch ou Ksplice ?

Kpatch et Ksplice modifient en direct un kernel qui continue de s’exécuter. LUO démarre un autre kernel avec kexec en essayant de préserver ses ressources essentielles. La première méthode concerne une modification à chaud, la seconde une transition entre deux kernels.

Quelles versions de Linux incluent KHO et LUO ?

La première infrastructure avec Kexec HandOver a été introduite dans Linux 6.16, tandis que Live Update Orchestrator a été intégré dans Linux 6.19. Systemd a ajouté la prise en charge dans sa version 261.

À quoi sert le luo-agent de Google ?

luo-agent fournit les composants en espace utilisateur qui coordonnent LUO. Il inclut le daemon luod et l’outil luoctl, permettant de charger un nouveau kernel, gérer les sessions, et initier la transition via kexec.

Sources :

  • Documentation du Linux Kernel, Kexec HandOver (KHO).
  • Documentation du Linux Kernel, Live Update Orchestrator et Live Update uAPI.
  • Google Production Kernel, projet open luo-agent sur GitHub.
  • Systemd 261, intégration du File Descriptor Store avec Live Update.
  • Phoronix, suivi de l’intégration de KHO dans Linux 6.16 et LUO dans Linux 6.19.

le dernier