Maison  >  Article  >  Tutoriel système  >  Outil de détection de crash du noyau Linux Kdump

Outil de détection de crash du noyau Linux Kdump

王林
王林avant
2024-01-03 19:25:421069parcourir
Présentation kdump est un moyen d'obtenir un dump du noyau Linux en panne, mais il peut être un peu difficile de trouver de la documentation expliquant son utilisation et ses composants internes. Dans cet article, j'étudierai l'utilisation de base de kdump et comment kdump/kexec est implémenté dans le noyau.

kexec est un chargeur de démarrage Linux noyau à noyau qui permet de démarrer du contexte d'un premier noyau vers un deuxième noyau. kexec arrête le premier cœur, en contournant l'étape du BIOS ou du micrologiciel, et passe au deuxième cœur. Par conséquent, le redémarrage devient plus rapide sans l'étape du BIOS.

kdump peut être utilisé avec une application kexec - par exemple, lorsque le premier noyau plante et qu'un deuxième noyau est démarré, le deuxième noyau est utilisé pour copier le vidage mémoire du premier noyau, qui peut être analysé à l'aide d'outils tels que gdb et crash La cause du crash. (Dans cet article, j'utiliserai les termes « premier noyau » pour désigner le noyau actuellement en cours d'exécution, « deuxième noyau » pour désigner le noyau exécuté avec kexec et « capturer le noyau » pour désigner le noyau en cours d'exécution lorsque le noyau actuel plante.)

Le mécanisme kexec comporte des composants dans le noyau ainsi que dans l'espace utilisateur. Le noyau fournit plusieurs appels système pour la fonctionnalité de redémarrage de kexec. Un outil en espace utilisateur appelé kexec-tools utilise ces appels et fournit un fichier exécutable pour charger et démarrer le « deuxième noyau ». Certaines distributions ajoutent également des wrappers sur kexec-tools, qui aident à capturer et à sauvegarder les sauvegardes de diverses configurations de cibles de sauvegarde. Dans cet article, j'utiliserai un outil appelé distro-kexec-tools pour éviter toute confusion entre les outils kexec en amont et le code kexec-tools spécifique à la distribution. Mes exemples utiliseront la distribution Fedora Linux.

Outil Fedora kexec-tools

Utilisez la commande dnf install kexec-tools pour installer fedora-kexec-tools sur la machine Fedora. Après avoir installé fedora-kexec-tools, vous pouvez exécuter la commande systemctl start kdump pour démarrer le service kdump. Lorsque ce service démarre, il crée un système de fichiers racine (initramfs) qui contient les ressources à monter sur l'emplacement cible, pour contenir le vmcore, ainsi que les commandes pour copier et vider le vmcore vers l'emplacement cible. Le service charge ensuite le noyau et initramfs dans les emplacements appropriés dans la région du noyau en panne afin qu'ils puissent être exécutés en cas de panne du noyau.

Le wrapper Fedora propose deux profils utilisateur :

/etc/kdump.conf spécifie les paramètres de configuration qui doivent être reconstruits après modification. Par exemple, si vous modifiez la cible de vidage d'un disque local vers un disque monté NFS, vous avez besoin des modules de noyau liés à NFS chargés par Capture Kernel.
/etc/sysconfig/kdump spécifie les paramètres de configuration qui ne nécessitent pas de reconstruire initramfs après modification. Par exemple, si vous avez uniquement besoin de modifier les paramètres de ligne de commande passés au "noyau de capture", vous n'avez pas besoin de reconstruire initramfs.
Si le noyau échoue après le démarrage du service kdump, une « capture du noyau » est effectuée, qui exécute ensuite le processus de sauvegarde vmcore dans initramfs, puis redémarre sur un noyau stable.

outils kexec-tools

Compilez le code source de kexec-tools et obtenez un fichier exécutable nommé kexec. Cet exécutable éponyme peut être utilisé pour charger et exécuter un « second noyau », ou charger un « noyau de capture », qui peut être exécuté lorsque le noyau plante.

Commande pour charger le "deuxième noyau" :

# kexec -l kernel.img --initrd=initramfs-image.img –reuse-cmdline

--reuse-command paramètre signifie utiliser la même ligne de commande que le "premier noyau". Utilisez --initrd pour transmettre initramfs. -l indique que vous chargez un "second noyau" qui peut être exécuté par l'application kexec elle-même (kexec -e). Les noyaux chargés avec -l ne peuvent pas être exécutés en cas de panique du noyau. Afin de charger un "noyau de capture" qui peut être exécuté en cas de crash du noyau, le paramètre -p doit être passé à la place de -l.

