スポンサーリンク

SYSCTL_ADD_OID(9) FreeBSD カーネル開発者マニュアル SYSCTL_ADD_OID(9)

名称

sysctl_add_oid, sysctl_move_oid, sysctl_remove_oid − ランタイム sysctl ツ リー操作

書式

#include <sys/types.h>
#include <sys/sysctl.h>

struct sysctl_oid *

       sysctl_add_oid(struct sysctl_ctx_list *ctx,struct sysctl_oid_list *parent, int number, const char *name,int kind, void *arg1, int arg2,int (*handler) (SYSCTL_HANDLER_ARGS), const char *format,const char *descr);
int

sysctl_move_oid(struct sysctl_oid *oidp, struct sysctl_oid_list *parent);

int
sysctl_remove_oid
(struct sysctl_oid *oidp, int del, int recurse);

struct sysctl_oid_list *
SYSCTL_CHILDREN
(struct sysctl_oid *oidp);

struct sysctl_oid_list *
SYSCTL_STATIC_CHILDREN
(struct sysctl_oid_list OID_NAME);

struct sysctl_oid *
SYSCTL_ADD_OID
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int kind, void *arg1, int arg2, int (*handler) (SYSCTL_HANDLER_ARGS), const char *format, const char *descr);

struct sysctl_oid *
SYSCTL_ADD_NODE
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int access, int (*handler) (SYSCTL_HANDLER_ARGS), const char *descr);

struct sysctl_oid *
SYSCTL_ADD_STRING
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int access, char *arg, int len, const char *descr);

struct sysctl_oid *
SYSCTL_ADD_INT
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int access, int *arg, int len, const char *descr);

struct sysctl_oid *
SYSCTL_ADD_UINT
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int access, unsigned int *arg, int len, const char *descr);

struct sysctl_oid *
SYSCTL_ADD_LONG
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int access, long *arg, const char *descr);

struct sysctl_oid *
SYSCTL_ADD_ULONG
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int access, unsigned long *arg, const char *descr);

struct sysctl_oid *
SYSCTL_ADD_OPAQUE
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int access, void *arg, int len, const char *format, const char *descr);

struct sysctl_oid *
SYSCTL_ADD_STRUCT
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int access, void *arg, STRUCT_NAME, const char *descr);

struct sysctl_oid *
SYSCTL_ADD_PROC
(struct sysctl_ctx_list *ctx, struct sysctl_oid_list *parent, int number, const char *name, int access, void *arg1, int arg2, int (*handler) (SYSCTL_HANDLER_ARGS), const char *format, const char *descr);

解説

これらの関数およびマクロは sysctl oid のランタイム (例えばモジュールの存 在期間) での作成と削除のためのインタフェースを提供します。リンカセット ( 詳細は <sys/linker_set.h> および src/sys/kern/kern_sysctl.c を参照) に基 づく代わりの方法は、各々のモジュールのロード時およびアンロード時の作成と 削除のみを可能にします。

型 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 型は特に有用です。

使用例

以下は、どのように新しいトップレベルのカテゴリを作成するか、およびどのよ うに既存の静的なノードに別のサブツリーを引っ掛けるかを示す使用例です。こ の使用例はコンテキストを使用していません。これは全ての後でそれらを解放す るといった、中間の 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 は解放されるべきであることに注意!

関連項目

sysctl(8), sysctl_ctx_free(9), sysctl_ctx_init(9)

歴史

これらの関数は FreeBSD 4.2 ではじめて登場しました。

作者

Andrzej Bialecki ⟨abial@FreeBSD.org⟩

バグ

多くのコードセクション間でノードを共有することは、時々リソースをロックす ることがある相互依存を引き起こします。例えば、モジュール B によって作成さ れた oid に対し、モジュール A がサブツリーを引っ掛けた場合には、モジュー ル B はその oid を削除できないでしょう。これらの問題は sysctl コンテキス トによって適切に取り扱われます。

ツリー上の多くの操作はリンクリストを横切ることを必要とします。この理由の ため、oid の作成と削除は相対的にコストがかかります。

FreeBSD 10.0 July 15, 2000 FreeBSD 10.0

スポンサーリンク