ibm ras 教程_IBM AIX RAS –固件辅助和实时转储功能介绍

固件辅助转储概述

固件辅助的转储通过重新引导分区并使用新的内核来转储来自先前内核崩溃的数据,从而提供了比传统转储类型更高的可靠性。

固件辅助的转储要求:

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

当启动为固件辅助转储配置的分区时,称为暂存区的一部分内存将分配给固件辅助转储功能使用。 因此,配置为使用传统系统转储的分区需要重新启动才能分配启动固件辅助转储所需的暂存区域内存。 固件有助于保留要转储的页面,直到出现非故障操作系统为止。 非故障操作系统将完成将保留的内存复制到转储文件的处理。

固件辅助转储的错误代码

引导加载程序将开始将数据写入转储逻辑块中,并且一旦将转储逻辑块中的数据写入转储逻辑卷中,就会释放空间。 如果释放了一定比例的主内存,那么将允许AIX引导。 从那时起,AIX将接管控制权,以将转储逻辑块中的其余数据写入转储逻辑卷中。

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

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


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

sysdumpdev -l –用于检查操作系统中的实际错误代码。

现场转储

提供实时转储功能,以允许在不关闭整个系统的情况下转储故障数据。 实时转储的两种最常见用法可能包括以下情形:

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

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

序列化实时转储是指在转储数据时导致系统冻结或挂起的转储。 冻结系统后,数据将复制到内核固定的内存中。 仅在系统解冻后才将其写入文件系统。 非序列化转储是指不冻结系统而进行的转储。

通过停止除转储处理器之外的每个处理器,冻结系统。 然后,使用转储处理器在最喜欢的中断优先级INTMAX处捕获转储数据。 应当指出,当系统冻结时,不允许出现页面错误。

同步和异步实时转储

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

转储位置

在实时转储过程中捕获的数据将排队进入实时转储过程。 取消冻结系统后,此过程会将数据写入文件系统。 默认情况下,实时转储位于/ var / adm / ras / livedump目录中。 转储文件名的格式为: [prefix。] component.yyyymmddhhmm.xx.DZ 。

实时转储堆内存

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

现场转储通行证

序列化的实时转储可以一次或多次进行。 转储过程包含可以在冻结系统时缓冲在固定存储中的数据。 多遍转储中进行的转储涉及多个系统冻结,因此,多遍转储中的数据可能不一致。 实时转储可以由内核或内核扩展从软件启动。 转储知道,转储中包含的任何组件都必须事先使用ras_register()在内核中注册。 他们还必须指示已通过使用RASCD_SET_LDMP_ON ras_control()服务来处理实时转储。

组件内存级别和最大缓冲区大小

以下列表显示了组件的数据限制。 如果组件超出了这些限制,则仅通过转储其导致超出限制的数据条目之前的数据条目来截断其数据。

下表指定了每个实时转储详细信息级别允许的最大数据

  • <CD_LVL_NORMAL-2 MB
  • > = CD_LVL_NORMAL和<CD_LVL_DETAIL-4 MB
  • > = CD_LVL_DETAIL和<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_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相同,不同之处在于,如果返回的值小于零,则不会再转储该组件的任何数据,但是以前的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" dumpctrl -l foo "pass through text"传递给别名为foo.的组件的RASCD_DMP_PASS_THROUGH处理程序foo.

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"

翻译自: https://www.ibm.com/developerworks/aix/library/au-aix-ras-firmware/index.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值