Pengenalan | kdump ialah satu cara untuk mendapatkan dump kernel Linux yang ranap, tetapi agak sukar untuk mencari dokumentasi yang menerangkan penggunaan dan dalamannya. Dalam artikel ini, saya akan mengkaji penggunaan asas kdump dan bagaimana kdump/kexec dilaksanakan dalam kernel. |
kexec ialah pemuat but kernel-ke-kernel Linux yang membantu but daripada konteks kernel pertama kepada kernel kedua. kexec menutup teras pertama, memintas peringkat BIOS atau perisian tegar, dan melompat ke teras kedua. Oleh itu, but semula menjadi lebih pantas tanpa peringkat BIOS.
kdump boleh digunakan dengan aplikasi kexec - contohnya, apabila kernel pertama ranap dan kernel kedua dimulakan, kernel kedua digunakan untuk menyalin pembuangan memori kernel pertama, yang boleh dianalisis menggunakan alat seperti gdb dan kemalangan Punca kemalangan. (Dalam artikel ini, saya akan menggunakan istilah "inti pertama" sebagai kernel yang sedang berjalan, "inti kedua" sebagai kernel yang berjalan dengan kexec , dan "inti tangkap" bermaksud kernel yang berjalan apabila kernel semasa ranap.)
Mekanisme kexec mempunyai komponen dalam kernel serta ruang pengguna. Kernel menyediakan beberapa panggilan sistem untuk kefungsian restart kexec. Alat ruang pengguna yang dipanggil kexec-tools menggunakan panggilan ini dan menyediakan fail boleh laku untuk memuatkan dan but "kernel kedua". Sesetengah pengedaran juga menambah pembalut pada alat kexec, yang membantu menangkap dan menyimpan pembuangan pelbagai konfigurasi sasaran pembuangan. Dalam artikel ini, saya akan menggunakan alat yang dipanggil distro-kexec-tools untuk mengelakkan kekeliruan antara alat kexec huluan dan kod alat kexec khusus pengedaran. Contoh saya akan menggunakan pengedaran Fedora Linux.
Fedora kexec-tools toolGunakan perintah dnf install kexec-tools untuk memasang fedora-kexec-tools pada mesin Fedora. Selepas memasang fedora-kexec-tools, anda boleh melaksanakan perintah systemctl start kdump untuk memulakan perkhidmatan kdump. Apabila perkhidmatan ini bermula, ia mencipta sistem fail akar (initramfs) yang mengandungi sumber untuk dipasang ke lokasi sasaran, untuk memegang vmcore, dan arahan untuk menyalin dan membuang vmcore ke lokasi sasaran. Perkhidmatan ini kemudiannya memuatkan kernel dan initramfs ke lokasi yang sesuai dalam kawasan kernel yang ranap supaya ia boleh dilaksanakan jika kernel ranap.
Pembungkus Fedora menyediakan dua profil pengguna:
/etc/kdump.conf menentukan parameter konfigurasi yang perlu dibina semula selepas pengubahsuaian. Contohnya, jika anda menukar sasaran pembuangan daripada cakera setempat kepada cakera yang dipasang NFS, anda memerlukan modul kernel berkaitan NFS yang dimuatkan oleh Capture Kernel.
/etc/sysconfig/kdump menentukan parameter konfigurasi yang tidak memerlukan membina semula initramfs selepas pengubahsuaian. Sebagai contoh, jika anda hanya perlu mengubah suai parameter baris arahan yang dihantar kepada "irung tangkap", anda tidak perlu membina semula initramfs.
Jika kernel gagal selepas perkhidmatan kdump dimulakan, maka "irung tangkapan" dilakukan, yang selanjutnya melaksanakan proses simpan vmcore dalam initramfs dan kemudian but semula ke kernel yang stabil.
Kompilkan kod sumber alat kexec dan dapatkan fail boleh laku bernama kexec. Boleh laku eponim ini boleh digunakan untuk memuatkan dan melaksanakan "inti kedua", atau memuatkan "inti tangkap", yang boleh dilaksanakan apabila kernel ranap.
Arahan untuk memuatkan "inti kedua":
# kexec -l kernel.img --initrd=initramfs-image.img –reuse-cmdline
--reuse-command parameter bermaksud menggunakan baris arahan yang sama seperti "kernel pertama". Gunakan --initrd untuk lulus initramfs. -l menunjukkan bahawa anda sedang memuatkan "kernel kedua" yang boleh dilaksanakan oleh aplikasi kexec itu sendiri (kexec -e). Inti yang dimuatkan dengan -l tidak boleh dilaksanakan pada panik kernel. Untuk memuatkan "inti tangkap" yang boleh dilaksanakan pada ranap kernel, parameter -p mesti diluluskan dan bukannya -l.
Arahan untuk memuatkan kernel tangkapan:
# kexec -p kernel.img --initrd=initramfs-image.img –reuse-cmdline
echo c > /pros/sysrq-trigger boleh digunakan untuk merosakkan kernel untuk ujian. Untuk maklumat lanjut tentang pilihan yang disediakan oleh kexec-tools, lihat man kexec. Sebelum beralih ke bahagian seterusnya, lihat demo kexec_dump ini:
Gambar di bawah menunjukkan carta alir. Memori crashkernel mesti dikhaskan untuk kernel tangkapan semasa but "kernel pertama". Anda boleh menghantar crashkernel=Y@X pada baris arahan kernel, di mana @X adalah pilihan. crashkernel=256M berfungsi untuk kebanyakan sistem x86_64, bagaimanapun, memilih memori yang sesuai untuk crashkernel bergantung pada banyak faktor, seperti saiz kernel dan initramf, serta modul yang terkandung dalam initramfs dan keperluan memori masa jalan aplikasi. Lihat dokumentasi kernel-parameters untuk lebih banyak cara untuk lulus parameter kernel ranap.
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 或“捕获内核”之前,会执行以下操作:
kdump 中涉及的大多数转储核心都是 ELF 格式。因此,理解 ELF 程序头部很重要,特别是当您想要找到 vmcore 准备的问题。每个 ELF 文件都有一个程序头:
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 的表示:
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 noteCrash notes 是每个 CPU 中用于在系统崩溃的情况下存储 CPU 状态的区域;它有关于当前 PID 和 CPU 寄存器的信息。
vmcoreinfo该 note 段具有各种内核调试信息,如结构体大小、符号值、页面大小等。这些值由捕获内核解析并嵌入到 /proc/vmcore 中。 vmcoreinfo 主要由 makedumpfile 应用程序使用。在 Linux 内核,include/linux/kexec.h 宏定义了一个新的 vmcoreinfo。 一些示例宏如下所示:
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 没有成功检查是否分配了崩溃内存。
(Tajuk: Penguin, Boot, pengubahsuaian: Opensource.com. CC BY-SA 4.0)
Mengenai pengarang:
Pratyush Anand - Pratyush bekerja dengan Red Hat sebagai pakar kernel Linux. Dia bertanggungjawab untuk beberapa isu kexec/kdump yang dihadapi oleh produk Red Hat dan huluan. Dia juga mengendalikan isu penyahpepijatan, pengesanan dan prestasi kernel lain di sekitar platform ARM64 yang disokong oleh Red Hat. Sebagai tambahan kepada kernel Linux, beliau telah menyumbang kepada projek kexec-tools huluan dan makedumpfile. Beliau adalah peminat sumber terbuka dan mempromosikan FOSS dengan memberikan syarahan sukarela di institusi pendidikan.
Atas ialah kandungan terperinci Alat pengesan ranap kernel Linux Kdump. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!