IBM AIX RAS – 通过固件协助的实时转储(Dump)工具简介

本文将介绍为获得稳健的系统转储而构建的高级 IBM® AIX® 转储工具。更具体地说,本文将讨论固件协助(firmware-assisted)的实时转储工具的各个方面内容。文中提供了对可靠性、可用性和可服务性 (RAS) 基础架构的实时转储内核服务的详细信息,还提供了在捕获组件或驱动程序数据的实时转储时需要考虑的各种选项或替代方法。本文还通过一个内核扩展示例对实时转储工具进行了说明。

Premkumar Nagarajan, 资深系统工程师, IBM

Premkumar Nagarajan 是效力于 IBM AIX RAS 开发团队的一名资深系统工程师。他目前在研究实现 AIX 的可靠性、可用性和可服务性 (RAS) 功能的各种特性。在加入 IBM 之前,他研究过各种存储和网络技术,参与过各种核心内核组件开发活动。



2013 年 7 月 15 日

固件协助转储的概述

通过重新引导分区并使用一个新内核从前一次内核崩溃转储数据,与传统的转储类型相比,固件协助转储提高了可靠性。

固件协助转储需要:

  • 一个基于 IBM POWER6 或更高版本处理器的硬件平台。
  • 一个至少具有 1.5 GB 内存的逻辑分区 (LPAR)。
  • 根卷组 (rootvg) 中的一个转储逻辑卷。
  • 分页空间,不能将它定义为转储逻辑卷

当启动一个为固件协助转储而配置的分区时,称为擦除区(scratch area) 的内存部分会分配给固件协助转储功能供其使用。出于这个原因,需要重新启动配置为传统系统转储的分区,才能分配进行固件协助转储所需的擦除区内存。固件有助于保留要转储的页面,直到非故障 OS 正常启动。非故障 OS 将完成将保留的内存复制到转储文件的过程。

固件协助转储的错误代码

引导加载器开始将数据写入转储逻辑块中,只要将转储逻辑块中的数据写入转储逻辑卷,占用的空间就会立即释放。如果释放了一定比例的主要内存,就可以引导 AIX。从那时起,AIX 会接管控制权,将转储逻辑块中的剩余数据写入转储逻辑卷。

在此过程中,引导加载器和 AIX 会向控制台通知固件协助转储的进度。

以下是用于固件协助转储的发光二极管 (LED) 代码:


0c0 – 表示固件协助转储成功完成

sysdumpdev -l – 用于检查来自 OS 的实际错误代码。

实时转储

实时转储 功能允许在不关闭整个系统的情况下转储故障数据。实时转储的两个最常见的用途可能包括以下场景:

  • 系统管理员从命令行发出 livedumpstart 命令,转储与故障相关的数据。
  • 在恢复时,子系统需要在恢复之前转储与故障相关的数据。此功能只可用于内核和内核扩展。

序列化转储和非序列化转储

序列化的实时转储在转储数据时会导致系统冻结或暂停。在系统冻结后,会将数据复制到内核锁定的内存中,只有系统解冻之后,才能将它们写入文件系统。非序列化的转储指在不冻结系统的情况下执行转储。

系统因为停止除转储处理器外的所有处理器而冻结。然后转储处理器在 INTMAX(最喜欢的中断优先级)级别上捕获转储数据。应该注意的是,在系统冻结时,不允许出现页面故障。

同步和异步实时转储

同步实时转储中,调用方等待完成针对此转储的数据收集,而在异步实时转储中,调用方会调度要执行的转储,而不会等待它完成。

转储位置

在实时转储过程 (live dump pass) 期间捕获的数据会排队进入实时转储进程。当系统解冻时,此进程会将数据写入文件系统。默认情况下,实时转储位于 /var/adm/ras/livedump 目录中。转储文件名具有以下命名规则:[prefix.]component.yyyymmddhhmm.xx.DZ

实时转储堆内存(heap memory)

用于实时转储的固定内核内存位于单独的实时转储堆中。默认情况下,这个堆最大为 64 MB。这个堆不得大于实际内存大小的 1/16。

实时转储过程

序列化的实时转储可在一个过程中发生,也可在多个过程中发生。转储过程包含可在系统冻结时缓存到固定存储中的数据。包含多个过程的转储包含多次系统冻结,因此多过程转储中的数据可能不一致。实时转储可由内核或内核扩展以软件的方式发起。将要包含在转储中的所有组件都必须使用 ras_register() 向内核注册,以便感知转储。它们还必须表明它们是通过使用 RASCD_SET_LDMP_ON ras_control() 服务来处理实时转储。

