Go to main content
リソース管理および Oracle® Solaris ゾーン開発者ガイド

印刷ビューの終了

更新: 2016 年 11 月
 
 

exacct ファイルにアクセスするための C コードの例

このセクションでは、exacct ファイルにアクセスするためのコード例を示します。

使用例 3  指定された pidexacct データの表示

この例は、特定の 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);
		...	
使用例 4  カーネルビルド中の個々のタスクの識別

この例では、カーネルビルドを評価し、このタスクによってビルドされるソースツリーの一部を表す文字列を示します。ソースディレクトリごとの分析に役立てるために、ビルドされるソースの一部を示します。

この例について次の重要なポイントに注意してください。

  • make の時間の集約には多くのプロセスが含まれることがあるため、各 make はタスクとして開始されます。make の子プロセスは別のタスクとして作成されます。makefile ツリー全体で集約するには、タスクの親子関係を識別する必要があります。

  • タスクの exacct ファイルにこの情報を含むタグを追加します。このタスクの make 操作でビルドされるソースツリーの一部を表す現在の作業ディレクトリの文字列を追加します。

    ea_set_item(&cwd, EXT_STRING | EXC_LOCAL | MY_CWD, 
                                   cwdbuf, strlen(cwdbuf));
  ...
/* 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);
  ...
使用例 5  システムの exacct ファイルの内容の読み取りと表示

この例では、プロセスまたはタスク用にシステムの exacct ファイルの読み取りまたは表示を行う方法を示します。

この例について次の重要なポイントに注意してください。

  • ファイル内の次のオブジェクトを取得するには、ea_get_object() を呼び出します。EOF が exacct ファイルの完全なトラバーサルを有効にするまで ea_get_object() をループで呼び出します。

  • catalog_name() は、catalog_item 構造体を使用して、Oracle Solaris カタログのタイプ ID をオブジェクトデータの内容を表す意味のある文字列に変換します。タイプ ID は最下位の 24 ビットつまり 3 バイトをマスキングすることで取得されます。

    switch(o->eo_catalog & EXT_TYPE_MASK) {
      case EXT_UINT8:
          printf(" 8: %u", o->eo_item.ei_uint8);
          break;
      case EXT_UINT16:
      ...
    }
  • TYPE_MASK の上位 4 ビットは、データ型を調べてオブジェクトの実際のデータを出力するために使用されます。

  • disp_group() は、グループオブジェクトへのポインタとグループ内のオブジェクト数を取得します。グループ内の各オブジェクトに対して、disp_group()disp_obj() を呼び出し、オブジェクトがグループオブジェクトの場合は disp_group() を再帰的に呼び出します。

/* 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 Oracle 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);
        }
 }