Solaris 10 资源管理器开发者指南

第 3 章 使用用于扩展记帐的 C 接口

本章介绍用于扩展记帐的 C 接口,包含以下主题:

用于扩展记帐的 C 接口概述

项目和任务用于标记和分隔工作负荷。扩展记帐子系统用于监视系统中正在运行的工作负荷的资源占用情况。扩展记帐将生成工作负荷任务和进程的记帐记录。

有关扩展记帐和扩展记帐管理过程示例的概述,请参见《系统管理指南:Solaris Containers-资源管理和 Solaris Zones》中的第 4  章 “扩展记帐(概述)”《系统管理指南:Solaris Containers-资源管理和 Solaris Zones》中的第 5  章 “管理扩展记帐(任务)”

扩展记帐 API 函数

扩展记帐 API 包含用于执行以下操作的函数:

exacct 系统调用

 

 

 

下表列出了与扩展记帐子系统交互的系统调用。

表 3–1 扩展记帐系统调用

函数 

说明 

putacct(2)

使具有权限的进程能够使用特定于进程的其他数据来标记记帐记录 

getacct(2)

使具有权限的进程能够从当前执行任务和进程的内核中请求扩展记帐缓冲区 

wracct(2)

请求内核为指定的任务或进程写入资源使用情况的数据 

exacct 文件执行的操作

以下函数提供对 exacct 文件的访问:

表 3–2 exacct 文件函数

函数 

说明 

ea_open(3EXACCT)

打开 exacct 文件。

ea_close(3EXACCT)

关闭 exacct 文件。

ea_get_object(3EXACCT)

首次对一组对象使用此函数会将数据读入 ea_object_t 结构。随后对该组使用此函数则会循环处理该组中的对象。

ea_write_object(3EXACCT)

将指定的对象附加到打开的 exacct 文件中。

ea_next_object(3EXACCT)

将基本字段(eo_catalogeo_type)读入 ea_object_t 结构中,并反绕到记录头。

ea_previous_object(3EXACCT)

exacct 文件中往回跳一个对象,并将基本字段(eo_catalogeo_type)读入 ea_object_t 中。

ea_get_hostname(3EXACCT)

获取在其上创建 exacct 文件的主机名。

ea_get_creator(3EXACCT)

确定 exacct 文件的创建者。

exacct 对象执行的操作

以下函数用于访问 exacct 对象:

 

 

 

 

 

 

 

表 3–3 exacct 对象函数

函数 

说明 

ea_set_item(3EXACCT)

指定 exacct 对象并设置值。

ea_set_group(3EXACCT)

设置一组 exacct 对象的值。

ea_match_object_catalog(3EXACCT)

检查 exacct 对象的掩码,以了解该对象是否具有特定目录标记。

ea_attach_to_object(3EXACCT)

exacct 对象附加到指定的 exacct 对象中。

ea_attach_to_group(3EXACCT)

exacct 对象链作为指定组的成员项进行附加。

ea_free_item(3EXACCT)

在指定的 exacct 对象中释放 value 字段。

ea_free_object(3EXACCT)

释放指定的 exacct 对象以及任何附加的对象分层结构。

杂项操作

以下函数与杂项操作相关联:

ea_error(3EXACCT)

ea_match_object_catalog(3EXACCT)

访问 exacct 文件的 C 代码示例

本节提供访问 exacct 文件的代码示例。


示例 3–1 显示与指定的 pid 对应的 exacct 数据

本示例显示内核中特定 pidexacct 数据快照。

...

  ea_object_t *scratch;

  int unpk_flag = EUP_ALLOC;  /* use the same allocation flag */

                              /* for unpack and free */



  /* Omit return value checking, to keep code samples short */



  bsize = getacct(P_PID, pid, NULL, 0);

  buf = malloc(bsize);



  /* Retrieve exacct object and unpack */

  getacct(P_PID, pid, buf, bsize);

  ea_unpack_object(&scratch, unpk_flag, buf, bsize);



  /* Display the exacct record */

  disp_obj(scratch);

  if (scratch->eo_type == EO_GROUP) {

         disp_group(scratch);

  }

  ea_free_object(scratch, unpk_flag);

		...	


