使用 AIX Event Infrastructure 监视事件

AIX® Event Infrastructure 是一个用于监视多种系统事件的可扩展框架。本文概述监视接口以及如何编写事件监视应用程序。

Cheryl L. Jennings, AIX 文件系统开发人员, IBM

Cheryl Jennings 毕业于 Austin 的 University of Texas,获得计算机科学学士学位。她最初在 IBM 的 AIX L3 Support 团队工作,目前在 AIX Filesystem Development 团队工作。



Trishali Nayar, AIX 文件系统开发人员, IBM

Trishali Nayar 在 IBM India Storage Lab 工作。她毕业于 University of Pune,获得计算机工程学士学位。她原来是开发 Cluster Aware AIX 操作系统的开发团队的成员。她具有分布式文件系统开发方面的经验。她还与别人合作撰写了 IBM Redbook Implementing NFSv4 in the Enterprise: Planning and Migration Strategies



2011 年 7 月 04 日

简介

AIX Event Infrastructure 是一个用于监视预定义和用户定义的系统事件的事件监视框架。在 AIX Event Infrastructure 的上下文中,事件是指状态或值的变化,变化发生时,可以在内核或内核扩展中探测到它们。

可以监视到的每个事件类型都与一个事件生成器相关联。事件生成器只是在事件发生时探测事件并通知 AIX Event Infrastructure 的代码段。下面例举了一些可用的事件生成器:

  • modFile:modFile 事件生成器监视对文件内容的修改。
  • utilFs:utilFs 事件生成器监视文件系统利用率。
  • waitTmPgInOut:waitTmPgInOut 事件生成器监视线程在一秒内等待页面换入或换出操作完成的平均等待时间(以毫秒为单位)。

可用事件生成器的完整列表见 参考资料

事件表示为一个伪文件系统中的文件。使用现有的文件系统接口(read()、write()、select() 等)指定应该如何和何时通知监视应用程序(也称为消费者),以及等待和读取事件的相关数据。使用 AIX Event Infrastructure 中监视器文件的路径名决定消费者希望监视哪些事件。

图 1. 挂装的 AIX Event Infrastructure 文件系统的实例示例
挂装的 AIX Event Infrastructure 文件系统实例的示意图

在 AIX Event Infrastructure 文件系统中,有四种基本文件类型:

  1. 监视器工厂:监视器工厂是扩展名为 ".monFactory" 的目录。它们以目录的形式表示事件生成器。在挂载 AIX Event Infrastructure 文件系统时自动地创建这些目录。
  2. 监视器文件:监视器文件的扩展名是 ".mon",它们代表要监视的事件。它们只出现在代表相关联的事件生成器的监视器工厂下面。
  3. 列表文件:列表文件是特殊的数据文件,扩展名是 ".list"。当前只有一个列表文件,即 evProds.list。读取这个文件会返回所有可用事件生成器的列表。
  4. 子目录:子目录用于简化管理,它们代表事件的完整路径名。

用 AIX Event Infrastructure 监视事件

AIX Event Infrastructure 包含在 AIX 6.1 TL 6 和 AIX 7.1 上的 bos.ahafs 文件集中。要想监视事件,首先要安装 bos.ahafs 文件集并挂载 AIX Event Infrastructure 文件系统的实例:

	mkdir /aha
	mount -v ahafs /aha /aha

可以把这个文件系统载在想要的任何挂装点上。本文中的示例假设它挂装在 /aha。

决定要使用哪个监视器文件

挂装文件系统之后,必须判断与希望监视的事件对应的监视器文件的路径名。对于每个事件生成器,以不同的方法决定应该使用的路径名。更多信息参见:

在下一节研究的监视示例中,我们要监视对 /etc/passwd 文件的修改。为了判断监视器文件的路径名,需要判断与这个事件对应的事件生成器。因为 /etc/passwd 是常规文件,所以应该使用 modFile 事件生成器监视对其内容的修改。根据 modFile 文档,“应该在 modFile.monFactory 目录下面创建路径与希望监视的文件相同的监视器文件。” 因此,假设 AIX Event Infrastructure 文件系统挂装在 /aha,这个监视器文件的完整路径名应该是:/aha/fs/modFile.monFactory/etc/passwd.mon

应该注意,监视器文件的路径名以相关联的监视器工厂的路径开头,代表不同的事件。例如,/aha/fs/modDir.monFactory/home/cherylfs.mon 文件监视 /home/cherylfs 目录中的文件创建和删除。/aha/fs/utilFs.monFactory/home/cherylfs.mon 文件监视 /home/cherylfs 文件系统的利用率。