Commande pour charger le noyau de capture :

# kexec -p kernel.img --initrd=initramfs-image.img –reuse-cmdline

echo c > /pros/sysrq-trigger peut être utilisé pour planter le noyau à des fins de test. Pour plus d'informations sur les options fournies par kexec-tools, consultez man kexec. Avant de passer à la section suivante, jetez un œil à cette démo de kexec_dump :


kdump : streaming de bout en bout

L'image ci-dessous montre l'organigramme. La mémoire du crashkernel doit être réservée au noyau de capture lors du démarrage du "premier noyau". Vous pouvez transmettre crashkernel=Y@X sur la ligne de commande du noyau, où @X est facultatif. crashkernel=256M fonctionne pour la plupart des systèmes x86_64 ; cependant, le choix de la mémoire appropriée pour un crashkernel dépend de nombreux facteurs, tels que la taille du noyau et des initramfs, ainsi que des modules contenus dans les initramfs et des besoins en mémoire de l'application. Durée. Consultez la documentation des paramètres du noyau pour plus de façons de transmettre les paramètres du noyau en cas de crash.
Kdump 检查 Linux 内核崩溃!

pratyush_f1.png

您可以将内核和 initramfs 镜像传递给 kexec 可执行文件,如(kexec-tools)部分的命令所示。“捕获内核”可以与“第一内核”相同,也可以不同。通常,一样即可。Initramfs 是可选的;例如,当内核使用 CONFIG_INITRAMFS_SOURCE 编译时,您不需要它。通常,从第一个 initramfs 中保存一个不一样的捕获 initramfs,因为在捕获 initramfs 中自动执行 vmcore 的副本能获得更好的效果。当执行 kexec 时,它还加载了 elfcorehdr 数据和 purgatory 可执行文件(LCTT 译注:purgatory 就是一个引导加载程序,是为 kdump 定作的。它被赋予了“炼狱”这样一个古怪的名字应该只是一种调侃)。 elfcorehdr 具有关于系统内存组织的信息,而 purgatory 可以在“捕获内核”执行之前执行并验证第二阶段的二进制或数据是否具有正确的 SHA。purgatory 也是可选的。
当“第一内核”崩溃时,它执行必要的退出过程并切换到 purgatory(如果存在)。purgatory 验证加载二进制文件的 SHA256,如果是正确的,则将控制权传递给“捕获内核”。“捕获内核”根据从 elfcorehdr 接收到的系统内存信息创建 vmcore。因此,“捕获内核”启动后,您将看到 /proc/vmcore 中“第一内核”的转储。根据您使用的 initramfs,您现在可以分析转储,将其复制到任何磁盘,也可以是自动复制的,然后重新启动到稳定的内核。

内核系统调用

内核提供了两个系统调用:kexec_load() 和 kexec_file_load(),可以用于在执行 kexec -l 时加载“第二内核”。它还为 reboot() 系统调用提供了一个额外的标志,可用于使用 kexec -e 引导到“第二内核”。

kexec_load():kexec_load() 系统调用加载一个可以在之后通过 reboot() 执行的新的内核。其原型定义如下:

long kexec_load(unsigned long entry, unsigned long nr_segments,
struct kexec_segment *segments, unsigned long flags);

用户空间需要为不同的组件传递不同的段,如内核,initramfs 等。因此,kexec 可执行文件有助于准备这些段。kexec_segment 的结构如下所示:

struct kexec_segment {
void *buf;
/* 用户空间缓冲区 */
size_t bufsz;
/* 用户空间中的缓冲区长度 */
void *mem;
/* 内核的物理地址 */
size_t memsz;
/* 物理地址长度 */
};

当使用 LINUX_REBOOT_CMD_KEXEC 调用 reboot() 时,它会引导进入由 kexec_load 加载的内核。如果标志 KEXEC_ON_CRASH 被传递给 kexec_load(),则加载的内核将不会使用 reboot(LINUX_REBOOT_CMD_KEXEC) 来启动;相反,这将在内核崩溃中执行。必须定义 CONFIG_KEXEC 才能使用 kexec,并且为 kdump 定义 CONFIG_CRASH_DUMP。

