表 27–2 に、io プローブの引数の型を示します。引数については、表 27–1 を参照してください。
表 27–2 io プローブ引数
プローブ |
args[0] |
args[1] |
args[2] |
---|---|---|---|
start |
struct buf * |
devinfo_t * |
fileinfo_t * |
done |
struct buf * |
devinfo_t * |
fileinfo_t * |
wait-start |
struct buf * |
devinfo_t * |
fileinfo_t * |
wait-done |
struct buf * |
devinfo_t * |
fileinfo_t * |
io プローブの引数は、buf(9S) 構造体のポインタ、devinfo_t のポインタ、および fileinfo_t のポインタで構成されます。以下では、これらの構造体について詳しく説明します。
bufinfo_t 構造体は、入出力要求について説明する抽象化オブジェクトです。start プローブ、done プローブ、wait-start プローブ、および wait-done プローブ内の args[0] は、入出力要求のバッファーをポイントしています。以下は、bufinfo_t 構造体の定義です。
typedef struct bufinfo { int b_flags; /* flags */ size_t b_bcount; /* number of bytes */ caddr_t b_addr; /* buffer address */ uint64_t b_blkno; /* expanded block # on device */ uint64_t b_lblkno; /* block # on device */ size_t b_resid; /* # of bytes not transferred */ size_t b_bufsize; /* size of allocated buffer */ caddr_t b_iodone; /* I/O completion routine */ dev_t b_edev; /* extended device */ } bufinfo_t;
b_flags メンバーは、複数の状態値のビット単位の論理和であり、入出力バッファーの状態を表します。表 27–3 に、有効な状態値を示します。
表 27–3 b_flags の値
B_DONE |
データ転送が完了しました。 |
B_ERROR |
入出力転送エラーが発生しました。この値は、b_error フィールドとともに設定されます。 |
B_PAGEIO |
バッファーは、呼び出された入出力要求内で使用されています。詳細については、b_addr フィールドの説明を参照してください。 |
B_PHYS |
バッファーは、ユーザーデータ領域への物理 (直接) 入出力で使用されています。 |
B_READ |
周辺機器から主記憶へデータが読み込まれます。 |
B_WRITE |
主記憶から周辺機器へデータが転送されます。 |
B_ASYNC |
非同期入出力要求です。この要求は待機されません。非同期入出力要求が発行されても、wait-start プローブや wait-done プローブは起動しません。ただし、非同期として指定された一部の入出力要求には、B_ASYNC が設定されていないことがあります。 非同期入出力サブシステムは、別のワークスレッドに非同期入出力操作を行わせることによって、非同期要求に応じることがあります。 |
b_bcount フィールドには、入出力要求の一環として転送されるバイト数が入ります。
B_PAGEIO が設定されていない場合、b_addr フィールドには、入出力要求の仮想アドレスが入ります。B_PHYS が設定されていない場合、これはカーネル仮想アドレスです。B_PHYS が設定されている場合は、ユーザー仮想アドレスです。B_PAGEIO が設定されている場合、b_addr フィールドには、カーネル非公開データが入ります。B_PHYS と B_PAGEIO は、どちらか 1 つだけを設定してください。そうしないと、両方とも設定されません。
b_lblkno フィールドは、デバイス上のどの論理ブロックがアクセスされるかを表します。論理ブロックから物理ブロック (シリンダ、トラックなど) へのマッピングは、デバイスごとに定義されています。
b_resid フィールドには、エラーのため転送されなかったバイト数が入ります。
b_bufsize フィールドには、割り当て済みのバッファーのサイズが入ります。
b_iodone フィールドは、入出力の完了時に呼び出されるカーネル内の特定のルーチンを表します。
b_error フィールドには、入出力エラーの際ドライバから返されるエラーコードが入ります。b_error が設定されるときは、b_flags メンバー内にも B_ERROR ビットが設定されます。
b_edev フィールドには、アクセス対象のデバイスのメジャーデバイス番号とマイナーデバイス番号が入ります。コンシューマは、D サブルーチン getmajor() と getminor() を使って、b_edev フィールドからメジャーデバイス番号とマイナーデバイス番号を抽出します。
devinfo_t 構造体は、デバイスに関する情報を提供します。start プローブ、done プローブ、wait-start プローブ、および wait-done プローブ内の args[1] は、入出力のターゲットデバイスの devinfo_t 構造体をポイントしています。devinfo_t は、次のメンバーから成ります。
typedef struct devinfo { int dev_major; /* major number */ int dev_minor; /* minor number */ int dev_instance; /* instance number */ string dev_name; /* name of device */ string dev_statname; /* name of device + instance/minor */ string dev_pathname; /* pathname of device */ } devinfo_t;
dev_major フィールドには、メジャーデバイス番号が入ります。詳細については、getmajor(9F) のマニュアルページを参照してください。
dev_minor フィールドには、マイナーデバイス番号が入ります。詳細については、getminor(9F) のマニュアルページを参照してください。
dev_instance フィールドには、デバイスのインスタンス番号が入ります。デバイスのインスタンス番号は、マイナーデバイス番号とは別のものです。マイナーデバイス番号は、デバイスドライバの管理下にある抽象化オブジェクトです。インスタンス番号は、デバイスノードのプロパティです。デバイスノードのインスタンス番号を表示するには、prtconf(1M) を実行します。
dev_name フィールドには、デバイスを管理するデバイスドライバの名前が入ります。デバイスドライバ名を表示するには、prtconf(1M) に -D を指定して実行します。
dev_statname フィールドには、デバイス名が入ります。このデバイス名は、iostat(1M) を実行したとき出力されるデバイス名と同じです。この名前は、kstat(1M) を実行したとき出力されるカーネル統計情報の名前とも一致しています。このフィールドは、iostat や kstat の出力内容に異常があったとき、この出力を実際の入出力アクティビティとすばやく対応付けるために提供されているものです。
dev_pathname フィールドには、デバイスの完全パスが入ります。このパスを prtconf(1M) の引数に指定すると、詳しいデバイス情報を得ることができます。dev_pathname のパスには、デバイスノード、インスタンス番号、およびマイナーノードを表す要素が含まれています。しかし、統計情報名に、これら 3 つの要素全部が含まれているとはかぎりません。デバイスによっては、統計情報名がデバイス名とインスタンス番号で構成されていることがあります。デバイスによってはまた、デバイス名とマイナーノード番号で構成されていることもあります。その結果、2 つのデバイスの dev_statname は同じでも、dev_pathname は異なるということが起こり得ます。
fileinfo_t 構造体は、ファイルに関する情報を提供します。start プローブ、done プローブ、wait-start プローブ、および wait-done プローブの args[2] は、入出力関連のファイルをポイントしています。ファイル情報が存在するかどうかは、入出力要求のディスパッチ時にこの情報を提供するファイルシステムによって決まります。一部のファイルシステム、特に第三者のファイルシステムは、この情報を提供しない場合があります。また、入出力要求の発行元ファイルシステムのファイル情報が存在しない場合もあります。たとえば、ファイルシステムのメタデータへの入出力には、関連ファイルはありません。さらに、高度に最適化されたファイルシステムは、複数の互いに無関係なファイルからの入出力を集積して、単一の入出力要求を作成することがあります。このようなファイルシステムからは、入出力の大部分を表現するファイルまたは入出力の「一部」を表現するファイルのファイル情報が提供されることがあります。また、このようなファイルシステムからファイル情報がまったく提供されないこともあります。
以下に、fileinfo_t 構造体の定義を示します。
typedef struct fileinfo { string fi_name; /* name (basename of fi_pathname) */ string fi_dirname; /* directory (dirname of fi_pathname) */ string fi_pathname; /* full pathname */ offset_t fi_offset; /* offset within file */ string fi_fs; /* filesystem */ string fi_mount; /* mount point of file system */ } fileinfo_t;
fi_name フィールドには、ファイル名だけが入ります。ここには、ディレクトリ要素は含まれません。入出力に関連ファイル情報がない場合、fi_name フィールドには文字列 <none> が入ります。まれに、ファイルのパス名が未知であることもあります。この場合、fi_name フィールドには文字列 <unknown> が入ります。
fi_dirname フィールドには、ファイル名のディレクトリ要素だけが入ります。fi_name の場合と同じく、ファイル情報が存在しない場合、この文字列は <none> になります。ファイルのパス名が未知である場合、この文字列は <unknown> になります。
fi_pathname フィールドには、ファイルの完全パス名が入ります。fi_name の場合と同じく、ファイル情報が存在しない場合、この文字列は <none> になります。ファイルのパス名が未知である場合、この文字列は <unknown> になります。
fi_offset フィールドには、ファイル内のオフセットが入ります。ファイル情報が存在しない場合や、ファイルシステムがオフセットを指定していない場合は、-1 が入ります。