dmp_ctl 内核服务
用途
添加和除去主转储表中的条目。
语法
#include <sys/types.h>
#include <errno.h>
#include <sys/dump.h>
int dmp_ctl(op, parmp)
int op;
struct dmpctl_data *parmp;描述
使用 dmp_ctl 内核服务来管理转储例程。 它将替换出于兼容性原因仍受支持的 dmp_add 和 dmp_del 内核服务。 使用 dmp_add () 命令添加的例程与使用 dmp_ctl () 命令添加的例程之间的主要差别如下所示:
- 这些例程的调用方式与使用 dmp_add 内核服务添加的例程不同。 使用 dmp_ctl 内核服务添加的例程将返回空指针,转储表或转储大小估算值。
- 随 dmp_ctl 内核服务一起添加的例程应该忽略它们不支持的函数。 例如,如果接收到无法识别的请求,那么不应将其捕获。 这允许在不需要更改所有用户的情况下添加未来功能。
dmp_ctl 内核服务用于请求在全局缓冲区中预留一定数量的内存。 然后,例程将使用此参数来存储不在内存中的数据。 此类数据的一个示例是由适配器提供的转储数据。 如果没有全局缓冲区,那么需要将数据放置在配置时分配的锁定缓冲区中。 每个组件都需要分配其自己的锁定缓冲区。
系统转储设施维护此类数据的全局缓冲区。 此缓冲区是在首次请求时使用所请求的大小进行分配的。 另一个请求更多数据的转储例程会导致以更大的大小重新分配缓冲区。 由于在系统的生命周期内必须将此缓冲区保留在固定存储器中,因此只需要尽可能多的内存。 要求过多的存储空间将会保留过多的固定存储空间,从而降低系统性能。
只要需要转储数据,就会调用使用全局缓冲区的任何转储例程。 例程仅调用一次以提供此类数据。 如果转储重新启动,那么将保存并使用其转储表地址。
注: dmp_ctl 内核服务也可以由转储例程用来报告例程故障。 如果例程检测到由于某些原因 (例如数据结构损坏) 而无法转储需要转储的内容,那么可能需要执行此操作。
注意:从采用 6100-02 技术级的AIX® 6.1版开始,dmp_ctl内核服务支持 DMPFUNC_SERIALIO 操作标志。
转储表
转储例程返回以 DMP_MAGIC 开头的组件转储表,该转储表是 32 位或 64 位转储表的幻数。 如果使用无限大小的转储表,那么幻数为 DMP_MAGIC_U ,并使用 CDT_u 结构。 如果是这种情况,那么将重复调用转储例程,直到它返回空 CDT_u 指针为止。 无限大小转储表的目的是提供一种方法来转储未知数量的数据区,而不必按照经典转储表的要求预先分配最大可能数量的 cdt_entry 元素数组。 转储表的定义位于 sys/dump.h 包含文件中。
参数
dmp_ctl 操作和 dmpctl_data 结构在 dump.h 文本文件中定义。
| 项 | 描述 |
|---|---|
| op | 指定要执行的操作。 |
| 帕姆普 | 指向包含所指定操作的值的 dmpctl_data 结构。 dmpctl_data 结构在 /usr/include/sys/dump.h 文件中定义,如下所示: |
受支持的操作及其关联数据为:
| 项 | 描述 |
|---|---|
| DMPCTL_ADD | 将指定的转储例程添加到主转储表。 这需要指向函数和函数类型标志的指针。 受支持的类型标志为:
|
| DMPCTL_DEL | 从主转储表中删除指定的转储函数。 |
| DMPCTL_RTNFAILURE | 报告无法转储所需数据。 例程必须设置 dmpc_func、dmpcf_rV, dmpcf_vaddr 和 dmpcf_handle 字段。 |
转储函数调用参数:
| 项 | 描述 |
|---|---|
| 操作码 | 指定该例程要执行的操作。 操作码如下所示:
|
| 缓冲区指针 | 这是指向全局缓冲区的指针,如果未请求全局缓冲区空间,那么为 NULL。 |
返回值
| 项 | 描述 |
|---|---|
| 0 | 如果成功,那么返回。 |
| EINVAL | 如果一个或多个参数值无效,那么返回。 |
| ENOMEM | 如果无法满足全局缓冲区请求,那么返回。 |
| EEXIST | 如果已添加转储功能,那么返回。 |
示例
- 要添加可以调用一次以提供数据的转储例程 (dmprtn) ,请输入:
void *dmprtn(int op, void *buf); struct cdt cdt; dmp_sizeest_t estimate; config() { struct dmpctl_data parm; ... parm.dmpc_magic = DMPC_MAGIC1; parm.dmpc_func = dmprtn; parm.dmpc_flags = 0; ret = dmp_ctl(DMPCTL_ADD, &parm); ... } /* * Dump routine. * * input: * op - dump routine operation. * buf - NULL since no global buffer is used. * * returns: * A pointer to the component dump table. */ void * dmprtn(int op, void *buf) { void *ret; switch(op) { case DMPRTN_START: /* Provide dump data. */ ... ret = (void *)&cdt; break; case DMPRTN_ESTIMATE: ret = (void *)&estimate; break; default: break; } return(ret); } - 要添加请求 16 kb 全局缓冲区空间的转储例程 (dmprtn) ,请输入:
... #define BSIZ 16*1024 dmp_sizeest_t estimate; config() { ... parm.dmpc_magic = DMPC_MAGIC1; parm.dmpc_func = dmprtn; parm.dmpc_flags = DMPFUNC_CALL_ON_RESTART|DMPC_GLOBAL_BUFFER; parm.dmpc_bsize = BSIZ; ret = dmp_ctl(DMPCTL_ADD, &parm); ... } /* * Dump routine. * * input: * op - dump routine operation. * buf - points to the global buffer. * * output: * Return a pointer to the dump table or to the estimate. */ void * dmprtn(int op, void *buf) { void *ret; switch(op) { case DMPRTN_START: /* Provide dump data. */ ... (Put data in buffer at buf.) ret = (void *)&cdt; break; case DMPRTN_ESTIMATE: ret = (void *)&estimate; break; default: break; } return(ret); }