固件辅助转储¶
2011年7月
固件辅助转储的目标是启用崩溃系统的转储,并从完全重置的系统执行此操作,并最大限度地缩短系统恢复生产使用之前的总耗时。
固件辅助转储 (FADump) 基础设施旨在取代现有的 phyp 辅助转储。
Fadump 使用与 phyp 辅助转储相同的固件接口和内存预留模型。
与 phyp 转储不同,FADump 通过 /proc/vmcore 以 ELF 格式导出内存转储,方式与 kdump 相同。这有助于我们重用 kdump 基础设施进行转储捕获和筛选。
与 phyp 转储不同,用户空间工具在读取 /proc/vmcore 时无需引用任何 sysfs 接口。
与 phyp 转储不同,FADump 允许用户通过单个操作 echo 1 > /sys/kernel/fadump_release_mem 来释放为转储预留的所有内存。
通过内核启动参数启用后,可以通过 /sys/kernel/fadump_registered 接口(请参阅下面的 sysfs 文件部分)启动/停止 FADump,并且可以轻松地与 kdump 服务启动/停止 init 脚本集成。
与 kdump 或其他策略相比,固件辅助转储具有以下几个强大的实际优势
与 kdump 不同,系统已重置,并加载了内核的全新副本。特别是,PCI 和 I/O 设备已重新初始化,并且处于干净、一致的状态。
一旦复制出转储,保存转储的内存会立即提供给正在运行的内核。因此,与 kdump 不同,FADump 不需要第二次重启即可使系统恢复到生产配置。
以上只能通过与 Power 固件协调并获得其帮助来实现。该过程如下
第一个内核在 OS 初始化期间向 Power 固件注册内存的各个部分,以便在转储期间保留。这些已注册的内存部分在早期启动期间由第一个内核保留。
当系统崩溃时,Power 固件会将已注册的低内存区域(引导内存)从源区域复制到目标区域。它还会保存硬件 PTE。
- 注意
术语“引导内存”是指在以受限内存引导时内核成功引导所需的低内存块大小。默认情况下,引导内存大小将是系统 RAM 的 5% 或 256MB 中的较大者。或者,用户还可以通过引导参数 ‘crashkernel=’ 指定引导内存大小,这将覆盖默认计算的大小。如果默认引导内存大小不足以使第二个内核成功引导,请使用此选项。有关 crashkernel= 参数的语法,请参阅 Kdump 文档 - 基于 kexec 的崩溃转储解决方案。如果在 crashkernel= 参数中提供了任何偏移量,则会将其忽略,因为在发生崩溃时,FADump 使用预定义的偏移量来保留引导内存转储保存的内存。
保存低内存(引导内存)区域后,固件将重置 PCI 和其他硬件状态。它会不清除 RAM。然后,它将像往常一样启动引导加载程序。
新启动的内核会注意到设备树中有一个新节点 (rtas/ibm,kernel-dump on pSeries 或 ibm,opal/dump/mpipl-boot on OPAL platform),这表明有来自先前启动的崩溃数据可用。在早期引导期间,OS 将保留引导内存大小以上的其余内存,从而有效地以受限内存大小启动。这将确保此内核(也称为第二个内核或捕获内核)不会接触任何转储内存区域。
用户空间工具将读取 /proc/vmcore 以获取内存内容,该内容以 ELF 格式保存先前崩溃的内核转储。用户空间工具可以将此信息复制到磁盘、网络、NAS、SAN、iSCSI 等,按需进行。
一旦用户空间工具完成保存转储,它将向 /sys/kernel/fadump_release_mem 发送“1”,以将保留的内存释放回常规使用,除了下次固件辅助转储注册所需的内存。
例如。
# echo 1 > /sys/kernel/fadump_release_mem
请注意,固件辅助转储功能仅在 pSeries (PowerVM) 平台上的 POWER6 及更高版本的系统以及 PowerNV (OPAL) 平台上具有 OP940 或更高版本固件的 POWER9 及更高版本的系统上可用。请注意,当 PowerNV 平台上支持 FADump 时,OPAL 固件会导出 ibm,opal/dump 节点。
在基于 OPAL 的计算机上,系统首先启动到一个中间内核(称为 petitboot 内核),然后再启动到捕获内核。此内核将具有最少的内核和/或用户空间支持来处理崩溃数据。此类内核需要为后续捕获内核引导保留先前崩溃内核的内存,以便处理此崩溃数据。必须在此类内核上启用内核配置选项 CONFIG_PRESERVE_FA_DUMP,以确保保留崩溃数据以便稍后处理。
- -- 在基于 OPAL 的计算机 (PowerNV) 上,如果使用以下方式构建内核
CONFIG_OPAL_CORE=y,崩溃时的 OPAL 内存也会导出为 /sys/firmware/opal/mpipl/core 文件。此 procfs 文件有助于使用 GDB 调试 OPAL 崩溃。用于导出此 procfs 文件的内核内存可以通过向 /sys/firmware/opal/mpipl/release_core 节点发送“1”来释放。
- 例如。
# echo 1 > /sys/firmware/opal/mpipl/release_core
实现细节:¶
在启动期间,会进行检查以查看固件是否在该特定计算机上支持此功能。如果支持,则我们检查以查看是否有活动的转储正在等待我们。如果有,那么除了 RAM 的引导内存大小之外的所有内容都会在早期启动期间保留(参见图 2)。一旦我们完成从运行的用户领域脚本(例如,kdump 脚本)收集转储,就会释放该区域。如果有转储数据,则会创建 /sys/kernel/fadump_release_mem 文件,并且会保留保留的内存。
如果没有等待转储数据,则通常只会在大于引导内存大小的偏移量处保留用于保存 CPU 状态、HPTE 区域、引导内存转储和 FADump 标头的内存(参见图 1)。此区域不释放:此区域将永久保留,以便在发生崩溃时,它可以充当引导内存内容的副本以及 CPU 状态和 HPTE 区域的容器。
由于此保留的内存区域仅在系统崩溃后使用,因此阻止生产内核使用此重要的内存块没有任何意义。因此,如果为内核配置了 CMA,则实现会使用 Linux 内核的连续内存分配器 (CMA) 进行内存预留。通过 CMA 预留,此内存将可供应用程序使用,同时会阻止内核使用它。使用此方法,FADump 仍然能够捕获所有内核内存和大部分用户空间内存,除了 CMA 区域中存在的用户页面。
o Memory Reservation during first kernel
Low memory Top of memory
0 boot memory size |<------ Reserved dump area ----->| |
| | | Permanent Reservation | |
V V | | V
+-----------+-----/ /---+---+----+-----------+-------+----+-----+
| | |///|////| DUMP | HDR |////| |
+-----------+-----/ /---+---+----+-----------+-------+----+-----+
| ^ ^ ^ ^ ^
| | | | | |
\ CPU HPTE / | |
-------------------------------- | |
Boot memory content gets transferred | |
to reserved area by firmware at the | |
time of crash. | |
FADump Header |
(meta area) |
|
|
Metadata: This area holds a metadata structure whose
address is registered with f/w and retrieved in the
second kernel after crash, on platforms that support
tags (OPAL). Having such structure with info needed
to process the crashdump eases dump capture process.
Fig. 1
o Memory Reservation during second kernel after crash
Low memory Top of memory
0 boot memory size |
| |<------------ Crash preserved area ------------>|
V V |<--- Reserved dump area --->| |
+----+---+--+-----/ /---+---+----+-------+-----+-----+-------+
| |ELF| | |///|////| DUMP | HDR |/////| |
+----+---+--+-----/ /---+---+----+-------+-----+-----+-------+
| | | | | |
----- ------------------------------ ---------------
\ | |
\ | |
\ | |
\ | ----------------------------
\ | /
\ | /
\ | /
/proc/vmcore
+---+
|///| -> Regions (CPU, HPTE & Metadata) marked like this in the above
+---+ figures are not always present. For example, OPAL platform
does not have CPU & HPTE regions while Metadata region is
not supported on pSeries currently.
+---+
|ELF| -> elfcorehdr, it is created in second kernel after crash.
+---+
Note: Memory from 0 to the boot memory size is used by second kernel
Fig. 2
当前,转储将通过用户干预从 /proc/vmcore 复制到新文件。通过 /proc/vmcore 提供的转储数据将为 ELF 格式。因此,现有的 kdump 基础设施(kdump 脚本)可以正常工作,只需进行少量修改即可保存转储。当使用 FADump 而不是 KDump 作为转储机制时,主要的发行版上的 KDump 脚本已经过修改,可以无缝工作(保存转储时无需用户干预)。
用于检查转储的工具将与用于 kdump 的工具相同。
如何启用固件辅助转储 (FADump):¶
设置配置选项 CONFIG_FA_DUMP=y 并构建内核。
使用 ‘fadump=on’ 内核 cmdline 选项启动到 Linux 内核。默认情况下,FADump 保留的内存将初始化为 CMA 区域。或者,用户可以使用 ‘fadump=nocma’ 启动 Linux 内核以阻止 FADump 使用 CMA。
(可选)用户还可以设置 ‘crashkernel=’ 内核 cmdline 来指定为引导内存转储保存预留的内存大小。
- 注意
‘fadump_reserve_mem=’ 参数已弃用。请改为使用 ‘crashkernel=’ 来指定为引导内存转储保存预留的内存大小。
如果固件辅助转储无法保留内存,则如果 ‘crashkernel=’ 选项在内核 cmdline 中设置,则将回退到现有的 kdump 机制。
如果用户想要捕获所有用户空间内存,并且可以接受保留的内存对生产系统不可用,则可以使用 ‘fadump=nocma’ 内核参数回退到旧的行为。
Sysfs/debugfs 文件:¶
固件辅助转储功能使用 sysfs 文件系统来保存控制文件,并使用 debugfs 文件来显示保留的内存区域。
以下是内核 sysfs 下的文件列表
- /sys/kernel/fadump_enabled
这用于显示 FADump 状态。
0 = FADump 已禁用
1 = FADump 已启用
kdump 初始化脚本可以使用此接口来识别内核中是否启用了 FADump,并采取相应的操作。
- /sys/kernel/fadump_registered
此文件用于显示 FADump 的注册状态,以及控制(启动/停止)FADump 的注册。
0 = FADump 未注册。
1 = FADump 已注册并准备好处理系统崩溃。
要注册 FADump,请执行 echo 1 > /sys/kernel/fadump_registered;要取消注册并停止 FADump,请执行 echo 0 > /sys/kernel/fadump_registered。一旦 FADump 被取消注册,系统崩溃将不会被处理,并且 vmcore 也不会被捕获。此接口可以轻松地与 kdump 服务启动/停止集成。
/sys/kernel/fadump/mem_reserved
此文件用于显示 FADump 为保存崩溃转储而保留的内存。
- /sys/kernel/fadump_release_mem
仅当 FADump 在第二个内核运行时处于活动状态时,此文件才可用。此文件用于释放为保存崩溃转储而保留的内存区域。要释放保留的内存,请执行 echo 1 > 该文件。
echo 1 > /sys/kernel/fadump_release_mem执行 echo 1 后,/sys/kernel/debug/powerpc/fadump_region 文件的内容将发生更改,以反映新的内存预留情况。
现有的用户空间工具(kdump 基础设施)可以很容易地得到增强,以使用此接口释放为转储预留的内存,并继续运行,而无需进行第二次重启。
- 注意:/sys/kernel/fadump_release_opalcore sysfs 已移动到
/sys/firmware/opal/mpipl/release_core
/sys/firmware/opal/mpipl/release_core
仅当 FADump 在捕获内核期间处于活动状态时,此文件才在基于 OPAL 的机器上可用。此文件用于释放内核用于导出 /sys/firmware/opal/mpipl/core 文件所使用的内存。要释放此内存,请执行 echo '1' > 该文件。
echo 1 > /sys/firmware/opal/mpipl/release_core
注意:以下 FADump sysfs 文件已弃用。
已弃用 |
替代方案 |
/sys/kernel/fadump_enabled |
/sys/kernel/fadump/enabled |
/sys/kernel/fadump_registered |
/sys/kernel/fadump/registered |
/sys/kernel/fadump_release_mem |
/sys/kernel/fadump/release_mem |
以下是 powerpc debugfs 下的文件列表:(假设 debugfs 已挂载在 /sys/kernel/debug 目录中。)
- /sys/kernel/debug/powerpc/fadump_region
如果启用了 FADump,此文件将显示保留的内存区域;否则,此文件为空。输出格式为
<region>: [<start>-<end>] <reserved-size> bytes, Dumped: <dump-size>对于内核转储区域,格式为
DUMP: Src: <源地址>, Dest: <目标地址>, Size: <大小>, Dumped: # 字节
例如:在第一个内核期间注册 FADump 时,内容如下:
# cat /sys/kernel/debug/powerpc/fadump_region CPU : [0x0000006ffb0000-0x0000006fff001f] 0x40020 bytes, Dumped: 0x0 HPTE: [0x0000006fff0020-0x0000006fff101f] 0x1000 bytes, Dumped: 0x0 DUMP: [0x0000006fff1020-0x0000007fff101f] 0x10000000 bytes, Dumped: 0x0在第二个内核期间 FADump 处于活动状态时,内容如下:
# cat /sys/kernel/debug/powerpc/fadump_region CPU : [0x0000006ffb0000-0x0000006fff001f] 0x40020 bytes, Dumped: 0x40020 HPTE: [0x0000006fff0020-0x0000006fff101f] 0x1000 bytes, Dumped: 0x1000 DUMP: [0x0000006fff1020-0x0000007fff101f] 0x10000000 bytes, Dumped: 0x10000000 : [0x00000010000000-0x0000006ffaffff] 0x5ffb0000 bytes, Dumped: 0x5ffb0000
- 注意
请参阅 DebugFS,了解如何挂载 debugfs 文件系统。
TODO:¶
需要提出更好的方法,以在受限内存启动时,找出内核成功启动所需的更准确的引导内存大小。
作者:Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
本文档基于 Linas Vepstas 和 Manish Ahuja 为 phyp 辅助转储编写的原始文档。
辅助转储 by Linas Vepstas 和 Manish Ahuja.