Child pages
  • Debian - Kdump
Skip to end of metadata
Go to start of metadata

Kdump

A ajouter

  • Prise en charge de l'envoi de dump sur NFS
  • Script et/ou paquet à disposition
  • Prise en charge des NMI

Introduction

Kdump est une fonctionnalité du noyau Linux permettant de prendre un dump (une empreinte mémoire) lors d'un crash du système d'exploitation. Cette fonctionnalité permet d'analyser après coup ce qui s'est passé sur le serveur au moment du crash et quel a été le processus engendrant ce crash.

Il est important de noté que cette méthode n'est pas fiable à 100%, certaines fois le dump analysait ne fournira pas la raison exacte du crash.

RedHat a demandé à ses développeurs de travailler sur cette partie du noyau, en fonction des révisions du noyau publié par RedHat, Kdump fonctionne ou ne fonctionne plus...

Noyaux 3.6.x et 3.7.x

Si vous utilisez un noyau 3.6.x ou 3.7.x, la version de crash (6.0.6) présente dans Wheezy ne fonctionnera pas. Il est donc nécessaire de télécharger la version (6.1.0) présente dans Sid.

Voici l'erreur obtenue avec un noyau 3.7.2 et crash 6.0.6 :

please wait... (gathering kmem slab cache data)
crash: invalid structure member offset: kmem_cache_s_next
       FILE: memory.c  LINE: 7903  FUNCTION: kmem_cache_init()
[/usr/bin/crash] error trace: 466a99 => 47b44b => 491f5c => 547d43
  547d43: OFFSET_verify+164
  491f5c: (undetermined)
  47b44b: vm_init+10841
  466a99: main_loop+239

La partie du changelog qui nous intéresse :

Fix for an invocation failure when running against Linux version 3.6 and later kernels
that are configured with CONFIG_SLAB. Without the patch, the crash session fails during
initialization with the error message "crash: invalid structure member offset: kmem_cache_s_next".

Installation

Par défaut le noyau Linux installé sur Debian est compilé avec les options nécessaires au bon fonctionnement de Kdump. Cette partie sera abordée dans la section "Configuration" de cette même page.

# aptitude install kdump-tools linux-image-3.2.0-4-amd64-dbg crash kexec-tools makedumpfile

A quoi servent ces paquets :

  • kdump-tools
    • Tous les outils nécessaires à l'automatisation de Kdump.
  • linux-image-3.2.0-4-amd64-dbg
    • Ce paquet contient tous les symboles nécessaires au debugging du noyau.
  • crash
    • Outil permettant d'analyser un dump généré par Kdump.
  • kexec-tools
    • Tous les outils nécessaires à la mise en mémoire d'un noyau.
  • makedumpfile
    • Programme permettant d'extraire certaines zones mémoire nécessaires à partir de /dev/mem ou /proc/vmcore.

Configuration

GRUB

Pour que Kdump puisse fonctionner, le noyau doit-être capable de se réserver une zone mémoire. Pour se faire il est nécessaire de remplacer la ligne suivante dans le fichier /etc/default/grub :

GRUB_CMDLINE_LINUX_DEFAULT="quiet"

Par :

GRUB_CMDLINE_LINUX_DEFAULT="crashkernel=128M@32M quiet"

Explications :

  • 128M
    • Espace mémoire réservé par le noyau destiné à charger le Kdump en cas de crash.
  • @32M
    • Offset à partir duquel sera réservé la mémoire (en cas de problème voir "Erreur possible n°3").

L'option suivante ne fonctionne pas avec les systèmes ayant moins de 2Go de RAM :

GRUB_CMDLINE_LINUX_DEFAULT="crashkernel=512M-2G:64M,2G-:128M quiet"

Ce que cela signifie :

Si le serveur possède entre 512Mo et 2Go de mémoire alors Kdump se réserve 64Mo de mémoire, si le serveur possède plus de 2Go de mémoire alors Kdump se réserve 128M.

La ligne ci-dessus causera un out of memory lors du démarrage sur le noyau Kdump  :

Kernel panic - not syncing: Out of memory and no killable processes...

Il existe un tableau récapitulatif permettant de choisir la quantité d'espace mémoire à réserver, en règle général ce tableau est plutôt fiable.

Mémoirecrashkernel=
0 - 12 GB128M
13 - 48 GB256M
49 - 128 GB512M
129 - 256 GB1G *(896M, 768M or 512M)

Après modification du fichier, il est nécessaire de régénéré le GRUB pour qu'il prenne en charge le nouveau paramètre noyau.

# update-grub2

Résultat :

Generating grub.cfg ...
Found linux image: /boot/vmlinuz-3.2.0-4-amd64
Found initrd image: /boot/initrd.img-3.2.0-4-amd64
Found linux image: /boot/vmlinuz-3.2.0-3-amd64
Found initrd image: /boot/initrd.img-3.2.0-3-amd64
done

Noyau

A l'installation des paquets, nous parlions d'options compilées dans le noyau qui permettent le bon fonctionnement de Kdump.

