固件辅助转储

2011年7月

固件辅助转储的目标是实现崩溃系统的转储,并且通过完全重置的系统来完成,同时将系统恢复投入生产使用所需的总耗时降至最低。

  • 固件辅助转储 (FADump) 基础设施旨在取代现有的 phyp 辅助转储。

  • Fadump 使用与 phyp 辅助转储相同的固件接口和内存预留模型。

  • 与 phyp 转储不同,FADump 以与 kdump 相同的方式通过 /proc/vmcore 以 ELF 格式导出内存转储。这有助于我们复用 kdump 基础设施来进行转储捕获和过滤。

  • 与 phyp 转储不同,用户空间工具在读取 /proc/vmcore 时无需引用任何 sysfs 接口。

  • 与 phyp 转储不同,FADump 允许用户通过单次操作 echo 1 > /sys/kernel/fadump_release_mem 来释放为转储预留的所有内存。

  • 一旦通过内核启动参数启用,FADump 就可以通过 /sys/kernel/fadump_registered 接口(参见下文 sysfs 文件部分)进行启动/停止,并且可以轻松地与 kdump 服务的启动/停止初始化脚本集成。

与 kdump 或其他策略相比,固件辅助转储具有几个强大而实用的优势

  • 与 kdump 不同,系统已被重置,并加载了全新复制的内核。特别是,PCI 和 I/O 设备已重新初始化,处于干净、一致的状态。

  • 转储复制完成后,保存转储的内存立即可供运行中的内核使用。因此,与 kdump 不同,FADump 不需要第二次重启即可将系统恢复到生产配置。

上述操作只能通过与 Power 固件的协调和协助来完成。步骤如下

  • 第一个内核在操作系统初始化期间向 Power 固件注册内存区域以保存转储。这些注册的内存区域由第一个内核在早期引导阶段预留。

  • 当系统崩溃时,Power 固件会将注册的低内存区域(引导内存)从源区域复制到目标区域。它还将保存硬件 PTE。

    注意

    术语“引导内存”是指在受限内存下引导时,内核成功引导所需的低内存块大小。默认情况下,引导内存大小为系统 RAM 的 5% 或 256MB 中的较大者。或者,用户也可以通过引导参数 ‘crashkernel=’ 指定引导内存大小,这将覆盖默认计算的大小。如果默认引导内存大小不足以让第二个内核成功引导,请使用此选项。有关 crashkernel= 参数的语法,请参考 Kdump 文档 - 基于 kexec 的崩溃转储解决方案。如果在 crashkernel= 参数中提供了任何偏移量,它将被忽略,因为 FADump 使用预定义的偏移量来预留内存,以便在发生崩溃时保存引导内存转储。

  • 保存低内存(引导内存)区域后,固件将重置 PCI 和其他硬件状态。它不会清除 RAM。然后,它将像往常一样启动引导加载程序。

  • 刚引导的内核会注意到设备树中有一个新节点(pSeries 上的 rtas/ibm,kernel-dump 或 OPAL 平台上的 ibm,opal/dump/mpipl-boot),表明有来自前一次引导的可用崩溃数据。在早期引导期间,操作系统将预留引导内存大小之上的其余内存,从而有效地以受限内存大小进行引导。这将确保该内核(也称为第二个内核或捕获内核)不会触及任何转储内存区域。

  • 用户空间工具将读取 /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 崩溃。通过向 /sys/firmware/opal/mpipl/release_core 节点写入 ‘1’,可以释放用于导出此 procfs 文件的内核内存。

例如:

# echo 1 > /sys/firmware/opal/mpipl/release_core

-- 支持 Fadump 中的附加内核参数

Fadump 具有一项允许向 fadump 内核传递附加内核参数的功能。此功能的主要设计目的是禁用 fadump 内核不需要的内核功能,并在收集转储时减少其内存占用。

向 Fadump 添加附加内核参数的命令:例如 # echo “nr_cpus=16” > /sys/kernel/fadump/bootargs_append

上述命令足以向 fadump 添加附加参数。不需要显式重启服务。

检索附加 Fadump 参数的命令:例如 # cat /sys/kernel/fadump/bootargs_append

注意:带有 HASH MMU 的 fadump 的附加内核参数仅

在 RMA 大小大于 768 MB 时受支持。如果 RMA 大小小于 768 MB,内核将不会导出 /sys/kernel/fadump/bootargs_append sysfs 节点。

实现细节:

在引导期间,会进行检查以查看固件是否在该特定机器上支持此功能。如果支持,我们会检查是否有活动的转储在等待我们处理。如果是,则在早期引导期间预留除引导内存大小之外的所有 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 脚本)只需进行微小的修改即可正常工作。主流发行版上的 KDump 脚本已经过修改,当使用 FADump 代替 KDump 作为转储机制时,可以无缝工作(保存转储时无需用户干预)。

检查转储的工具将与 kdump 使用的工具相同。

如何启用固件辅助转储 (FADump):

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

  2. 使用 ‘fadump=on’ 内核命令行选项引导进入 linux 内核。默认情况下,FADump 预留内存将被初始化为 CMA 区域。或者,用户可以使用 ‘fadump=nocma’ 引导 linux 内核以阻止 FADump 使用 CMA。

  3. 可选地,用户还可以设置 ‘crashkernel=’ 内核命令行来指定为保存引导内存转储而预留的内存大小。

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

  2. 如果固件辅助转储未能预留内存,且内核命令行中设置了 ‘crashkernel=’ 选项,它将回退到现有的 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 在第二个内核期间处于活动状态时可用。它用于释放为保存崩溃转储而持有的预留内存区域。要释放预留内存,请向其写入 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

此文件仅在基于 OPAL 的机器上且 FADump 在捕获内核期间处于活动状态时可用。它用于释放内核用于导出 /sys/firmware/opal/mpipl/core 文件的内存。要释放此内存,请向其写入 ‘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 区域,格式为

DUMP: Src: <src-addr>, Dest: <dest-addr>, Size: <size>, Dumped: # bytes

例如:在第一个内核期间注册 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

待办事项:

  • 需要想出更好的方法,来找出内核在受限内存下成功引导所需的更准确的引导内存大小。

作者:Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

本文档基于由 Linas Vepstas 和 Manish Ahuja 为 phyp

辅助转储编写的原始文档。