Oracle® Solaris 11.2 デバイスドライバの記述

印刷ビューの終了

更新: 2014 年 9 月
 
 

イベント属性の定義

イベント属性は名前-値ペアのリストとして定義します。Oracle Solaris DDI には、情報を名前-値ペアとして格納するためのルーチンや構造体が用意されています。名前-値ペアは、ドライバからは不透明な nvlist_t 構造体に保持されます。名前-値ペアの値は、ブール、int、バイト、文字列、nvlist のいずれか、またはこれらのデータ型の配列になります。int は、16 ビット、32 ビット、64 ビットのいずれかとして定義できるほか、符号付き、符号なしのいずれかにすることができます。

名前-値ペアのリストを作成する手順は、次のとおりです。

  1. nvlist_alloc(9F) を使用して nvlist_t 構造体を作成します。

    nvlist_alloc () インタフェースが取る引数は次の 3 つです。

    • nvlp – nvlist_t 構造体へのポインタへのポインタ

    • nvflag – ペアの名前の一意性を示すフラグ。このフラグを NV_UNIQUE_NAME_TYPE に設定すると、新しいペアの名前と型に一致する既存のペアがすべて、リストから削除されます。このフラグを NV_UNIQUE_NAME に設定すると、型が何であっても、同じ名前を持つ既存のペアがすべて削除されます。NV_UNIQUE_NAME_TYPE を指定すると、型が異なるかぎり、名前が同じペアを複数個リストに含めることが可能となります。一方、NV_UNIQUE_NAME の場合、リストに含めることのできるペア名のインスタンスは 1 つのみになります。このフラグを設定しなかった場合、一意性のチェックは行われず、リストのコンシューマが重複への対処を担当することになります。

    • kmflag – カーネルメモリーの割り当てポリシーを示すフラグ。この引数を KM_SLEEP に設定すると、要求したメモリーが割り当て可能になるまでドライバがブロックされます。KM_SLEEP 割り当ての場合、スリープが発生する可能性がありますが、処理が成功することは保証されます。KM_NOSLEEP 割り当ての場合、スリープが発生しないことが保証されますが、使用可能なメモリーが現在存在しない場合には NULL が返される可能性があります。

  2. nvlist に名前-値ペアを設定します。たとえば、文字列を追加するには、nvlist_add_string(9F) を使用します。32 ビット整数の配列を追加するには、nvlist_add_int32_array(9F) を使用します。nvlist_add_boolean(9F) のマニュアルページに、ペア追加用インタフェースの完全な一覧が含まれています。

リストの割り当てを解除するには、nvlist_free(9F) を使用します。

次のサンプルコードは、名前-値リストの作成方法を示したものです。

使用例 5-2  名前-値ペアリストの作成およびデータ設定
nvlist_t*
create_nvlist()
    {
    int err;
    char *str = "child";
    int32_t ints[] = {0, 1, 2};
    nvlist_t *nvl;

    err = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);    /* allocate list */
    if (err)
        return (NULL);
    if ((nvlist_add_string(nvl, "name", str) != 0) ||
        (nvlist_add_int32_array(nvl, "prop", ints, 3) != 0)) {
        nvlist_free(nvl);
        return (NULL);
    }
    return (nvl);
}

ドライバから nvlist の要素を取得するには、nvlist_lookup_int32_array(9F) など、その型の検索用関数を使用します。検索用関数は、検索対象となるペアの名前を引数として取ります。


注 - これらのインタフェースが動作するのは、nvlist_alloc(9F) の呼び出し時に NV_UNIQUE_NAME または NV_UNIQUE_NAME_TYPE のどちらかが指定された場合のみです。それ以外の場合は ENOTSUP が返されます。同じ名前の複数のペアをリストに含めることができないためです。

名前-値リストペアのリストは、連続するメモリー内に配置できます。このアプローチは、通知を受け取るように登録したエンティティーにリストを渡す場合に便利です。最初の段階は、リストに必要なメモリーブロックのサイズを、nvlist_size(9F) を使用して取得することです。次の段階は、nvlist_pack (9F) でリストをバッファーにパックすることです。バッファーの内容を受け取るコンシューマは、nvlist_unpack(9F) でバッファーを展開できます。

名前-値ペアを操作するための関数は、ユーザーレベル、カーネルレベルのどちらの開発者も使用できます。man pages section 3: Library Interfaces and Headersman pages section 9: DDI and DKI Kernel Functions の両方に、これらの関数に対する同一のマニュアルページが含まれています。名前-値ペアを処理対象とする関数の一覧については、次の表を参照してください。

表 5-1  名前-値ペアを使用するための関数
マニュアルページ
目的/関数
名前-値ペアをリストに追加します。次の関数があります。
nvlist_add_boolean()nvlist_add_boolean_value()nvlist_add_byte()nvlist_add_int8()nvlist_add_uint8()nvlist_add_int16()nvlist_add_uint16()nvlist_add_int32()nvlist_add_uint32()nvlist_add_int64()nvlist_add_uint64()nvlist_add_string()nvlist_add_nvlist()nvlist_add_nvpair()nvlist_add_boolean_array()nvlist_add_int8_array, nvlist_add_uint8_array()nvlist_add_nvlist_array()nvlist_add_byte_array()nvlist_add_int16_array()nvlist_add_uint16_array()nvlist_add_int32_array()nvlist_add_uint32_array ()nvlist_add_int64_array()nvlist_add_uint64_array()nvlist_add_string_array()
名前-値リストのバッファーを操作します。次の関数があります。
nvlist_alloc()nvlist_free()nvlist_size()nvlist_pack()nvlist_unpack()nvlist_dup()nvlist_merge()
名前-値ペアを検索します。次の関数があります。
nvlist_lookup_boolean()nvlist_lookup_boolean_value ()nvlist_lookup_byte()nvlist_lookup_int8()nvlist_lookup_int16()nvlist_lookup_int32()nvlist_lookup_int64()nvlist_lookup_uint8()nvlist_lookup_uint16()nvlist_lookup_uint32()nvlist_lookup_uint64()nvlist_lookup_string()nvlist_lookup_nvlist()nvlist_lookup_boolean_array、nvlist_lookup_byte_array()nvlist_lookup_int8_array()nvlist_lookup_int16_array()nvlist_lookup_int32_array()nvlist_lookup_int64_array()nvlist_lookup_uint8_array()nvlist_lookup_uint16_array()nvlist_lookup_uint32_array() nvlist_lookup_uint64_array()nvlist_lookup_string_array() nvlist_lookup_nvlist_array()nvlist_lookup_pairs()
名前-値ペアのデータを取得します。次の関数があります。
nvlist_next_nvpair()nvpair_name()nvpair_type()
名前-値ペアを削除します。次の関数があります。
nv_remove()nv_remove_all()