# egrep "CRASH_DUMP|CONFIG_KEXEC|CONFIG_MAGIC_SYSRQ" /boot/config-3.2.0-4-amd64

Résultat :

CONFIG_KEXEC=y
CONFIG_CRASH_DUMP=y
CONFIG_MAGIC_SYSRQ=y

Il est nécessaire de redémarrer de le système pour que le noyau démarre avec le nouveau paramètre.

# init 6

Kdump

Voici le contenu du fichier /etc/default/kdump-tools (après quelques modifications de ma part) sans tous les commentaires :

/etc/default/kdump-tools
USE_KDUMP=1
KDUMP_RUNLEVEL="1"
KDUMP_SAVEDIR="file:///var/crash"
KDUMP_NET="none"
KDUMP_SYSCTL="kernel.panic_on_oops=1"
KDUMP_COREDIR="/var/crash"
KDUMP_FAIL_CMD="reboot -f"
DEBUG_KERNEL=/usr/lib/debug/boot/vmlinux-3.2.0-4-amd64
MAKEDUMP_ARGS="-c -d 31"

La ligne MAKEDUMP_ARGS="-c -d 31" veut dire ceci :

  • L'option "-c" indique que le core généré doit être compressé.
  • L'option "-d 31" permet de définir le niveau de dump (dump_level), ces niveaux vont de 0 à 31 (man makedumpfile pour de plus amples informations).

Tableau récapitulatif :

OptionDescription du type de page
1Pages zéro
2Pages de cache
4Cache privé
8Pages utilisateurs
16Pages libres

Voilà comment nous obtenons l'option "-d 31" :

1 + 2 + 4 + 8 +16 = 31

La valeur 31 indique que le core généré inclura toutes les pages mémoire (utilisées et non-utilisées).

De nos jours les serveurs possèdent de plus en plus de mémoire vive, suite à cela les cores générés peuvent atteindre des tailles considérables.
Afin de réduire la taille de ces derniers il est recommandé de ne pas récupérer les pages libres (mémoire non-utilisées), pour se faire il suffit d'enlever 16 à 31 ce qui nous donne 17 :

MAKEDUMP_ARGS="-c -d 17"

Erreur possible n°1

Si le noyau n'a pas réussi à se réserver un adressage mémoire, l'erreur suivante apparaîtra lors du démarrage du service kdump :

Memory for crashkernel is not reserved
Please reserve memory by passing "crashkernel=X@Y" parameter to the kernel
Then try loading kdump kernel
[FAIL] failed to unload kdump kernel ... failed!

La commande ci-dessous permet de vérifier que le noyau se soit attribué de la mémoire pour dumper en cas de crash.

# dmesg | grep "Reserving"

Résultat :

[    0.000000] Reserving 128MB of memory at 32MB for crashkernel (System RAM: 512MB)

Si la commande précédente ne retourne rien c'est que le noyau est mal configuré, il est donc nécessaire de revoir la configuration de GRUB. Un noyau bien configuré doit afficher le paramètre crashkernel dans sa commande de démarrage. Exemple :

# cat /proc/cmdline

Résultat :

BOOT_IMAGE=/boot/vmlinuz-3.2.0-4-amd64 root=UUID=1b7e79c1-5827-4c64-8bd2-060591e0ddc3 ro crashkernel=128M@32M quiet

Erreur possible n°2

Si le chemin vers les fichiers de debug du noyau n'est pas défini dans le fichier de configuration alors l'erreur suivante apparaîtra :

Could not find an installed debug vmlinux image and
DEBUG_KERNEL is not specified in /etc/default/kdump-tools
[warn] makedumpfile may be limited to -d 1 ... (warning).

Pour corriger le problème, éditer le fichier /etc/default/kdump et remplacer :

#DEBUG_KERNEL=

Par :

DEBUG_KERNEL=/usr/lib/debug/boot/vmlinux-3.2.0-4-amd64

Erreur possible n°3

Si l'offset de réservation de la mémoire démarre trop bas alors la réservation sera impossible et l'erreur suivante apparaîtra lors du dmesg :

crashkernel reservation failed - memory is in use

Il est possible de laisser le noyau définir à partir de quel offset il souhaite réserver la mémoire. Pour se faire il suffit de supprimer l'argument @32. Le paramètre crashkernel=128M@32M devient donc crashkernel=128M (à modifier dans le fichier /etc/default/grub).

# dmesg | grep "Reserving"

Résultat :

[ 0.000000] Reserving 128MB of memory at 64MB for crashkernel (System RAM: 512MB)

Le noyau a décider de débuter la réservation à partir de 64MB, soit deux fois plus loin que ce que nous lui avions demandé.

Toutes modifications apportées au fichier de configuration Kdump nécessite une relance du service.

Validation de la configuration

# kdump-config test

Résultat :

