• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Chargez un noyau linux sans reboot avec kexec
 

Chargez un noyau linux sans reboot avec kexec

on

  • 285 views

Chargez un noyau linux sans reboot avec kexec

Chargez un noyau linux sans reboot avec kexec

Statistics

Views

Total Views
285
Views on SlideShare
284
Embed Views
1

Actions

Likes
1
Downloads
1
Comments
0

1 Embed 1

http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Chargez un noyau linux sans reboot avec kexec Chargez un noyau linux sans reboot avec kexec Document Transcript

    • Chargez un nouveau noyau linux à chaud avec kexec Thierry GAYET http://www.nextinnovation.org Qui n'a jamais souhaité pouvoir tester un noyau à chaud sans avoir à rebooter physiquement son système pour minimiser le temps mort du au redémarrage d'un système. 1. Introduction Le nom « kexec » provient de l'exécution du noyau, dérivé de l'appel du noyau exec Unix / Linux. C'est un mécanisme du noyau Linux qui permet le démarrage «à chaud» d'un nouveau noyau « sur » le noyau en cours d'exécution. En effet, il permet donc de sauter plusieurs étape : • phase d'initialisation du matériel par le microprogramme du système : BIOS, BIOS UEFI, coreboot (aka linuxBios) ; • différents tests sur le matériel : ◦ mémoire vive ; ◦ périphériques de stockages ou mass-storage (disques RAID, … ) ; ◦ ... • bootloader grub ou autre Il charge donc directement le nouveau noyau en mémoire, et commence à s'exécuter immédiatement après. Cela permet d'éviter de longs délais associés à un redémarrage complet, et peut aider les systèmes à répondre aux exigences de haute disponibilité en minimisant les temps d'arrêt. Cela fonctionne sur des serveurs de grosses capacités (mémoire, disques, etc), et même sur certain ordinateurs de bureau ou portables. 2. Installation Tout comme cela peut être fait habituellement, les binaires de kexec sont disponible dans la majorité des repos de packages. Kexec est fournis par le paquet “kexec-tools” : $ apt-cache search kexec [sudo] password for tgayet: kexec-tools - tools to support fast kexec reboots mkelfimage - utility to create ELF boot images from Linux kernel images pxe-kexec - Fetch PXE configuration file and netboot using kexec $ apt-get install kexec-tools Avec les dérivés de Red Hat, la commande pourra varier « yum install kexec-tools » ou sous gentoo « emerge -av kexec-tools ». L'installation de ce package entraînera par dépendance l'installation d'autres packages comme « debconf », « initramfs-tools », « makedumpfile » et enfin « crash ».
    • 3. Démarrage Un redémarrage via “kexec” se décompose en 2 phases : Un redémarrage via « kexec » se décompose en 2 phases : • chargement du noyau en spécifiant les paramètres nécessaires ; • exécution du redémarrage 3.1 Vérification des conditions initiales Premièrement on vérifiera la version courante du noyau GNU/linux déjà chargé pour la comparer une fois le redémarrage du nouveau noyau effectué : $ uname -a Linux PCL131017 3.8.0-34-generic #49~precise1-Ubuntu SMP Wed Nov 13 18:05:00 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux On vérifiera également les paramètres passés au noyau par le bootloader grub2 : $ cat /proc/cmdline BOOT_IMAGE=/boot/vmlinuz-3.8.0-34-generic root=UUID=b48414f7-fdbc-4b4d-97fc-a2b40e53e839 ro quiet splash vt.handoff=7 Enfin, on pourra vérifier les versions noyaux présente dans la partition de boot : $ ls -al /boot | grep vmlinuz -rw-r--r-- 1 root root 3847424 févr. 27 2013 vmlinuz-2.6.32-art-generic -rw-r--r-- 1 root root 4237104 nov. 18 19:47 vmlinuz-2.6.38.8-xenomai -rw------- 1 root root 4998096 nov. 21 01:23 vmlinuz-3.2.0-57-lowlatency -rw-r--r-- 1 root root 5426432 oct. 15 16:40 vmlinuz-3.8.0-29-generic -rw------- 1 root root 5428304 sept. 11 20:44 vmlinuz-3.8.0-31-generic -rw------- 1 root root 5428528 oct. 2 18:43 vmlinuz-3.8.0-32-generic -rw------- 1 root root 5426064 oct. 24 18:50 vmlinuz-3.8.0-33-generic -rw------- 1 root root 5426224 nov. 13 19:26 vmlinuz-3.8.0-34-generic et $ ls -al /boot | grep initrd.img -rw-r--r-- 1 root root 13324390 nov. 18 20:11 initrd.img-2.6.38.8-xenomai -rw-r--r-- 1 root root 14240658 déc. 6 12:32 initrd.img-3.2.0-57-lowlatency -rw-r--r-- 1 root root 16208253 oct. 15 17:03 initrd.img-3.8.0-29-generic -rw-r--r-- 1 root root 16211572 oct. 15 17:58 initrd.img-3.8.0-31-generic -rw-r--r-- 1 root root 16214027 nov. 7 09:49 initrd.img-3.8.0-32-generic -rw-r--r-- 1 root root 16242300 nov. 19 09:58 initrd.img-3.8.0-33-generic -rw------- 1 root root 24034504 déc. 14 11:01 initrd.img-3.8.0-34-generic On pourra donc soit charger un noyau compilé séparément ou bien un autre noyau. 3.2 Chargement du noyau Dans cette phase préparatoire, il sera donné plusieurs paramètre à “kexec” :
    • • le noyau à charger (option “-l”) • les options qui doivent être passé à ce noyau (option “—append=” ou “—command-line=”) • l’initrd à appliquer (option “—initrd=” ou “—ramdisk=”) Cela donne donc avec le chargement du noyau 3.8.0.33 : $ sudo kexec -l /boot/vmlinuz-3.8.0-33-generic --append="$( cat /proc/cmdline ) panic=10" --initrd=/boot/initrd.img-3.8.0-33-generic Pour la ligne de paramètre, on reprendra celui du noyau courant qui au runtime peut être obtenu depuis le pseudo filesystem /proc/cmdline. A noter que le ramdisk reste optionnel et que nous aurions pu nous contenter de : $ sudo kexec -l /boot/vmlinuz-3.8.0-33-generic --append="$( cat /proc/cmdline ) panic=10" Une fois le noyau chargé, cela ne l'exécute pas pour autant. 3.3 Redémarrage du noyau noyau L’option “-e” (pour “execute”) de la commande kexec lance la séquence de redémarrage. : $ sudo kexec -e Attention sur un serveur cela change de noyau mais sur un desktop, la session sera coupée. Une fois redémarré, on peut vérifier le changement de noyau grace à la version : $ uname -a Linux PCL131017 3.8.0-33-generic #48~precise1-Ubuntu SMP Thu Oct 24 16:28:06 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux Et voilà votre système qui vient de change de noyau et cela à chaud !! 3. L'envers du décors de kexec Un des plus grands défis dans le développement de kexec vient du fait que le noyau Linux fonctionne à partir d'une adresse fixe en mémoire. Cela signifie que le nouveau noyau aura besoin de se charger à la même adresse que le noyau actuel. Sur les systèmes x86, le noyau se trouve à l'adresse phyisique 0x100000 (adresse de 0xc0000000 en virtuel, connu sous le nom PAGE_OFFSET). La tâche d'écrasement de l'ancien noyau avec la nouvelle se fait en trois étapes : • Copie du nouveau noyau en mémoire ; • Déplacement de l'image du noyau dans la mémoire dynamique du noyau ; • Copie de cette image dans la destination réelle (en remplaçant le noyau actuel), puis redémarrage du nouveau noyau . Les deux premières étapes sont réalisées lors du chargement du nouveau noyau .La première tâche consiste à interpréter le contenu du fichier image du noyau. Kexec-tool a été construit de telle sorte que l'on puisse en principe charger et démarrer à n'importe quel moment un noyau (même non-linux). Actuellement, il est possible de démarrer à n'importe quel noyau de format ELF32. Le fichier est analysé et les segment du noyau sont chargés dans les buffers. Ces segments sont classés en fonction de la nature du code. Par exemple, dans le cas où le format de fichier du noyau couramment utilisé est « bzImage », les
    • segments typiques sont pour le code 16 bits noyau, le code du noyau sera 32 bits, et init Code du disque virtuel . La structure utilisée pour le suivi de ces segments est connu comme kexec_segment et est une structure assez simple en soit : struct kexec_segment { void* buf; size_t bufsz; void* mem; size_t memsz; }; Détail de la structure kexec_segment. Les deux premiers éléments de la structure pointe sur la mémoire tampon de l'espace utilisateur et sa taille. Les deux éléments suivants indiquent la destination finale du segment ainsi que sa taille. Une fois l'image du noyau chargée en mémoire par le module relatif au format respectif, elle est transférée dynamiquement grâce à l'appel système sys_kexec. Cet appel système alloue les pages de noyau dynamique pour chacun des segments qui ont été adoptées depuis l'espace utilisateur et copie les segments sur ces pages noyau. Kexec alloue également une page de noyau pour stocker un petit stub de code assembleur, connu sous le nom reboot_code_buffer. Cette souche de code fait le travail réel d'écrasement du noyau actuel avec le nouveau noyau et s'il déplace. Le reboot_code_buffer est le seul tampon qui se trouve dans son dernier « lieu transitoire». En d'autres termes, il est exécuté à partir du même endroit où il a été initialement initialement chargé. Pour ce faire, sur les systèmes avec MMU d'activé, la page contenant le code identité comme mapée. Pour parler simplement, il s'agit de créer une page d'entrée de table dans la structure de la table de la page du noyau « init_mm » avec la même adresse physique et virtuel. Cela est nécessaire pour être en mesure d'accéder à ce morceau de code lors de l'opération de redémarrage , comme nous le verrons plus tard. Les informations sur la reboot_code_buffer, les différents segments, et d'autres détails sont maintenues grâce à l'utilisation de la structure de kimage suivante : struct kimage { kimage_entry_t head; kimage_entry_t *entry; kimage_entry_t *last_entry; unsigned long destination; unsigned long offset; unsigned long start; struct page *reboot_code_pages; unsigned long nr_segments; struct kexec_segment segment[KEXEC_SEGMENT_MAX+1]; struct list_head dest_pages; struct list_head unuseable_pages; }; Détail de la structure kimage. Les parties les plus importantes de cette structure sont, bien sûr, le segment [KEXEC_SEGMENT_MAX+1] qui pointent vers les tampons de la mémoire du noyau contenant l'image, et le pointeur reboot_code_pages au stub assembleur utilisé pendant la phase de redémarrage. Une fois l'image du noyau chargé, le système est prêt à redémarrer avec ce dernier. Le
    • fonctionnement réel sur le redémarrage sur le nouveau noyau démarre avec la commande kexec -e . Cette commande appelle essentiellement le noyau pour effectuer un redémarrage à l'aide de l'appel système de sys_reboot, mais avec un drapeau spécial de LINUX_REBOOT_CMD_KEXEC L'appel système reboot, en voyant le drapeau spécial, transfère le contrôle à la fonction machine_kexec(). Les actions réalisées par machine_kexec( ) sont extrêmement spécifique à l'architecture. Sous x86, la séquence d'actions est la suivante: 1. Pour l'accès reboot_code_buffer bascule de la structure de mm du processus actuel à la structure de init_mm du noyau ; 2. Arrête les APICS et désactive les interruptions ; 3. Copie l' ensemble du code de stub dans le reboot_code_buffer que l'on a attribué lors du chargement de l'image du noyau. Le code assembleur se trouve dans le sousprogramme de relocate_new_kernel ; 4. Charge tous les registres de segment avec le segment de données du noyau ( __KERNEL_DS ) de valeur et invalide la GDT et IDT ; 5. va au code localisé dans reboot_code_buffer, et passe des informations vitales comme les paramètres à passer au nouveau noyau, la page d'indirection contenant les adresses source / destination de l'image du noyau, l'adresse de départ du nouveau noyau, l'adresse de la page reboot_code_buffer et un drapeau indiquant si le système a l'extension d'adresse physique (PAE) est activé. Le stub assembleur effectue quant à lui les opérations suivantes : • Lit les arguments de la pile et les sauvegarde dans des registres et désactive les interruptions ; • En utilisant l'adresse de sa propre page qui lui a été passé comme argument, met en place une pile à la fin de cette page ; • Stocke l'adresse de départ de la nouvelle image du noyau sur la pile de sorte que le retour du code de remplacement prendra automatiquement le système à l'image du nouveau noyau ; • Désactive la pagination en réglant les bits appropriés dans le registre de cr0 ; • Remet le registre de base de répertoire de pages, cr4 , à zéro ; • Efface la traduction Tampons de Consultation (TLB) ; • Copie toutes les pages d'image du noyau dans leurs pages de destination finale ; • Vide le TLB une fois de plus ; • Remet tous les registres à zéro , à l'exception du registre de pointeur de pile esp ( car il pointe vers la pile contenant l'adresse de départ du nouveau noyau ) . • « Retours » à partir du stub. Cela prend en compte automatiquement le système comme le nouveau noyau . Après cette séquence terminée, le nouveau noyau prend le contrôle et le système est démarré normalement. 4. Avantages et utilisations de kexec Les systèmes avec des exigences de haute disponibilité et les développeurs du noyau qui doivent redémarrer sans cesse leurs systèmes apprécieront le plus des avantages que peut offrir kexec. Parce que kexec saute les parties les plus fastidieuses (lente) du redémarrage du système, à savoir la phase de firmware, le redémarrages avec kexec sont extrêmement rapides et la disponibilité est augmentée. Kexec a également des applications intéressantes dans les outils de vidage mémoire. Le projet Linux Kernel Crash Dumps (LKCD) a utilisé kexec pour élaborer un mécanisme de dumping
    • différent. Lors d'un kernel panic du système ou lors de l'initialisation d'un dump par l'utilisateur, l'image de la mémoire système est comprimé et stocké dans les pages de mémoire disponibles. Ensuite, le système est redémarré avec un autre noyau en utilisant kexec. La zone de stockage est précisé à ce dernier de façon à éviter tout écrasement ou altération. Par la suite, le dump mémoire peut être récupéré sur l'une d'une partition de disque ou à travers le réseau. La clé de la réalisation réside dans le fait qu'en évitant l'étape de firmware pendant le redémarrage, LKCD est capable d'empêcher le contenu de la mémoire physique d'être effacé. 5. Spécificité à Debian ou Ubuntu Pour les utilisateurs de Debian, Ubuntu, etc, “kexec” ce substitue au “reboot” classique de la machine dès son installation. Par défaut, un “reboot” charge, à chaud, le noyau “/vmlinuz” avec les options courantes (récupérées dans “/proc/cmdline”) et l’initrd “/initrd.img”. Ces paramètres peuvent être modifiés dans le fichier « /etc/default/kexec » : ... # Utilisation de kexec pour le redémarrage ? true/false LOAD_KEXEC=true # Noyau par défaut à charger : KERNEL_IMAGE="/vmlinuz" # initrd à charger par défaut : INITRD="/initrd.img" # Options de démarrage du noyau. Si vide, récupère les options # de /proc/cmdline : APPEND="" # ex : APPEND="$( cat /proc/cmdline ) panic=10" Une fois “kexec-tools” installé sur votre système vous pouvez effectuer un redémarrage classique via “coldreboot” qui est un script bash contenant : #!/bin/sh NOKEXECFILE=/tmp/no-kexec-reboot /bin/rm -f $NOKEXECFILE touch $NOKEXECFILE /sbin/reboot $* La commande du redémarrage nécessite elle aussi des droits superutilisateur : $ sudo coldreboot 6. Allier un boot tftp avec Kexec Avec kexec, le package « pxe-kexec » est utilisable. Il faut tout d'abord l'installer : $ sudo apt-get install pxe-kexec Pour la mise en place de kexec via pxe, l'utilitaire « pxkxc » peut être téléchargé : http://myllynen.fedorapeople.org/ Il allie la simplicité du PXE et la puissance de kexec pour permettre des démarrage d'une image kernel / initrd depuis un serveur PXE sans la nécessité pour le soutien HW, les images de démarrage, ou même d'avoir à redémarrer le système. Par exemple, on peut lancer l'installation d'une distribution sans média de démarrage. pxkxc fournit une interface utilisateur et comme il a été implémenté en Python il est facile de l'améliorer et de le personnaliser au besoin. Quelques exemples de cas d'utilisation concret :
    • • Un utilisateur décide, avec le soutien kexec, de faire une nouvelle installation d'un système linux sur un système en cours d'exécution. L'utilisateur exécute simplement pxkxc en tant que root et choisit l'option de menu appropriée . Le programme d'installation démarre automatiquement séparément en téléchargeant ou l'écriture des images de démarrage incluant tout le support nécessaire pour le matériel. • Une entreprise dispose de plusieurs types de systèmes sur leur réseau, dont la plupart supportent PXE au niveau matériel. Les autres sont compatible avec gPXE. Cependant , le portage de nouveaux drivers ou même des sous-systèmes du noyau se révélerait une tâche hardue à concrétiser pour faire en sorte que tous les drivers réseau possède un support avec gPXE. En créant une image d'amorçage constitué par un noyau récent GNU/linux et un initrd modifié qui lance pxkxc l' entreprise peut faire les installations basées PXE sur tous leurs systèmes, indépendamment du niveau de prise en charge PXE / gPXE de leur matériel. Aussi, en ajoutant quelques personnalisations comme les paramètres de proxy HTTP ou d'autres ajustements en fonction de l'environnement de réseau détectée, cela devient un outils convivial pour l'administrateur système et réseau. Pxkxc jusqu'ici a surtout été testé en utilisant les touches F12 et F13, l'autre combinaisons peuvent aussi fonctionner. 7. Sécurité Bien que possible, la mise en œuvre d'un mécanisme tel que kexec soulève deux défis majeurs: • La mémoire du noyau en cours d'exécution est remplacé par le nouveau noyau, alors que l'ancien est toujours en cours d'exécution ; • Le nouveau noyau devra généralement s'attendre à ce que tous les périphériques physiques soient déjà dans un état bien défini, car ils sont après un redémarrage du système , lorsque le BIOS , l'UEFI ou le microprogramme du système réinitialise les à un état « sain d'esprit » . Le contournement d'un réel redémarrage peut laisser les appareils dans un état inconnu, et le nouveau noyau devra se remettre de cette transition. Il y a des problèmes de sécurité associés au mécanisme kexec, comme pratiquement tout ce que peut être chargé et exécuté de cette façon, en raison du fait que le nouveau noyau à exécuter n'est pas nécessairement signé. En d'autres termes, même si un mécanisme dans le noyau solide permettrait d'assurer que seuls les modules du noyau Linux signés puisse être chargés dans le noyau en cours d'exécution, l'utilisateur root peut toujours charger du code arbitraire via kexec et l'exécuter. 8. Conclusion Voila, avec kexec, il est possible de réduire la disponibilité d'un système en minimisant les reboot. Cela peu également servir à tester la configuration d'un noyau. 9. Liens • • • • • • • • • https://www.kernel.org/pub/linux/kernel/people/geoff/petitboot/kexec-man-11.10.21g90da2c37.txt http://manpages.ubuntu.com/manpages/precise/en/man8/kexec.8.html http://manpages.ubuntu.com/manpages/precise/en/man8/pxe-kexec.8.html http://myllynen.fedorapeople.org/pxkxc-0.1.1.tar.gz http://doc.fedora-fr.org/wiki/Configuration_d %27un_serveur_pour_lancer_des_installations_par_PXE_boot http://pxe-kexec.berlios.de/ https://www.kernel.org/pub/linux/kernel/people/geoff/petitboot/petitboot.html http://www.solemnwarning.net/kexec-loader/ http://www.solemnwarning.net/kexec-loader/faq
    • • • • • • • • • • • • • • • • • • http://www.solemnwarning.net/kexec-loader/readme.html https://wiki.archlinux.org/index.php/kexec http://www.almesberger.net/cv/papers/ols2k-9.pdf http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man3/exec.3.html http://web.archive.org/web/20130121033946/http://www.ibm.com/developerworks/linux/lib rary/l-kexec/index.html http://archive09.linux.com/feature/1502 http://mjg59.dreamwidth.org/28746.html http://www.outflux.net/blog/archives/2013/12/10/live-patching-the-kernel/ http://turbochaos.blogspot.fr/2013/10/writing-linux-rootkits-301_31.html http://prefetch.net/blog/index.php/2009/07/06/using-kdump-to-get-core-files-on-fedora-andcentos-hosts/ http://www.solemnwarning.net/kexec-loader/downloads/addmod.sh https://github.com/mjg59/kexec-tools/tree/mjg_dummy http://grsecurity.net/~spender/msr32.c http://xorl.wordpress.com/2010/11/20/grkernsec_hidesym-hide-kernel-symbols/ http://web.archive.org/web/20130116180330/http://lkcd.sourceforge.net/ https://docs.google.com/file/d/0ByaHyu9Ur1viMm52TFdXTVVNWjg/edit http://wwwarchive.xenproject.org/files/xensummit_santaclara11/aug3/7_DanielK_Kexec_KDump.pdf