デバイスドライバは ddi_log_sysevent (9F) インタフェースを使用することで、イベントの生成とそのイベントのシステムへの記録を行います。
ddi_log_sysevent() で使用される構文は、次のとおりです。
int ddi_log_sysevent(dev_info_t *dip, char *vendor, char *class, char *subclass, nvlist_t *attr-list, sysevent_id_t *eidp, int sleep-flag);
ここでは:
このドライバの dev_info ノードへのポインタ。
ドライバのベンダーを定義する文字列へのポインタ。他社製ドライバでは、その会社の銘柄記号や、銘柄記号と同様の永続性のある識別子を使用します。Oracle が提供するドライバでは DDI_VENDOR_SUNW が使用されます。
イベントのクラスを定義する文字列へのポインタ。class はドライバに固有の値です。クラスの例には、あるデバイスに影響を与える一連の環境状態を表す文字列があります。この値は、イベントのコンシューマが認識できるものである必要があります。
class 引数のサブセットを表すドライバ固有の文字列。たとえば、環境の状態を表すクラス内に、デバイスの温度を表すイベントサブクラスを追加できます。この値は、イベントのコンシューマが理解できるものである必要があります。
このイベントに関連する名前-値属性のリストを含む nvlist_t 構造体へのポインタ。名前-値属性はドライバごとに定義される値であり、デバイスの特定の属性や状態を表すことができます。
たとえば、CD-ROM と DVD の両方を読み取るデバイスを考えます。このデバイスには、名前が disc_type で値が cd_rom、dvd のいずれかに等しいような属性を割り当てることができます。
イベントのコンシューマは class や subclass の場合と同様に、名前-値ペアを解釈できる必要があります。
名前-値ペアや nvlist_t 構造体の詳細については、Defining Event Attributesを参照するほか、 nvlist_alloc(9F) のマニュアルページも参照してください。
属性を持たないイベントでは、この引数を NULL に設定する必要があります。
sysevent_id_t 構造体のアドレス。sysevent_id_t 構造体を使用すると、イベントを一意に識別できます。ddi_log_sysevent(9F) から返されるこの構造体には、システムによって提供されるイベントシーケンス番号とタイムスタンプが含まれます。sysevent_id_t 構造体の詳細については、ddi_log_sysevent(9F) のマニュアルページを参照してください。
リソースが使用可能でない場合に呼び出し元がどのように対処するのかを示すフラグ。sleep-flag が DDI_SLEEP に設定されると、リソースが使用可能になるまでドライバがブロックされます。DDI_NOSLEEP の状態では割り当てがスリープしないため、処理の成功が保証されません。DDI_ENOMEM が返された場合、ドライバは処理をあとで再試行する必要があります。
DDI_SLEEP の状態でも、システムビジーや syseventd デーモンの不応答、割り込みコンテキストでのイベントのロギング試行など、その他のエラーがこのインタフェースから返される可能性があります。
デバイスドライバは、イベントのロギングを行うために次のタスクを実行します。
nvlist_alloc(9F) を使用して属性リスト用のメモリーを割り当てる
名前-値ペアを属性リストに追加する
ddi_log_sysevent (9F) 関数を使用して sysevent キューにイベントを記録する
属性リストが不要になった時点で nvlist_free(9F) を呼び出す
次の例は、ddi_log_sysevent() の使用方法を示しています。
使用例 5-1 ddi_log_sysevent() の呼び出しchar *vendor_name = "DDI_VENDOR_JGJG" char *my_class = "JGJG_event"; char *my_subclass = "JGJG_alert"; nvlist_t *nvl; /* ... */ nvlist_alloc(&nvl, nvflag, kmflag); /* ... */ (void) nvlist_add_byte_array(nvl, propname, (uchar_t *)propval, proplen + 1); /* ... */ if (ddi_log_sysevent(dip, vendor_name, my_class, my_subclass, nvl, NULL, DDI_SLEEP)!= DDI_SUCCESS) cmn_err(CE_WARN, "error logging system event"); nvlist_free(nvl);