総合手引 | セクション 9 | English | オプション |
#include <sys/types.h>
#include <sys/sysctl.h>
型 CTLTYPE_NODE の動的な oid は再利用可能であるため、複数のコードセクションが、 oid を作成および削除することが可能です。 実際には、参照カウントに基づいて、その割り当ておよび解放が行われます。 その結果として、2 つ以上のコードセクションが、部分的に重なり、 両者が使用できるツリーを作成可能にします。 重なる葉の作成や、同一の名前と親を持つ異なる型の子の作成は、 不可能です。
新しく作成された oid は親のノードに接続されます。 これら全ての関数およびマクロ ((sysctl_remove_oid) は例外) において、必須パラメータの 1 つ parent は、子の親リストの先頭を指します。
殆どのトップレベルのカテゴリは静的に作成されます。 既存の静的な oid に接続するときに、このポインタは SYSCTL_STATIC_CHILDREN() マクロによって取得することが可能で、その OID_NAME 引数は CTLTYPE_NODE 型の親 oid の名前 (すなわち、 sysctl(8) によって表示される名前に、 アンダスコアを前置し、全てのドットをアンダスコアで置き換えた名前) です。
既存の動的な oid に接続するときに、このポインタは SYSCTL_CHILDREN() マクロによって取得することが可能で、その oidp 引数は CTLTYPE_NODE 型の親 oid を指します。
sysctl_add_oid() 関数はあらゆる型の生の oid を作成します。 oid の作成が成功した場合には、この関数はその oid へのポインタを返します。 そうでない場合には、 NULL を返します。 sysctl_add_oid() のための引数の多くはマクロと共通です。 引数は以下のとおりです。
ctx | |
オプションの sysctl コンテキストへのポインタ、または NULL です。 詳細は sysctl_ctx_init(9) を参照してください。 特別な作成および削除のシーケンスが要求されるのでなければ、 作成する動的な oid を組織するためにコンテキストを使用することを、 プログラマは強く勧告されています。 ctx が NULL でない場合には、新しく作成される oid は最初のエントリとしてこのコンテキストに 追加されます。 | |
parent | |
子の親リストの先頭である struct sysctl_oid_list へのポインタです。 | |
number | |
この oid に割り当てられる oid 番号です。 殆ど全ての場合、これは割り当て時に次の利用可能な oid 番号になる OID_AUTO に設定されるべきです。 | |
name | |
この oid の名前です。 新しく作成された oid は名前のコピーを含んでいます。 | |
kind | |
oid の種類で、 <sys/sysctl.h> ヘッダファイルの中で定義される型とアクセス値のビットマスクとして明示されます。 動的に作成された oid は常に CTLFLAG_DYN フラグが設定されます。 アクセスフラグはこの oid が読み取り専用か読み書き可能か、および 全てのユーザによってまたはスーパユーザによってのみ修正可能かを明示します。 | |
arg1 | |
oid が参照すべきあらゆるデータへのポインタ、または NULL です。 | |
arg2 | |
arg1 の大きさ、または arg1 が NULL であれば 0 です。 | |
handler | |
この oid への読み書き要求を取り扱う責任がある関数へのポインタです。 ノード、整数、文字列、および不透明なオブジェクトの操作をサポートする 幾つかの標準ハンドラが存在しています。 SYSCTL_ADD_PROC() マクロを使用して新しいハンドラを定義することも可能です。 | |
format | |
oid のフォーマットを記号的に明示する文字列へのポインタです。 このフォーマットは、表示目的のための適切なデータフォーマットを適用するために sysctl(8) によってヒントとして使用されます。 現在使用されているフォーマット名は以下のとおりです。 "N" はノード、 "A" は char * 型、 "I" は int 型、 "IU" は unsigned int 型、 "L" は long 型、 "LU" は unsigned long 型、および "S,TYPE" は struct TYPE 構造体です。 | |
descr | |
この oid の解説テキストへのポインタです。 | |
sysctl_move_oid() 関数は存在している oid の親を付け変えます。 その oid は、まるで number に OID_AUTO が設定されて作成されたかの様に、新しい番号を割り当てられます。
sysctl_remove_oid() 関数は動的に作成された oid をツリーから削除し、 オプションでそのリソースを解放します。 これは以下の引数を取ります。
oidp | |
削除されるべき動的な oid へのポインタです。 oid が動的でない、またはポインタが NULL の場合には、この関数は EINVAL を返します。 | |
del | |
0 でない場合には、oid の参照カウントが 0 になった時に、 sysctl_remove_oid() は oid のリソースを解放しようとします。 しかしながら del が 0 に設定されている場合には、このルーチンは oid のリソースの解放をせずに ツリーから oid の登録抹消のみを行ないます。 この振舞いは、呼び出し側が後で (ひょっとすると部分的に失敗する) 多数の oid の 削除のロールバックを予期している時に、有用です。 | |
recurse | |
0 でない場合には、そのノードとその子を削除しようとします。 recurse が 0 に設定されている場合には、あらゆる子を含むノードの削除の試みは ENOTEMPTY エラーを発生させます。 警告: 再帰的な削除は非常な注意を払って使用すること ! 通常、コンテキストが使用されていれば、必要とされるべきではありません。 コンテキストはツリーの利用者間の依存性の追跡に注意しています。 しかしながら、ある極端な場合には、ある他のリソースを解放するために、 それがどのように作成されたものであれ、サブツリーの一部を削除することが 必要になることがあります。 しかしながら、このことは、別のコードセクションが削除されたサブツリーを 使用し続ける場合に、システムの panic(9) を引き起こすことがあることを知っていてください。 | |
再度言いますが、殆んどの場合、作成された oid を見失わないようにするため、 および後で整然とした流儀でそれらを削除するため、 sysctl_ctx_init(9) で解説されているように、プログラマはコンテキストを使用するべきです。
与えられた型の oid の作成を助ける定義済みのマクロセットがあります。 それらを以下に示します。
SYSCTL_ADD_OID() | |
は生の oid を作成します。 このマクロは機能的には sysctl_add_oid() 関数と同等です。 | |
SYSCTL_ADD_NODE() | |
は型 CTLTYPE_NODE の oid を作成します。 この oid に対して、子の oid を追加可能です。 | |
SYSCTL_ADD_STRING() | |
は 0 で終端された文字列を取り扱う oid を作成します。 | |
SYSCTL_ADD_INT() | |
は int 変数を取り扱う oid を作成します。 | |
SYSCTL_ADD_UINT() | |
は unsigned int 変数を取り扱う oid を作成します。 | |
SYSCTL_ADD_LONG() | |
は long 変数を取り扱う oid を作成します。 | |
SYSCTL_ADD_ULONG() | |
は unsigned long 変数を取り扱う oid を作成します。 | |
SYSCTL_ADD_OPAQUE() | |
は size_t * へのポインタである len 引数によって明示された大きさのあらゆる不透明なデータのかたまりを 取り扱う oid を作成します。 | |
SYSCTL_ADD_STRUCT() | |
は struct TYPE 構造体を取り扱う oid を作成します。 format 引数は sysctl(8) ユーティリティへの適切なヒントを提供するために "S,TYPE" に設定されます。 | |
SYSCTL_ADD_PROC() | |
は明示された handler ハンドラ関数を持つ oid を作成します。 ハンドラは oid に対しての読み書き要求を取り扱う責任を持ちます。 カーネルデータが簡単にアクセスできない場合、または取り出される前に処理される 必要がある場合に、この oid 型は特に有用です。 | |
#include <sys/sysctl.h> ... /* 新しく作成したサブツリーへのポインタは、後でそれらを解放するために * 保存しておく必要があります。 */ struct sysctl_oid *root1, *root2, *oidp; int a_int; char *string = "dynamic sysctl"; ...root1 = SYSCTL_ADD_NODE( NULL, SYSCTL_STATIC_CHILDREN(/* tree top */), OID_AUTO, "newtree", CTLFLAG_RW, 0, "new top level tree"); oidp = SYSCTL_ADD_INT( NULL, SYSCTL_CHILDREN(root1), OID_AUTO, "newint", CTLFLAG_RW, &a_int, 0, "new int leaf"); ... root2 = SYSCTL_ADD_NODE( NULL, SYSCTL_STATIC_CHILDREN(_debug), OID_AUTO, "newtree", CTLFLAG_RW, 0, "new tree under debug"); oidp = SYSCTL_ADD_STRING( NULL, SYSCTL_CHILDREN(root2), OID_AUTO, "newstring", CTLFLAG_RD, string, 0, "new string leaf");
この使用例は以下のサブツリーを作成します。
debug.newtree.newstring newtree.newint
これ以上必要でなくなった全ての oid は解放されるべきであることに注意!
ツリー上の多くの操作はリンクリストを横切ることを必要とします。 この理由のため、oid の作成と削除は相対的にコストがかかります。
SYSCTL_ADD_OID (9) | July 15, 2000 |
総合手引 | セクション 9 | English | オプション |
このマニュアルページサービスについてのご意見は Ben Bullock にお知らせください。 Privacy policy.
“ | Unix is the answer, but only if you phrase the question very carefully. | ” |
— Belinda Asbell |