事件监视流程示例

下面是典型事件监视流程的高层视图。在这个示例中,事件消费者(监视应用程序)监视 /etc/passwd 文件。这个流程说明在监视事件时事件消费者和 AIX Event Infrastructure 执行的操作。

图 2. 事件监视流程示例
事件监视流程示例的示意图

此时,监视应用程序休眠,直到探测到事件发生。AIX Event Infrastructure 监视文件操作,判断所监视的文件是否被修改。

图 3. 事件监视流程示例(续)
事件监视流程示例的示意图(续)

在前面的示例中可以看到,监视应用程序的典型流程是:

  1. 使用 write() 系统调用设置事件监视。
  2. 使用 select()(或阻塞的 read())系统调用等待事件发生。
  3. 通过 read() 系统调用读取事件发生数据。
  4. 解析事件发生数据并采取适当的措施。
  5. 如果需要,继续等待事件发生。

本文会讨论每个步骤。您可以下载本文提供的示例程序 mon_modFile_event.c。


设置事件监视

挂载 AIX Event Infrastructure 文件系统并确定适当的监视器文件之后,必须创建监视器文件。这可以使用带 O_CREAT 标志的 open() 调用来完成。关于创建监视器文件的信息见 参考资料

创建并打开监视器文件之后,必须写入关于如何和何时发出通知的说明。可以在 参考资料 中找到可用选项的完整列表(见 "Writing to the monitor file")。

尽管大多数监视说明很简单,但是 AIX Event Infrastructure 以两种方式处理通知计数 (NOTIFY_CNT) 说明:

图 4. NOTIFY_CNT 差别
NOTIFY_CNT 差别的示意图

对于 NOTIFY_CNT=-1 的情况,在监视应用程序当前没有在 select() 或 read() 调用中阻塞时,如果探测到另一次事件发生,那么在分配给这个消费者的缓冲区中记录事件发生数据。当监视应用程序试图执行另一次 select() 或阻塞的 read() 调用时,这些调用会立即返回,因为缓冲区中有未读的事件发生数据。

在示例程序 mon_modFile_event.c 中,用户通过参数传递要通过 modFile 事件生成器监视的文件。如果需要,在 AIX Event Infrastructure 文件系统中创建子目录以创建所需的监视器文件。

打开监视器文件之后,把字符串 "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=1" 写入监视器文件,这是因为:

  1. modFile 事件生成器指定了 AHAFS_THRESHOLD_STATE 功能 (CHANGED=YES)。
  2. mon_modFile_event 程序将在 select() 调用中等待 (WAIT_TYPE=WAIT_IN_SELECT)。
  3. modFile 事件生成器不传递消息,而且这个程序中不需要堆栈跟踪 (INFO_LVL=1)。

mon_modFile_event 程序会不断地监视事件。因为 NOTIFY_CNT 的默认值是 -1,所以不需要指定它。


等待事件发生

监视应用程序可以监视多个事件,多个应用程序可以用不同的监视说明监视同一事件。

一定要注意,直到监视应用程序执行 select() 或阻塞的 read() 调用,才会开始监视事件。几种情况会导致 select() 或阻塞的 read() 返回。AIX 6.1 信息中心中列出了这些情况(见 Waiting on events)。

把监视说明写入监视器文件之后,示例程序在 select() 调用中阻塞。如果 select() 调用返回错误,就把一个特殊的标志传递给解析函数,表示在输出中将使用错误格式。

不可用事件发生

对于某些事件生成器,可能有某些类型的事件发生会导致所监视的事件变得无效。例如:

  • 通过 utilFs 事件生成器监视的文件系统被卸载。
  • 通过 modFile 事件生成器监视的文件被删除或重命名。
  • 通过 processMon 或 pidProcessMon 事件生成器监视的进程死亡了。

出现不可用事件发生(unavailable event occurrence)之后,用户无法监视此事件,直到它再次可用。理想情况下,监视应用程序应该识别不可用事件发生并采取纠正措施。这会让事件再次有效。每个事件生成器的文档列出了表示探测到不可用事件发生的返回码。事件生成器的返回码在 sys/ahafs_evProds.h 中定义。

对于本地的不可用事件发生,会删除与此事件相关联的监视器文件。在监视器文件的文件描述符仍然打开的情况下,监视应用程序可以从删除的监视器文件读取事件数据,但是不再继续等待事件发生。当监视应用程序采取纠正措施,事件再次有效之后,必须执行以下操作恢复监视:

  1. 必须关闭删除的监视器文件的文件描述符。
  2. 必须用 O_CREAT 标志再次打开监视器文件。
  3. 必须把监视说明写入此文件。

