LinuxにおけるSCSIプログラミング

Download Report

Transcript LinuxにおけるSCSIプログラミング

LinuxにおけるSCSI
プログラミング
sg3-utilsソースコード解読
SCSI規格の規定

大まかに以下の3層に分かれる
– 物理層
– プロトコル層
– コマンド・セット
メディアチェンジャー
共通コマンド
シーケンシャル・アクセス
ダイレクト・アクセス
ファイバーチャネル
プロトコル
シリアルSCSI
パラレルSCSI
シングル・エンド
物理・電気層
ディファレンシャル
ケーブル
コネクタ
LinuxでのSCSI制御

大まかに以下の3層に分かれる
– 「高」レベルレイヤがSCSI規格のコマンド・セットの
部分に接している
– 「低」レベルレイヤがプロトコル層や物理・電気層に
接している
– 「中間」レベルは「高」レベルと「低」レベルに共通の
サービス層を提供する
• アプリケーションレベルの開発ではこれらの「高」レベルレ
イヤのドライバを用いて開発を行う。
SD(ディスクドライバ)
「高」レベル
SR(CDROM等ドライバ)
ST(テープドライバ)
「中間」レベル
「低」レベル
SG(汎用ドライバ)
LinuxでのSCSIプログラミング

SD(ディスクドライバ)・SR(CDROMまたはDVDド
ライバ)・ST(テープドライバ)での開発
– 開発が可能であればこれらのドライバを使って開発し
たほうが楽。

以下の場合はSGドライバを使って開発
– 細かいSCSI制御が必要な場合。
– 上記以外の種類のSCSI機器を制御しなければいけ
ないとき。(例:テープライブラリ)
SGドライバを用いたのプログラ
ム開発の手法

最小限必要なincludeファイル
– /usr/include/scsi/scsi.h
• SCSIコマンドやステータス・バイト(コマンドの返り
値)等を定義
– /usr/include/scsi/sg.h
• SGデバイスとアクセスするためのioctlシステム
コールの引数を定義
プログラム開発の大まかな開発
手順

SGデバイスをopen(2)をO_RDWRのflagを付け
て開く。
– (Read onlyのデバイスでもO_RDWRを付ける)

sg_io_hdr構造体を初期化してioctlシステムコー
ルを呼び出す。
 SGデバイスをcloseする。
 エラーが発生したときの具体的内容はsg_io_hdr
構造体に保持されているので、エラー発生時に
はsg_io_hdr構造体の中身を見て処理をする。
少し楽に開発するには
このままではエラー処理が大変面倒
 sg3-utilsのソースコードにある以下のファイルを
用いると開発が楽になる。

– sg_linux.inc.h
• sg.hとscsi.hが/usr/include/scsiディレクトリに無い場合でも
コンパイル出来るようにする為のラッパーファイル
– sg_io_linux.h・sg_io_linux.c
• SCSIコマンド実行後の返り値
• エラー発生時のエラー処理をするための関数等を定義した
ファイル(Linux依存)
– sg_lib.h・sg_lib.c
•
•
•
•
CDB(後で説明)で定義されている情報を処理するコマンド
SCSIコマンドやステータス・バイトの定義
SCSIコマンドで入出力に使われるメモリを処理するコマンド
SCSI処理でエラーが発生したときに出力されるSense Data
を処理するコマンド等を定義したファイル(Linux非依存)
更に楽にするには
殆どSCSIコマンドを呼び出すだけ
 Linux以外のOSにも移植出来るようになる。

– sg_pt.h・sg_pt_linux.c
• sg_pt.hはさまざまなOSで同じ関数名で呼び出す
ためのインクルードファイル
• sg_pt_linx.c(sg_pt_freebsd.c・sg_pt_solaris.c・
sg_pt_osf1.c・sg_pt_win32.c)はその実際の処理
の記述したファイル。
– sg_cmds.h
• sg_cmds_basicおよびsg_cmds_extraの両方の
インクルードファイルを呼び出すファイル
更に楽にするには

(続き)
– sg_cmds_basic.h・sg_cmds_basic.c
• SCSIコマンドの中で比較的良く使われるコマンド
およびファイルのオープン・クローズ・エラー出力処
理を定義したファイル
– sg_cmds_extra.h・sg_cmds_extra.c
• SCSIコマンドの中で比較的使われる頻度が少な
いコマンドを定義したファイル
sg_io_hdr_tで設定するデータ

1)CDB(Command Descriptor Block )
– イニシエータ(SCSIボード)からターゲット
(SCSI機器)に操作要求を伝えるためのコマン
ド情報を示す。大体6・10・12バイトの大きさ。
必ず先頭バイトがオペレーションコード最終バ
イトがコントール・バイトとなる。
– サポートするSCSIコマンドはSCSI機器毎で異
なる。詳しくはそれぞれのSCSI機器のハード
ウェアマニュアルを参照する。
sg_io_hdr_tで設定するデータ

1)CDB(続き)
– コマンドの先頭アドレスとコマンドの長さを
sg_io_hdr_tの以下のメンバに設定
• cmd_len
– CDBを保持する配列の長さ
• cmdp
– CDBを保持する配列を指すポインタ
sg_io_hdr_tで設定するデータ

2)SCSIコマンドで受け渡しするメモリ上のデータ
– SCSIコマンドでデータを送るとき
• 送るデータ内容の配列を設定する。
– SCSIコマンドでデータを受け取るとき
• 受け取るデータの配列を初期化しておく。
– どちらもデータの先頭アドレスとデータの長さを
sg_io_hdr_tのメンバに設定する。
– SCSIコマンドでデータを受け取とったときの配列の長
さはCDBのデータとして返される。
sg_io_hdr_tで設定するデータ

2)SCSIコマンドで受け渡しするメモリ上のデータ
– dxfer_direction
• SCSIコマンドを使って遣取りをするデータの流れる方向
SG_DXFER_NONE
データのやり取りをしない
SG_DXFER_TO_DEV
イニシエータ→ターゲット
SG_DXVER_FROM_DEV
ターゲット→イニシエータ
SG_DXFER_TO_FROM_DEV ターゲット←→イニシエータ
sg_io_hdr_tで設定するデータ

2)SCSIコマンドで受け渡しするメモリ上のデータ
– SG_DXFER_TO_DEV
•
•
•
•
•
•
•
•
•
•
•
•
•
mode select (6)
mode select (10)
log select
set target port group
send diagnostic
set identifying information
format unit
reassign blocks
persistent reserve out
write long(10)
write long(16)
verify (10)
write buffer
sg_io_hdr_tで設定するデータ

2)SCSIコマンドで受け渡しするメモリ上のデータ
– SG_DXFER_FROM_DEV
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
inquiry
read capacity (16)
read capacity (10)
mode sense (6)
mode sense (10)
request sense
report luns
log sense
report target port group
receive diagnostic results
read defect (10)
read media serial number
report identifying information
get configuration
persistent reservation in
read long (10)
read long (16)
read buffer
sg_io_hdr_tで設定するデータ

3)Sense Data
– SCSIコマンドがエラーを起こしたときに機器
の」メモリに保存されたエラー情報
• 発生時に自動的にsg_io_hdr_tのメンバにコピーさ
れる。
– 先頭アドレスとデータの長さはsg_io_hdr_tの
メンバにあらかじめ設定しておく
ioctlの返り値
ステータス・バイトの値を返す。
 値の定義はscsi.hの中で定義されている。
