KHELP(9) | FreeBSD Kernel Developer's Manual | KHELP(9) |
名称
khelp, khelp_init_osd, khelp_destroy_osd, khelp_get_id, khelp_get_osd, khelp_add_hhook, khelp_remove_hhook, KHELP_DECLARE_MOD, KHELP_DECLARE_MOD_UMA — カーネルヘルパ (helper) フレームワーク書式
#include < sys/khelp.h>#include < sys/module_khelp.h>
int khelp_init_osd( uint32_t classes, struct osd *hosd);
int khelp_destroy_osd( struct osd *hosd);
int32_t khelp_get_id( char *hname);
void * khelp_get_osd( struct osd *hosd, int32_t id);
int khelp_add_hhook( struct hookinfo *hki, uint32_t flags);
int khelp_remove_hhook( struct hookinfo *hki);
KHELP_DECLARE_MOD( hname, hdata, hhooks, version);
KHELP_DECLARE_MOD_UMA( hname, hdata, hhooks, version, ctor, dtor);
解説
khelp は、カーネル内で興味があるフックポイントがある、それらのフック関数を登録するために hhook(9) KPI を間接的に使用する、 khelp モジュールを管理するためのフレームワークを提供します。 Khelp モジュールは、方法を保持する ABI (ABI preserving manner) で実行時に動的にカーネルを拡張する構造化された方法を提供することを目標としています。フックポイントを提供するサブシステムによって、 khelp モジュールは、フック呼び出しの間の関連状態を維持するためのオブジェクト毎のデータを関連づけることができます。 hhook(9) と khelp フレームワークは、しっかり統合しています、また、 khelp に興味を持っている人はだれでも hhook(9) マニュアルページを徹底的に読むべきです。Khelp モジュール開発者への情報
khelp モジュールは、次のメンバがある struct helper によって khelp フレームワークの中に表されます:
struct helper { int (*mod_init) (void); int (*mod_destroy) (void); #define HELPER_NAME_MAXLEN 16 char h_name[HELPER_NAME_MAXLEN]; uma_zone_t h_zone; struct hookinfo *h_hooks; uint32_t h_nhooks; uint32_t h_classes; int32_t h_id; volatile uint32_t h_refcount; uint16_t h_flags; TAILQ_ENTRY(helper) h_next; };
モジュールは、 struct helper のインスタンスを作成しなければなりませんが、 h_classes フィールドのみ設定する必要があり、必要なところに h_flags, mod_init と mod_destroy フィールドをオプションで設定します。フレームワークは、他のすべてのフィールドを管理し、モジュールは、それらの操作を控えるべきです。フィールドを設定する初期化子の機能で指定された C99 を使用することは、奨励されます。
指定されるなら、 mod_init 関数は、登録プロセスを完了する前に、 khelp フレームワークによって実行されます。 mod_init 関数から 0 以外の値を返すことは、登録プロセスを中止し、モジュールのロードを失敗します。指定されるなら、 mod_destroy 関数は、モジュールが khelp フレームワークによって登録取り消しされた後に、登録取り消しプロセスの間に khelp フレームワークによって実行されます。返り値は、現在、無視されます。有効な khelp のクラスは、 < sys/khelp.h> で定義されます。有効なフラグは、 < sys/module_khelp.h> で定義されます。 HELPER_NEEDS_OSD フラグは、 khelp モジュールが永続的なオブジェクト毎のデータ記憶域を必要とするなら、 h_flags フィールドに設定されるべきです。 khelp クラスが永続的なオブジェクト毎のデータを関連づけるために khelp モジュールのための能力を提供するかどうか調べるプログラム的な方法が (まだ) ないので、手動のチェックが必要とされます。
KHELP_DECLARE_MOD() と KHELP_DECLARE_MOD_UMA() マクロは、 DECLARE_MODULE(9) マクロの周りの便利なラッパを提供し、 khelp フレームワークで khelp モジュールを登録するために使用されます。 KHELP_DECLARE_MOD_UMA() は、永続的なオブジェクト毎の記憶域の使用を必要とするモジュールによってのみ使用されるべきです、すなわち、それらの struct helper's の h_flags フィールドで HELPER_NEEDS_OSD フラグを設定するモジュールです。
両方のマクロに共通の最初の 4 つの引数は、次の通りです: hname 引数は、 khelp モジュールのためのユニークな ascii(7) 名前を指定します。それは、HELPER_NAME_MAXLEN-1 文字より長くない長さであるべきです。 hdata 引数は、モジュールの struct helper へのポインタです。 hhooks 引数は、 struct hookinfo 構造体の静的配列を指します。異なった hhook(9) ポイントのために複数回、同じフック関数を使用さえするときでさえ、配列は、モジュールがフックする必要があるそれぞれの hhook(9) ポイントに対して struct hookinfo を含むべきです。 version 引数は、 MODULE_VERSION(9) に渡されるモジュールのためのバージョン番号を指定します。 KHELP_DECLARE_MOD_UMA() マクロは、オプションの uma(9) コンストラクタとデコンストラクタ関数を指定する、追加の ctor と dtor 引数を取ります。 NULL は、機能性が必要でないところで渡されるべきです。
khelp_get_id() 関数は、名前 hname で khelp モジュールのための数値識別子を返します。
khelp_get_osd() 関数は、指定された khelp モジュールのためのオブジェクト毎のデータポインタを取得するために使用されます。 hosd 引数は、基本的なサブシステムオブジェクトの struct osd へのポインタです。これは、 khelp モジュールのフック関数に呼び出されるとき、 hhook(9) フレームワークによって提供されます。 id 引数は、 hosd からデータポインタを抽出するために khelp モジュールのための数値識別子を指定します。 id は、 khelp_get_id() 関数を使用して取得されます。
khelp_add_hhook() と khelp_remove_hhook() 関数によって、 khelp モジュールは、実行時に hhook(9) ポイントに動的にフックするが、またはアンフックすることができます。 hki 引数は、操作される hhook(9) ポイントとフック関数に関する必要な情報を要約する struct hookinfo へのポインタを指定します。 HHOOK_WAITOK フラグは、 malloc(9) が、メモリが利用可能になるのをウェートしてスリープすることができるなら、 khelp_add_hhook() の flags 引数を通して渡されます
Khelp をカーネルサブシステムに統合する
役に立つことを行うための khelp モジュールを許可するために必要なほとんどの作業は、フックするために khelp モジュールのための適切な hhook(9) ポイントを定義して、インスタンスを作成することに関連します。行う必要がある唯一の追加決定サブシステムは、 khelp モジュールが永続的なオブジェクト毎のデータを関連づけることができる必要があるかどうかということです。永続的なデータ記憶域のためのサポートを提供することで、 khelp モジュールは、望ましいより複雑な機能性を実行することできます。サブシステムのデータ構造の 1 つで永続的なオブジェクト毎のデータを関連づけるために Khelp モジュールを許可する必要があるサブシステムは、次の 2 つのキーに変更を行う必要があります:- オブジェクトのための構造体の定義に struct osd ポインタを埋め込みます。
- それぞれ、オブジェクトを初期化して、破壊することに責任があるサブシステムコードパスに khelp_init_osd() と khelp_destroy_osd() への呼び出しを追加します。
khelp_init_osd() 関数は、それらの h_flags フィールドに HELPER_NEEDS_OSD フラグを設定する適切なクラスのすべての現在ロードされた khelp モジュールのためのオブジェクト毎のデータ記憶域を初期化します。 classes 引数は、このサブシステムが関連づける khelp クラスのビットマスクを指定します。 khelp モジュールがビットマスクでクラスのどれかにマッチするなら、そのモジュールは、オブジェクトに関連付けられます。 hosd 引数は、 khelp モジュールによって使用のための永続的な記憶域を提供するためにに使用されるオブジェクトの struct osd へのポインタを指定します。
khelp_destroy_osd() 関数は、 khelp_init_osd() への以前の呼び出しによってオブジェクトの struct osd に関連したすべてのメモリを解放します。 hosd 引数は、破壊の準備で消去されるオブジェクトの struct osd へのポインタを指定します。
実装に関する注
khelp モジュールは、参照カウントによって時期尚早にアンロードされることから保護されます。カウントは、サブシステムが永続的な記憶域をモジュールのために割り付ける khelp_init_osd() を呼び出すたびに増加され、 khelp_destroy_osd() へのそれぞれ対応する呼び出しのために減少されます。モジュールの参照カウントが 0 に落ちたときだけ、モジュールをアンロードすことができます。戻り値
khelp_init_osd() 関数は、エラーが発生しなかったなら、0 を返します。オブジェクト毎の記憶域を必要とする khelp モジュールが、必要なメモリの割り付けに失敗したなら、ENOMEM を返します。khelp_destroy_osd() 関数は、エラーが発生しなかったことを示すために 0 を返すだけです。
khelp_get_id() 関数は、名前 hname で登録された khelp モジュールのためのユニークな数値の識別子を返します。指定された名前があるモジュールが、現在登録されないなら、-1 を返します。
khelp_get_osd() 関数は、 khelp モジュールの永続的なオブジェクトの記憶域のメモリへのポインタを返します。 id によって識別されたモジュールがオブジェクトの hosd struct osd で登録された永続的なオブジェクトの記憶域がないなら、NULL を返します。
khelp_add_hhook() 関数は、エラーが発生しなかったなら、0 を返します。要求された hhook(9) ポイントを見つけることができないなら、ENOENT を返します。 malloc(9) がメモリの割り付けに失敗するなら、ENOMEM を返します。同じ hhook(9) ポイントに対して 2 つ以上の同じフック関数を登録すること試みるなら、 EEXIST を返します。
khelp_remove_hhook() 関数は、エラーが発生しなかったなら、0 を返します。要求された hhook(9) ポイントを見つけることができないなら、ENOENT を返します。
使用例
よく論評された例の Khelp モジュールは、次で見つけることができます: /usr/share/examples/kld/khelp/h_example.cEnhanced Round Trip Time (ERTT) h_ertt(4) khelp モジュールは、何ができるかの、より複雑な例を提供します。
謝辞
このソフトウェアの開発とテストは、Community Foundation Silicon Valley において FreeBSD Foundation と Cisco University Research Program Fund からの助成金によって一部可能となりました。歴史
khelp カーネルヘルパ (helper) フレームワークは、 FreeBSD 9.0 ではじめて登場しました。khelp フレームワークは、 Advanced Internet Architectures、Melbourne、Australia のために Swinburne University of Technology の Centre において研究している間に、 Lawrence Stewart によって 2010 年に始めてリリースされました。その他の詳細は、次で利用可能です:
http://caia.swin.edu.au/urp/newtcp/
作者
khelp フレームワークは、 <lstewart@FreeBSD.org>によって書かれました。このマニュアルページは、
<david.hayes@ieee.org>と <lstewart@FreeBSD.org>によって書かれました。February 15, 2011 | FreeBSD |