此时,监视应用程序再次在 select() 或 read() 中等待事件发生。

示例程序会检查事件生成器的返回码 (RC_FROM_EVPROD),判断事件发生是否是不可用事件发生。对于某些不可用事件发生类型,它尝试执行纠正措施;对于其他类型,停止监视。


读取事件发生数据

事件数据由 <keyword>=<value> 对组成,收集的数据取决于事件生成器的功能和监视应用程序指定的 INFO_LVL。事件生成器的文档列出了每个事件生成器的功能。

事件数据只能读取一次,而且在一个 read 调用中不会返回多个事件的数据。例如,假设在消费者读取监视器文件之前,已经把两个事件发生的数据复制到了缓冲区中,每个事件发生的数据有 256 字节。即使消费者调用 read() 以要求读取 4096 字节,也只会把第一个事件的 256 字节数据返回给用户。需要再次执行 read 调用,才能够获得第二个事件的数据。

在示例程序中,总是用 4K 的缓冲区读取事件数据。这是推荐的读取大小,因为大多数事件发生数据都少于 4K。用这么大的缓冲区读取数据意味着,不会由于传递给 read() 调用的缓冲区空间不够造成只返回部分事件数据。

事件发生数据的示例

对于指定了 AHAFS_THRESHOLD_STATE 和 AHAFS_STKTRACE_AVAILABLE 并把消息传递给事件消费者的事件生成器,三个级别的输出如下所示:

INFO_LVL=1 INFO_LVL=2 INFO_LVL=3
BEGIN_EVENT_INFO
TIME_tvsec=1269863383
TIME_tvnsec=455993143
SEQUENCE_NUM=0
PID=6947038
UID=0
UID_LOGIN=0
GID=0
PROG_NAME=cat
RC_FROM_EVPROD=1000
END_EVENT_INFO
BEGIN_EVENT_INFO
TIME_tvsec=1269863383
TIME_tvnsec=455993143
SEQUENCE_NUM=0
PID=6947038
UID=0
UID_LOGIN=0
GID=0
PROG_NAME=cat
RC_FROM_EVPROD=1000
BEGIN_EVPROD_INFO
event producer message here
END_EVPROD_INFO
END_EVENT_INFO
BEGIN_EVENT_INFO
TIME_tvsec=1269863383
TIME_tvnsec=455993143
SEQUENCE_NUM=0
PID=6947038
UID=0
UID_LOGIN=0
GID=0
PROG_NAME=cat
RC_FROM_EVPROD=1000
BEGIN_EVPROD_INFO
event producer message here
END_EVPROD_INFO
STACK_TRACE:
ahafs_prod_callback+3C4
ahafs_cbfn_wrapper+30
ahafs_vn_write+204
vnop_rdwr+7E4
vno_rw+B4
rwuio+12C
rdwr+184
kewrite+16C
.svc_instr
write+1A4
_xwrite+6C
_xflsbuf+B0
__flsbuf+9C
copyopt_ascii+2C0
scat+388
main+11C
__start+68
END_EVENT_INFO

对于指定了 AHAFS_THRESHOLD_VALUE_HI 但没有指定 AHAFS_STKTRACE_AVAILABLE 并把消息传递给事件消费者的事件生成器,三个级别的输出如下所示:

INFO_LVL=1 INFO_LVL=2 INFO_LVL=3
BEGIN_EVENT_INFO
TIME_tvsec=1269866715
TIME_tvnsec=16678418
SEQUENCE_NUM=0
CURRENT_VALUE=3
RC_FROM_EVPROD=1000
END_EVENT_INFO
BEGIN_EVENT_INFO
TIME_tvsec=1269866715
TIME_tvnsec=16678418
SEQUENCE_NUM=0
CURRENT_VALUE=3
RC_FROM_EVPROD=1000
BEGIN_EVPROD_INFO
event producer message here
END_EVPROD_INFO
END_EVENT_INFO
BEGIN_EVENT_INFO
TIME_tvsec=1269866715
TIME_tvnsec=16678418
SEQUENCE_NUM=0
CURRENT_VALUE=3
RC_FROM_EVPROD=1000
BEGIN_EVPROD_INFO
event producer message here
END_EVPROD_INFO
END_EVENT_INFO