示例 3–2 确定内核生成期间的各项任务

本示例评估了内核生成并显示了描述此 make 任务要生成的那部分源代码树的字符串。显示正在生成的且在按源目录的分析中有帮助的源代码部分。

本示例的要点包括以下内容:

  ...

/* Omit return value checking and error processing */

/* to keep code sample short */

ptid = gettaskid();	/* Save "parent" task-id */

tid = settaskid(getprojid(), TASK_NORMAL);	/* Create new task */



/* Set data for item objects ptskid and cwd */

ea_set_item(&ptskid, EXT_UINT32 | EXC_LOCAL | MY_PTID, &ptid, 0);

ea_set_item(&cwd, EXT_STRING | EXC_LOCAL | MY_CWD, cwdbuf, strlen(cwdbuf));



/* Set grp object and attach ptskid and cwd to grp */

ea_set_group(&grp, EXT_GROUP | EXC_LOCAL |  EXD_GROUP_HEADER);

ea_attach_to_group(&grp, &ptskid);

ea_attach_to_group(&grp, &cwd);



/* Pack the object and put it back into the accounting stream */

ea_buflen = ea_pack_object(&grp, ea_buf, sizeof(ea_buf));

putacct(P_TASKID, tid, ea_buf, ea_buflen, EP_EXACCT_OBJECT);



/* Memory management: free memory allocate in ea_set_item */

ea_free_item(&cwd, EUP_ALLOC);

  ...


示例 3–3 读取和显示系统 exacct 文件的内容

本示例显示如何读取并显示进程或任务的系统 exacct 文件。

本示例的要点包括以下内容:

/* Omit return value checking and error processing */

/* to keep code sample short */

main(int argc, char *argv)

{

  ea_file_t ef;

  ea_object_t scratch;

  char *fname;

		

  fname = argv[1];

  ea_open(&ef, fname, NULL,  EO_NO_VALID_HDR, O_RDONLY, 0);

  bzero(&scratch, sizeof (ea_object_t));

  while (ea_get_object(&ef, &scratch)  != -1) {

	     disp_obj(&scratch);

	     if (scratch.eo_type == EO_GROUP)

	         disp_group(&ef, scratch.eo_group.eg_nobjs);

	     bzero(&scratch, sizeof (ea_object_t));

  }

  ea_close(&ef);

}



struct catalog_item {   /* convert Solaris catalog's type ID */

                        /* to a meaningful string */

	 int	type;

	 char *name;

 } catalog[] = {

	 { EXD_VERSION, 	"version\t" },

	 ...

	 { EXD_PROC_PID,	"  pid\t" },

	 ...

   };



 static char *

 catalog_name(int type)

 {

	 int i = 0;

	 while (catalog[i].type != EXD_NONE) {

		 if (catalog[i].type == type)

			 return (catalog[i].name);	

		 else

			 i++;

	 }

	 return ("unknown\t");

 }



 static void disp_obj(ea_object_t *o)

 {

	 printf("%s\t", catalog_name(o->eo_catalog & 0xffffff));

	 switch(o->eo_catalog & EXT_TYPE_MASK) {

	 case EXT_UINT8:

		 printf(" 8: %u", o->eo_item.ei_uint8);

		 break;

	 case EXT_UINT16:

	 ...

 }

 static void disp_group(ea_file_t *ef, uint_t nobjs)

 {

	 for (i = 0; i < nobjs; i++) {

		 ea_get_object(ef, &scratch));

             	 disp_obj(&scratch);

		 if (scratch.eo_type == EO_GROUP)

                disp_group(ef, scratch.eo_group.eg_nobjs);

        }

 }