kexec_file_load():作为用户,你只需传递两个参数(即 kernel 和 initramfs)到 kexec 可执行文件。然后,kexec 从 sysfs 或其他内核信息源中读取数据,并创建所有段。所以使用 kexec_file_load() 可以简化用户空间,只传递内核和 initramfs 的文件描述符。其余部分由内核本身完成。使用此系统调用时应该启用 CONFIG_KEXEC_FILE。它的原型如下:

long kexec_file_load(int kernel_fd, int initrd_fd, unsigned long
cmdline_len, const char __user * cmdline_ptr, unsigned long
flags);

请注意,kexec_file_load 也可以接受命令行,而 kexec_load() 不行。内核根据不同的系统架构来接受和执行命令行。因此,在 kexec_load() 的情况下,kexec-tools 将通过其中一个段(如在 dtb 或 ELF 引导注释等)中传递命令行。

目前,kexec_file_load() 仅支持 x86 和 PowerPC。

当内核崩溃时会发生什么

当第一个内核崩溃时,在控制权传递给 purgatory 或“捕获内核”之前,会执行以下操作:

  • 准备 CPU 寄存器(参见内核代码中的 crash_setup_regs());
  • 更新 vmcoreinfo 备注(请参阅 crash_save_vmcoreinfo());
  • 关闭非崩溃的 CPU 并保存准备好的寄存器(请参阅 machine_crash_shutdown() 和 crash_save_cpu());
  • 您可能需要在此处禁用中断控制器;
  • 最后,它执行 kexec 重新启动(请参阅 machine_kexec()),它将加载或刷新 kexec 段到内存,并将控制权传递给进入段的执行文件。输入段可以是下一个内核的 purgatory 或开始地址。
ELF 程序头

kdump 中涉及的大多数转储核心都是 ELF 格式。因此,理解 ELF 程序头部很重要,特别是当您想要找到 vmcore 准备的问题。每个 ELF 文件都有一个程序头:

  • 由系统加载器读取,
  • 描述如何将程序加载到内存中,
  • 可以使用 Objdump -p elf_file 来查看程序头。

vmcore 的 ELF 程序头的示例如下:

# objdump -p vmcore
vmcore:
file format elf64-littleaarch64
Program Header:
NOTE off 0x0000000000010000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**0 filesz
0x00000000000013e8 memsz 0x00000000000013e8 flags ---
LOAD off 0x0000000000020000 vaddr 0xffff000008080000 paddr 0x0000004000280000 align 2**0 filesz
0x0000000001460000 memsz 0x0000000001460000 flags rwx
LOAD off 0x0000000001480000 vaddr 0xffff800000200000 paddr 0x0000004000200000 align 2**0 filesz
0x000000007fc00000 memsz 0x000000007fc00000 flags rwx
LOAD off 0x0000000081080000 vaddr 0xffff8000ffe00000 paddr 0x00000040ffe00000 align 2**0 filesz
0x00000002fa7a0000 memsz 0x00000002fa7a0000 flags rwx
LOAD off 0x000000037b820000 vaddr 0xffff8003fa9e0000 paddr 0x00000043fa9e0000 align 2**0 filesz
0x0000000004fc0000 memsz 0x0000000004fc0000 flags rwx
LOAD off 0x00000003807e0000 vaddr 0xffff8003ff9b0000 paddr 0x00000043ff9b0000 align 2**0 filesz
0x0000000000010000 memsz 0x0000000000010000 flags rwx
LOAD off 0x00000003807f0000 vaddr 0xffff8003ff9f0000 paddr 0x00000043ff9f0000 align 2**0 filesz
0x0000000000610000 memsz 0x0000000000610000 flags rwx

在这个例子中,有一个 note 段,其余的是 load 段。note 段提供了有关 CPU 信息,load 段提供了关于复制的系统内存组件的信息。
vmcore 从 elfcorehdr 开始,它具有与 ELF 程序头相同的结构。参见下图中 elfcorehdr 的表示:
Kdump 检查 Linux 内核崩溃!

pratyush_f2.png

kexec-tools 读取 /sys/devices/system/cpu/cpu%d/crash_notes 并准备 CPU PT_NOTE 的标头。同样,它读取 /sys/kernel/vmcoreinfo 并准备 vmcoreinfo PT_NOTE 的标头,从 /proc/iomem 读取系统内存并准备存储器 PT_LOAD 标头。当“捕获内核”接收到 elfcorehdr 时,它从标头中提到的地址中读取数据,并准备 vmcore。

Crash note

Crash notes 是每个 CPU 中用于在系统崩溃的情况下存储 CPU 状态的区域;它有关于当前 PID 和 CPU 寄存器的信息。

vmcoreinfo

