EN JA
ALQ(9)
ALQ(9) FreeBSD Kernel Developer's Manual ALQ(9)

名称

alq, alq_open_flags, alq_open, alq_writen, alq_write, alq_flush, alq_close, alq_getn, alq_get, alq_post_flags, alq_post非同期ロギングキュー

書式

#include < sys/alq.h>

int
alq_open_flags( struct alq **app, const char *file, struct ucred *cred, int cmode, int size, int flags);

int
alq_open( struct alq **app, const char *file, struct ucred *cred, int cmode, int size, int count);

int
alq_writen( struct alq *alq, void *data, int len, int flags);

int
alq_write( struct alq *alq, void *data, int flags);

void
alq_flush( struct alq *alq);

void
alq_close( struct alq *alq);

struct ale *
alq_getn( struct alq *alq, int len, int flags);

struct ale *
alq_get( struct alq *alq, int flags);

void
alq_post_flags( struct alq *alq, struct ale *ale, int flags);

void
alq_post( struct alq *alq, struct ale *ale);

解説

alq 機能は、非同期ロギングキュー (Asynchronous Logging Queues) として知られる、非同期で固定長または可変長の記録メカニズムを提供します。それは、どんな vnode(9) にも記録することができ、その結果、通常ファイルと同様にキャラクタデバイスにジャーナルログする能力を提供します。すべての関数は、非同期ロギングキュー (Asynchronous Logging Queue) のための状態情報を維持する不透明なタイプである struct alq 引数を受け付けます。このロギング機能は、すべてのログエントリの要求をサービスする個別のカーネルスレッドで実行します。

“非同期ログエントリ”は、次のメンバがある struct ale として定義されます:

struct ale { 
 intptr_t ae_bytesused; /* ALE への書き込みバイト数. 
        */ 
 char  *ae_data; /* 書き込みポインタ. */ 
 int  ae_pad;  /* 未使用, compat. */ 
};

固定長または可変長のモードで alq を作成することができます。可変長の alq は、 alq_writen() と alq_getn() を使用して異なった長さの書き込みに対応します。固定長の alq は、それぞれの固定サイズ (キュー作成時間に設定される) の alq_write() と alq_get() を使用して固定長の書き込みに対応します。固定長モードは、可変長モードを支持して推奨されません。

関数

alq_open_flags() 関数は、新しい可変長の非同期ロギングキューを作成します。 file 引数は、ロギングのためにオープンするファイルの名前です。ファイルがまだ存在していないなら、 alq_open() は、それを作成することを試みます。 cmode 引数は、ファイルが alq_open() によって作成されるなら、使用される要求された作成モードとして vn_open() に渡されます。この API のカスタマは、ほとんどのアプリケーションに適切なデフォルトの作成モードである、 ALQ_DEFAULT_CMODE を渡したいかもしれません。 cred 引数は、ファイルをオープンして I/O を実行するとき使用する資格証明を指定します。 size 引数は、基本的なキューの (バイト単位の) サイズを設定します。 ALQ_ORDERED フラグは、リソースを解放するためにビジーの alq を待つ、書き込みスレッドの順序付けが保存されるべきであることを示す flags を通して渡されます。

推奨されない alq_open() 関数は、新しい alq_open_flags() 関数を利用するように更新されていないカスタマへの後方互換性を提供するために alq_open_flags() 周りのラッパとして実装されています。それは、 sizecount を除いて、変更されない alq_open_flags() を通してすべての引数に渡され、 flags を 0 に設定します。可変長モードの alq を作成するために、 size 引数は、基本的なキューの (バイト単位の) サイズに設定されるべきで、 count 引数は、0 に設定されるべきです。固定長モードの alq を作成するために、 size 引数は、各書き込みの (バイト単位の) サイズに設定されるべきで、 count 引数は、容量を予約する size バイトのチャンクの数に設定されるべきです。

alq_writen() 関数は、 data から指定された可変長モードのキュー alqlen バイトを書き込みます。 alq_writen() が直ちにエントリを書き込みことができないで、 ALQ_WAITOKflags に設定されているなら、関数は、“ alqwnord”または“ alqwnres”待ちメッセージで msleep_spin(9) することが許可されます。書き込みは、ディスクをフラッシュするように、キュー alq を自動的にスケジュールします。書き込みがディスクをフラッシュするように、キュー alq をスケジュールするべきでないことを示すために flags を通して ALQ_NOACTIVATE を渡すことによって、この振る舞いを制御することができます。

推奨されない alq_write() 関数は、可変長モードのキューを利用するように更新されていないカスタマへの後方互換性を提供するために alq_writen() 周りのラッパとして実装されています。関数は、 data バッファから alq まで ( size がキュー作成時間に指定されたところで) size バイトのデータを書き込みます。可変長モードのキューで alq_write() を呼び出すことはエラーであることに注意してください。

alq_flush() 関数は、 alq_open() に渡されたログメディアに alq をフラッシュするために使用されます。 alq にフラッシュするデータがあり、まだフラッシュされているプロセスでないなら、関数は、I/O を行うことをブロックします。そうでなければ、関数は、直ちに返ります。

alq_close() 関数は、非同期ロギングキュー alq をクローズし、ログメディアへのすべての保留中 (pending) の書き込み要求をフラッシュします。以前に割り付けらたすべてのリソースを開放します。

alq_getn() 関数は、 len バイトのデータを受信することができるバッファを指すように初期化された、 alq から非同期なログエントリを返します。この関数は、その後の alq_post() または alq_post_flags() 呼び出しが行われるまで、ロックされた状態で、 alq をそのままにします。 alq_getn() が直ちに len バイトのバッファを得ることができないで、 ALQ_WAITOKflags に設定されているなら、関数は、“ alqgnord”または“ alqgnres”待ちメッセージで msleep_spin(9) することが許可されます。呼び出し側は、エントリの ae_bytesused フィールドを実際に書き込まれたバイト数に設定することによって返された非同期ログエントリに len バイトの未満のデータを書き込むことを選択することができます。これは、 alq_post() を呼び出す前に行わなければなりません。

推奨されない alq_get() 関数は、可変長モードのキューを利用するように更新されていないカスタマへの後方互換性を提供するために alq_getn() 周りのラッパとして実装されています。返された非同期ログエントリは、 ( size がキュー作成時間に指定されたところで) size バイトのデータを受信することができるバッファを指すように初期化されます。可変長モードキューで alq_get() を呼び出すことはエラーであることに注意してください。

alq_post_flags() 関数は、 alq へ書き込むために ( alq_getn() または alq_get() から取得された) 非同期ログエントリ ale をスケジュールします ALQ_NOACTIVATE フラグは、キューが、直ちにディスクをフラッシュするようにスケジュールすべきでないことを示すために flags を通して渡されます。この関数は、アンロックされた状態で alq をそのままにします。

alq_post() 関数は、新しい alq_post_flags() 関数を利用するように更新されていないカスタマへの後方互換性を提供するために alq_post_flags() 周りのラッパとして実装されています。それは、単に変更されない alq_post_flags() を通してすべての引数に渡され、 flags を 0 に設定します。

実装に関する注

alq_writen() と alq_write() 関数は、共に供給された data バッファから基本的な alq バッファに bcopy(3) を実行します。パフォーマンスのクリティカルコードパスは、余分なメモリーコピーを避けるために、 alq_getn() (可変長キュー) または alq_get() (固定長キュー) を使用することを検討したいかもしれません。キューは、 alq_getn() または alq_get() と alq_post() または alq_post_flags() への呼び出しの間でロックされて残るので、このキューへの書き込みのメソッドは、呼び出しの間の時間が重要である状況に適さないことに注意してください。

ロック

各非同期ロギングキューは、スピンミューテックス (spin mutex) によって保護されます。

関数 alq_flush() と alq_open() は、内部のスリープミューテックス (sleep mutex) を取得する試みを行い、したがって、スリープが許されていないコンテキストで使用されるべきではありません。

戻り値

alq_open() 関数は、 file のオープンに失敗したなら、 open(2) にリストされているエラーコードの 1 つを返し、そうでなければ、0 を返します。

alq_writen() と alq_write() 関数は、 ALQ_NOWAITflags に設定され、キューが満杯であるか、またはシステムがシャットダウンしているなら、 EWOULDBLOCK を返します。

alq_getn() と alq_get() 関数は、 ALQ_NOWAITflags に設定され、キューが満杯であるか、またはシステムがシャットダウンしているなら、 NULL を返します。

注意: void ではない関数への無効な引数は、未定義の振る舞いの結果となります。

歴史

非同期ロギングキュー (ALQ) の仕組みは、 FreeBSD 5.0 ではじめて登場しました。

作者

alq 機能は、 Jeffrey Roberson <jeff@FreeBSD.org>によって書かれ、 Lawrence Stewart <lstewart@freebsd.org>によって拡張されました。

このマニュアルページは、 Hiten Pandya <hmp@FreeBSD.org>によって書かれ、 Lawrence Stewart <lstewart@freebsd.org>によって改訂されました。

April 26, 2010 FreeBSD