组件内核水平和最大缓冲区大小

下面的列表显示了一个组件的数据限制。如果组件的数据超出这些限制,该数据就会被截断,仅存储导致超出限制的数据项之前的数据项。

下面的列表指定了每个实时转储细节水平所允许的最大数据量

  • < CD_LVL_NORMAL - 2 MB
  • >= CD_LVL_NORMAL and < CD_LVL_DETAIL - 4 MB
  • >= CD_LVL_DETAIL and < CD_LEVEL_9 - 8 MB
  • CD_LEVEL_9 - 无限制(实际内存的/16)

从软件执行实时转储:

  • 使用 ldmp_setupparms() 初始化一个 ldmp_parms_t 项。

这会设置数据结构,填入所有默认值,包括引人注目的内容和版本字段。

  • 使用 dmp_compspec() 指定组件和伪组件。

这是指定转储的内容的方式。

  • 使用 livedump() 内核服务创建转储。

这将执行转储。

以上的操作会在结尾的实力中演示。

伪组件

转储伪组件是一种服务例程,用于转储与组件无关的数据。这些伪组件(比如内核上下文、线程、进程等)仅限于在某个转储内使用。

暂存缓冲区

组件可以请求获得暂存缓冲区中的空间,以便在系统转储或实时转储期间使用。对于系统转储,一个组件可分配一个私有 (RASCD_SET_SDMP_STAGING) 或共享暂存缓冲区 (RASCD_SET_SDMP_SHARED_STAGING)。如果将缓冲区用于要转储的实际数据(比如某个设备的微代码或日志),那么私有暂存缓冲区必不可少。如果缓冲区仅用于转储元数据,比如组件的转储表,那么可以使用共享的暂存缓冲区。

通过回调执行实时转储序列

参与实时转储的组件必须提供一个回调例程来处理以下 ras_control() 命令。收到回调命令后,回调发出 "_SET" 命令来执行操作。请参阅示例扩展,特别留意 sample_callback() 函数。

RASCD_LDMP_PREPARE (用于准备执行实时转储

在要求回调参与实时转储时,该回调会收到此转储。如果有必要,回调可使用 dmp_compspec() 指定将包含在转储中的其他组件。它还可以指定伪组件,比如 dmp_eaddr()。它必须返回将要转储的数据的估计量。这个估计量应该是最大量,应该包含转储表所占用的空间,不应包含其他组件或伪组件转储的内存。例如,如果 prepare 函数使用 dmp_ct() 来转储组件轨迹数据,那么 dmp_ct() 伪组件将提供该估计量。

RASCD_LDMP_START(用于转储数据)

展示回调在提供用于转储的数据时收到的命令。回调将它的转储表地址放在以参数形式接收的 ldmp_start_t 数据项的 ldmpst_table 字段中。回调接收后续的 RASCD_LDMP_AGAIN 调用来提供更多数据。这个过程会在回调返回一个 NULL 转储表指针时停止。

RASCD_LDMP_FINISHED-这个命令表明转储已完成。同样地,没有转储该组件的任何数据。

RASCD_LDMP_AGAIN-RASCD_LDMP_AGAIN 命令提供了更多数据。返回代码的处理方式与 RASCD_LDMP_START 相同,但是,如果返回一个小于 0 的值,则不会继续转储组件的数据,但以前的 RASCD_LDMP_STARTRASCD_LDMP_AGAIN 调用已经转储的数据会出现在转储中。

RASCD_LDMP_FINISHED-此命令表明实时转储已完成。

RASCD_DMP_PASS_THROUGH - 此命令将任意文本数据传递给回调。

请注意,RASCD_DMP_PASS_THROUGH 可应用于整个转储域,(也就是说)包含实时转储和系统转储的域只有一个转储过程。您可以使用 dumpctrl 将数据传递给某个组件的 RASCD_DMP_PASS_THROUGH 处理函数。

例如,以下命令

dumpctrl -l foo "pass through text" "pass through text" 传递到具有别名 foo 的组件的 RASCD_DMP_PASS_THROUGH 处理函数

RASCD_LDMP_ESTIMATE -此命令提供将转储的数据的估计量。

实时转储具有一些限制

  • 组件可转储的内容受到细节水平的限制。
  • 因为实时转储可在系统冻结时执行,所以在转储期间,只有一组有限的系统服务可供组件回调使用,例如轻量型内存轨迹和组件轨迹。

组件可以指定要转储的任何数据,但在序列化的转储中,仅转储位于内存中的数据。

实时转储数据需求的考虑因素

多个过程

如果一个组件需要转储更多数据,并且无法在一次冻结过程中转储,那么将会为该组件提供多个过程。数据可通过暂存缓冲区在多个过程中暂存,但在解冻和下一次冻结时,数据可能发生更改。如果在一个中断的环境中执行序列化转储,则允许对组件执行单个转储过程。这可以通过组件中的 RASCD_LDMP_AGAIN 回调实现。

冻结时间

在执行实时转储时,如果系统冻结事件超过 100 毫秒(0.1 秒),则会记录一个告知性错误。让转储回调执行路径尽可能得短非常重要,尤其在为转储提供数据时。如果我们检测到系统已冻结了 5000 毫秒(也就是 5 秒),那么转储会在这个时刻截断,系统会解冻。

堆分配错误

有时,组件尝试执行转储的次数可能超出了相应水平所允许的限制。所以组件应负责增加私有暂存缓冲区,使用多个过程来转储组件的更多数据(对于中断环境中运行的驱动程序,这一点行不通)。

示例

以下是一个执行实时转储和系统转储的示例内核扩展。其中的重要函数是 sample_callback(),它使用系统发送的 ras_control() 命令执行转储。请注意,我仅展示了转储命令的处理。正常情况下,此回调还将处理组件轨迹和错误检查命令。

示例扩展的后面是一个简单的语句序列,这些语句用于从软件执行 sample_comp 的实时转储。

#include <sys/types.h>
#include <sys/syspest.h>
#include <sys/uio.h>
#include <sys/processor.h>
#include <sys/systemcfg.h>
#include <sys/malloc.h>
#include <sys/ras.h>
#include <sys/livedump.h>
#include <sys/eyec.h>
#include <sys/raschk.h>
#include <sys/param.h>
#include <sys/dump.h>

/* RAS conmtrol block for the component */
ras_block_t rascb=NULL;

/* Data to include in livedump */

typedef struct sample_data {
char *dev;
int flag;
} sample_data_t;

sample_data_t *data;

/* componet callback */

kerrno_t sample_livedump_callback(ras_block_t cb, ras_cmd_t cmd, void *arg, void *priv);
void sample_initiate_livedump();

/*
* Entry point called when this kernel extension is loaded.
*
* Input:
* cmd - 1=config, 2=unconfig)
* uiop - points to the uio structure.
*/
int
sampleext(int cmd, struct uio *uiop)
{
kerrno_t rv = 0;
int rc,len;
char *comp="/dev/sample";

/* cmd should be 1 or 2 */
if (cmd == 2) {
/* Unloading */
if (rascb) ras_unregister(rascb);
xmfree(data, kernel_heap);
return(0);
}

if (cmd != 1) return(EINVAL);
/* Allocate data */

data = xmalloc(sizeof(sample_data_t), 1, kernel_heap);

if (!data) {
return(ENOMEM);
}
len = strlen(comp)+1;
data->dev=xmalloc(len, 1, kernel_heap);
strcpy(data->dev,comp);
data->flag = 0;



/* Register the component as dump aware */
rv = ras_register(&rascb, "sample_livedump", (ras_block_t)0, RAS_TYPE_FILESYSTEM
, "sample component",
RASF_DUMP_AWARE, sample_livedump_callback, NULL);
if (rv) return(KERROR2ERRNO(rv));

/* turn on component live dump */
rv = ras_control(rascb, RASCD_SET_LDMP_ON, 0, 0);
if (rv) return(KERROR2ERRNO(rv));

/* dump staging buffer space must be set up to store the dump table */
rv = ras_control(rascb, RASCD_SET_SDMP_STAGING,
(void*)(sizeof(struct cdt_nn_head)+ sizeof(struct cdt_entry)), 0);
if (rv) return(KERROR2ERRNO(rv));

/* To make persistent */
rv = ras_customize(rascb);
if (rv) return(KERROR2ERRNO(rv));

sample_initiate_livedump();

return(0);
}

/*
* Sample Callback that is called for live dump.
*
* The data to dump consists of a header and data .
*
* Input:
* cb - Contains the component's ras_block_t.
* cmd - ras_control command
* arg - command argument
* priv - private data, unused.
*/
kerrno_t
sample_livedump_callback(ras_block_t cb, ras_cmd_t cmd, void *arg, void *priv)
{
kerrno_t rv = 0;

switch(cmd) {
case RASCD_LDMP_ON: {
/* Turn live dump on. */
rv = ras_control(cb, RASCD_SET_LDMP_ON, 0, 0);
break;
}
case RASCD_LDMP_OFF: {
/* Turn live dump off. */
rv = ras_control(cb, RASCD_SET_LDMP_OFF, 0, 0);
break;
}
case RASCD_LDMP_LVL: {
/* Set livedump data level */
rv = ras_control(cb, RASCD_SET_LDMP_LVL, arg, 0);
break;
}
case RASCD_LDMP_ESTIMATE: /* fall through */
case RASCD_LDMP_PREPARE:{
/*
* The prepare call is used to request staging buffer space
* and provide an estimate of the amount of data to be dumped
*/
ldmp_prepare_t *p = (ldmp_prepare_t*)arg;
int n = 0;
/* Staging buffer used for dump table */
p->ldpr_sbufsz =sizeof(struct cdt_nn_head)+ sizeof(struct cdt_entry) ;
p->ldpr_datasize = p->ldpr_sbufsz + sizeof(sample_data_t);
break;
}
case RASCD_LDMP_START: {
/*
* This is received to provide the dump table.
* the table is an limited table here.
*/
ldmp_start_t *p = (ldmp_start_t*)arg;
struct cdt_nn_head *hp;
struct cdt_entry *ep;

hp = (struct cdt_nn_head*)p->ldmpst_buffer;
bzero(hp,sizeof(struct cdt_nn_head));
hp->cdtn_magic = DMP_MAGIC_N;
hp->cdtn_len=sizeof(struct cdt_nn_head)+ sizeof(struct cdt_entry);

ep = (struct cdt_entry*)(hp+1);
strcpy(ep->d_name, "dev1");
ep->d_len = sizeof(sample_data_t);
ep->d_ptr = &data;
ep->d_segval = DUMP_GEN_SEGVAL;
p->ldmpst_table = hp;
break;
}
case RASCD_LDMP_AGAIN:
break;
case RASCD_LDMP_FINISHED:
break;

case RASCD_DMP_PASS_THROUGH:{
/* pass through */
printf("%s\n", arg);
break;
}
default: {
printf("bad ras_control command.\n");
rv = EINVAL_RAS_CONTROL_BADCMD;
}
}

return(rv);
}

void
sample_initiate_livedump()
{
ldmp_parms_t sample_params;
kerrno_t kc,rc;
if(ldmp_setupparms(&sample_params)==0) {
sample_params.ldp_title= "sample";
sample_params.ldp_errcode = 3;
sample_params.ldp_symptom = "sam";;
sample_params.ldp_func = "func";;
if (dmp_compspec(DCF_FAILING|DCF_BYCB, rascb, &sample_params, NULL, NULL)) {
printf("Error");
}
rc=livedump(&sample_params);
if(rc!=0) {
printf("Error %d",rc);
}
} else {
printf("Error");
}
}

要将 sample_comp 包含在一个从命令行发起的实时转储中,可运行以下命令:

livedumpstart -C sample_comp symptom="sample dump"

参考资料

学习

  • Livedump 内核服务
  • 实时转储工具
  • 固件协助转储 - 进度代码
  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
  • AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。
  • AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。
  • AIX and UNIX 下载中心:在这里你可以下载到可以运行在 AIX 或者是 UNIX 系统上的 IBM 服务器软件以及工具,让您可以提前免费试用他们的强大功能。
  • IBM Systems Magazine for AIX 中文版:本杂志的内容更加关注于趋势和企业级架构应用方面的内容,同时对于新兴的技术、产品、应用方式等也有很深入的探讨。IBM Systems Magazine 的内容都是由十分资深的业内人士撰写的,包括 IBM 的合作伙伴、IBM 的主机工程师以及高级管理人员。所以,从这些内容中,您可以了解到更高层次的应用理念,让您在选择和应用 IBM 系统时有一个更好的认识。

讨论

  • 加入 developerWorks 中文社区。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=937308
ArticleTitle=IBM AIX RAS – 通过固件协助的实时转储(Dump)工具简介
publish-date=07152013