如果事件生成器返回错误,那么所有事件生成器对于所有 INFO_LVL 都使用以下格式:

	BEGIN_EVENT_INFO
	TIME_tvsec=1269868036
	TIME_tvnsec=966708948
	SEQUENCE_NUM=0
	RC_FROM_EVPROD=19
	END_EVENT_INFO

如果消费者监视一个值事件,而当前值已经超过了要求的阈值,那么使用以下格式记录这个 EALREADY 事件:

	BEGIN_EVENT_INFO
	TIME_tvsec=1281837726
	TIME_tvnsec=446010404
	SEQUENCE_NUM=0
	CURRENT_VALUE=70
	RC_FROM_EVPROD=56
	END_EVENT_INFO

每个事件生成器提供关于它们生成的事件发生的输出中包含什么内容的信息。事件生成器的返回码在 sys/ahafs_evProds.h 中定义。

示例程序在事件发生数据中检查错误格式,判断 select() 调用是否返回了错误。如果没有返回错误,就使用 modFile 事件生成器文档中包含的格式。它使用 sscanf() 读取相应关键字的值。

SEQUENCE_NUM 关键字

对于每个消费者,维护每个事件的序号。相同的事件发生对于不同的消费者可能有不同的序号,这取决于消费者开始监视事件的时间。

出现监视停止之后,序号复位为 0。下图说明 SEQUENCE_NUM 关键字的表现。

图 4. 两个消费者监视同一事件
两个消费者监视同一事件的示意图

BUF_WRAP 和 EVENT_OVERFLOW 关键字

对于每个消费者和监视的每个事件,事件数据保存在一个循环的缓冲区中。如果写入事件数据的速度比消费者读取数据快,可能会出现缓冲区回绕(wrap)。如果出现缓冲区回绕,会覆盖事件数据,所以 read() 调用不会返回部分事件数据。图 5 说明缓冲区在缓冲区回绕之前和之后的样子:

图 5. 缓冲区回绕
缓冲区回绕的示意图

如果出现缓冲区回绕,第一个 read 只返回关键字 BUF_WRAP。第二个 read 返回下一个事件发生的全部事件数据。应该根据 SEQUENCE_NUM 字段判断缓冲区回绕覆盖了多少个事件发生。如果监视应用程序遇到缓冲区回绕,可以增加在 BUF_SIZE 中指定的监视缓冲区大小。不能动态地修改这个设置。

如果消费者使用非常小的缓冲区,一个事件发生的事件数据可能会超过缓冲区。在这种情况下,会把关键字 EVENT_OVERFLOW 写入缓冲区,并写入缓冲区能够容纳的尽可能多的事件发生数据。在发生溢出的情况下,第一个 read 只返回关键字 EVENT_OVERFLOW。下一个 read 返回缓冲区能够容纳的事件数据。

如果在发生溢出的情况下发生回绕,第一个 read 返回关键字 BUF_WRAP,第二个 read 返回关键字 EVENT_OVERFLOW,第三个 read 返回缓冲区能够容纳的事件数据。

示例程序检查传递的事件数据是否包含 BUF_WRAP 关键字。如果发生了缓冲区回绕,就向用户输出警告。示例程序并不检查 EVENT_OVERFLOW,因为它指定 INFO_LVL 为 1 并使用默认缓冲区大小 4K。当前,在 INFO_LVL 设置为 1 的情况下 modFile 事件的最大大小小于 4K。

重复事件数据整合

为了减少缓冲区回绕,AIX Event Infrastructure 会整合重复的未读事件。在收集到新的事件数据时,与最近的未读事件数据进行比较。如果每个事件发生的数据完全相同(除了时间戳和序号之外),那么更新以前写的事件数据的时间戳和序号以反映这个新的重复的事件发生。

重复事件数据整合与缓冲区回绕的表现差异在于,在发生整合时并不会读取到关键字 BUF_WRAP。

示例程序维护自己的内部序号。它会比较预期的值和从事件发生数据读取的实际值,从而判断是否整合了重复事件。如果探测到不可用事件,那么这个内部序号复位为 0。


下载

描述名字大小
用于监视修改的程序mon_modFile_event.c10KB

参考资料

学习

  • 查阅 Waiting on events 列表。这里列出了这些条件:http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.baseadmn/doc/baseadmndita/aix_ev_in_mon_wait.htm
  • 了解如何 创建监视器文件
  • 阅读 "Writing to the monitor file",查看完整的监视器文件选项列表。
  • 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: 登录

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


需要一个 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=696991
ArticleTitle=使用 AIX Event Infrastructure 监视事件
publish-date=07042011