固件辅助转储

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):

  1. 设置配置选项 CONFIG_FA_DUMP=y 并构建内核。

  2. 使用 ‘fadump=on’ 内核 cmdline 选项启动到 Linux 内核。默认情况下,FADump 保留的内存将初始化为 CMA 区域。或者,用户可以使用 ‘fadump=nocma’ 启动 Linux 内核以阻止 FADump 使用 CMA。

  3. (可选)用户还可以设置 ‘crashkernel=’ 内核 cmdline 来指定为引导内存转储保存预留的内存大小。

注意
  1. ‘fadump_reserve_mem=’ 参数已弃用。请改为使用 ‘crashkernel=’ 来指定为引导内存转储保存预留的内存大小。

  2. 如果固件辅助转储无法保留内存,则如果 ‘crashkernel=’ 选项在内核 cmdline 中设置,则将回退到现有的 kdump 机制。

  3. 如果用户想要捕获所有用户空间内存,并且可以接受保留的内存对生产系统不可用,则可以使用 ‘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.