USE_KDUMP:         1
KDUMP_SYSCTL:      kernel.panic_on_oops=1
KDUMP_COREDIR:     /var/crash
crashkernel addr:  0x2000000
kdump kernel addr: relocatable
kdump kernel:
   /boot/vmlinuz-3.2.0-4-amd64
kdump initrd: 
  /boot/initrd.img-3.2.0-4-amd64
debug kernel: 
  /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64
kexec command to be used:
  /sbin/kexec -p --command-line="BOOT_IMAGE=/boot/vmlinuz-3.2.0-4-amd64 root=UUID=1b7e79c1-5827-4c64-8bd2-060591e0ddc3 ro quiet irqpoll maxcpus=1 nousb" --initrd=/boot/initrd.img-3.2.0-4-amd64 /boot/vmlinuz-3.2.0-4-amd64

Magic SysRQ

Les Magic SysRQ sont un ensemble de commande permettant d'envoyer des ordres de bas niveau au noyau. Cette fonctionne fait partie du noyau Linux, cependant il est impératif que cette dernière soit compilée dans le noyau (voir la partie Installation).

# cat /proc/sys/kernel/sysrq

Résultat :

1

Si la commande ci-dessus retourne 438 c'est que l'option est bien compilée dans le noyau mais que ce dernier n'est pas encore autorisé à l'utiliser.

Pour corriger cela il faut ajouter la ligne suivante dans le fichier /etc/sysctl.conf :

kernel.sysrq = 1

Puis relancer le sysctl.

# sysctl -p

Quand le service Kdump se lance, se dernier charge un noyau en mémoire. S'il a bien été chargé alors la commande ci-dessous doit retourner 1.

# cat /sys/kernel/kexec_crash_loaded

Résultat :

1

Si la valeur retournée est égale à 0 c'est que le service Kdump n'a pas démarré et que ce dernier n'a pas pu initialiser la commande kexec. Une simple relance du service devrait résoudre le problème.

# /etc/init.d/kdump-tools restart

Simulation d'un crash

Pour simuler un crash du système, il suffit d'utiliser les sysrq configurées précédemment. Ici l'option de crash (c) sera envoyée au noyau (liste complète des sysrq).

# echo c > /proc/sysrq-trigger

Si le noyau a bien reçu cette ordre et que Kdump a bien été configuré alors vous devriez voir démarrer votre serveur sur le noyau chargé en mémoire.

Exemple d'un crash sans que le service Kdump soit démarré :

Exemple d'un crash qui s'est parfaitement déroulé :

Ici, Kdump indique que le crashdump (vmcore) a été stocké dans le répertoire /var/crash/201301191230 (le répertoire est un timestamp de l'heure du crash).

# ls -hl /var/crash/201301191230/dump.201301191230 

Résultat :

-rw------- 1 root root 7.0M Jan 19 12:30 /var/crash/201301191230/dump.201301191230

Analyse du crashdump

Cette étape permet de valider que le crashdump généré est bien exploitable. Il est important d'indiquer à crash les fichiers de debug utilisés lors de la création du crashdump auquel cas il sera incapable d'interpréter ce dernier.

# crash /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64 /var/crash/201301191230/dump.201301191230

Résultat :

crash 6.0.6
Copyright (C) 2002-2012  Red Hat, Inc.
Copyright (C) 2004, 2005, 2006  IBM Corporation
Copyright (C) 1999-2006  Hewlett-Packard Co
Copyright (C) 2005, 2006  Fujitsu Limited
Copyright (C) 2006, 2007  VA Linux Systems Japan K.K.
Copyright (C) 2005  NEC Corporation
Copyright (C) 1999, 2002, 2007  Silicon Graphics, Inc.
Copyright (C) 1999, 2000, 2001, 2002  Mission Critical Linux, Inc.
This program is free software, covered by the GNU General Public License,
and you are welcome to change it and/or distribute copies of it under
certain conditions.  Enter "help copying" to see the conditions.
This program has absolutely no warranty.  Enter "help warranty" for details.
 
GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu"...

      KERNEL: /usr/lib/debug/boot/vmlinux-3.2.0-4-amd64
    DUMPFILE: /var/crash/201301191230/dump.201301191230  [PARTIAL DUMP]
        CPUS: 1
        DATE: Sat Jan 19 12:29:46 2013
      UPTIME: 00:01:19
LOAD AVERAGE: 0.35, 0.15, 0.05
       TASKS: 129
    NODENAME: sorel
     RELEASE: 3.2.0-4-amd64
     VERSION: #1 SMP Debian 3.2.35-2
     MACHINE: x86_64  (2766 Mhz)
      MEMORY: 511.5 MB
       PANIC: "[   79.248677] Oops: 0002 [#1] SMP " (check log for details)
         PID: 1946
     COMMAND: "bash"
        TASK: ffff88001c2a0200  [THREAD_INFO: ffff88001c090000]
         CPU: 0
       STATE: TASK_RUNNING (PANIC)

crash>

Le crashdump est exploitable. (smile)

Pour une analyse plus complète d'un crashdump, je vous invite à lire la documentation suivante Kdump - Analyse