该 note 段具有各种内核调试信息,如结构体大小、符号值、页面大小等。这些值由捕获内核解析并嵌入到 /proc/vmcore 中。 vmcoreinfo 主要由 makedumpfile 应用程序使用。在 Linux 内核,include/linux/kexec.h 宏定义了一个新的 vmcoreinfo。 一些示例宏如下所示:

  • VMCOREINFO_PAGESIZE()
  • VMCOREINFO_SYMBOL()
  • VMCOREINFO_SIZE()
  • VMCOREINFO_STRUCT_SIZE()
makedumpfile

vmcore 中的许多信息(如可用页面)都没有用处。makedumpfile 是一个用于排除不必要的页面的应用程序,如:

  • 填满零的页面;
  • 没有私有标志的缓存页面(非专用缓存);
  • 具有私有标志的缓存页面(专用缓存);
  • 用户进程数据页;
  • 可用页面。

此外,makedumpfile 在复制时压缩 /proc/vmcore 的数据。它也可以从转储中删除敏感的符号信息; 然而,为了做到这一点,它首先需要内核的调试信息。该调试信息来自 VMLINUX 或 vmcoreinfo,其输出可以是 ELF 格式或 kdump 压缩格式。

典型用法:

# makedumpfile -l --message-level 1 -d 31 /proc/vmcore makedumpfilecore

详细信息请参阅 man makedumpfile。

kdump 调试

新手在使用 kdump 时可能会遇到的问题:

kexec -p kernel_image 没有成功

检查是否分配了崩溃内存。

  • cat /sys/kernel/kexec_crash_size ne devrait pas avoir de valeur nulle.
  • cat /proc/iomem | grep "Crash kernel" Il devrait y avoir une plage allouée.
  • S'il n'est pas attribué, transmettez le paramètre crashkernel= correct sur la ligne de commande.
  • S'il n'est pas affiché, transmettez l'argument -d à la commande kexec et envoyez le résultat à la liste de diffusion kexec-tools.
Je ne vois rien sur la console (comme "bye") après le dernier message du "premier noyau"
  • Vérifiez si la commande kexec -e suivie de la commande kexec -l kernel_image fonctionne.
  • Les architectures prises en charge ou les options spécifiques à la machine peuvent manquer.
  • Il se peut que la vérification SHA du purgatoire ait échoué. Si votre architecture ne prend pas en charge la console du purgatoire, le débogage peut être difficile.
  • Il se peut que le "deuxième noyau" soit déjà tombé en panne.
  • Transmettez les options earlycon ou earlyprintk de votre système à la ligne de commande "second noyau".
  • Utilisez la liste de diffusion kexec-tools pour partager le premier noyau et capturer les journaux dmesg du noyau.
Ressources fedora-kexec-tools
  • Dépôt GitHub : git://pkgs.fedoraproject.org/kexec-tools
  • Liste de diffusion : [email protégé]
  • Description : les fichiers de spécifications et les scripts fournissent des commandes et des services conviviaux afin que les outils kexec puissent être automatisés dans différents scénarios utilisateur.
kexec-tools
  • Dépôt GitHub : git://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git
  • Liste de diffusion : [email protégé]
  • Description : utilisez l'appel système du noyau et fournissez la commande utilisateur kexec.
Noyau Linux
  • Dépôt GitHub : git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
  • Liste de diffusion : [email protégé]
  • Description : implémente les appels système kexec_load(), kexec_file_load(), reboot() et le code spécifique à l'architecture tel que machine_kexec() et machine_crash_shutdown().
Créer un fichier de vidage
  • Dépôt GitHub : git://git.code.sf.net/p/makedumpfile/code
  • Liste de diffusion : [email protégé]
  • Description : Compressez et filtrez les composants inutiles des fichiers de vidage.

(Titre : Penguin, Boot, modification : Opensource.com. CC BY-SA 4.0)

À propos de l'auteur :

Pratyush Anand - Pratyush travaille avec Red Hat en tant qu'expert du noyau Linux. Il est responsable de plusieurs problèmes kexec/kdump rencontrés par les produits Red Hat et en amont. Il gère également d'autres problèmes de débogage, de traçage et de performances du noyau autour de la plate-forme ARM64 prise en charge par Red Hat. En plus du noyau Linux, il a contribué aux projets kexec-tools et makedumpfile en amont. Il est un passionné de l'open source et fait la promotion des logiciels libres en donnant des conférences bénévoles dans des établissements d'enseignement.


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer