Linux SCSI サブシステムの徹底調査

階層型 SCSI アーキテクチャーの紹介

SCSI (Small Computer Systems Interface) は多数のデバイス (主にストレージ関連のデバイス) と通信するためのインターフェースおよびプロトコルを定義する標準の集合で、Linux® では SCSI サブシステムを提供し、これらのデバイスとの通信を可能にしています。Linux はディスク、CD-ROM ドライバーなどの上位レベルのドライバーを、Fibre Channel や SAS (Serial Attached SCSI) などの物理インターフェースに結び付ける階層化アーキテクチャーの格好の例です。この記事では、Linux の SCSI サブシステムを紹介し、このサブシステムの将来について検討します。

M. Tim Jones (mtj@mtjones.com), Consultant Engineer, Emulex Corp.

M. Tim JonesM. Tim Jones は組み込みソフトウェアのエンジニアであり、『GNU/Linux Application Programming』や『AI Application Programming』、それに『BSD Sockets Programming from a Multilanguage Perspective』などの著者でもあります。技術的な経歴は静止軌道衛星用のカーネル開発から、組み込みシステム・アーキテクチャーやネットワーク・プロトコル開発まで、広範にわたっています。また、コロラド州ロングモン所在のEmulex Corp. の顧問エンジニアでもあります。



2007年 11月 14日

それぞれの環境で同じような特性を持つ GNU/Linux と SCSI はぴったりの組み合わせです。GNU/Linux はセキュアで信頼性の高いオペレーティング・システムで、停止することなく稼動します。そして SCSI は信頼性とパフォーマンスに優れたストレージにはうってつけのインターフェースです。しかも両方ともオープンソースでもあります。INCITS (International Committee on Information Technology Standards) T10 技術委員会から、さまざまな SCSI 仕様をダウンロードして読んでみてください。同様に、GNU/Linux ソースをダウンロードすれば、これらの仕様の実装を理解することができます。GNU/Linux と SCSI はそれぞれの業界で優位を占めているため、GNU/Linux の SCSI サポートが他のどのオペレーティング・システムより優れているのは当然だと言えます。

SCSI の進化

もっとも古くからのインターフェースでありながら、現在でも進化し続けている SCSI は調べるに値する興味深いインターフェースです。最初の SCSI 標準、SCSI-1 は、1979年頃に Shugart Associates により作成されました。SCSI-1 では 5MHz のデータ・クロックで動作する 8 ビットのパラレル・インターフェースを定義し、毎秒 5 メガバイト (MB/s) の最大データ転送速度を達成しました。

1985年には SCSI-2 標準が開始され、データ速度とバスの幅がそれぞれ 10MHz、16 ビットに改善されました。Fast Wide SCSI と呼ばれる SCSI-2 の最大データ転送速度は 20MB/s です。また、SCSI-1 のデータ速度にはなりますが SCSI-1 とも後方互換性を持ちます。

SCSI-3 の開発は 1993年に着手されました。SCSI-3 は、実際にはプロトコル、コマンド・セット、信号方式を定義する標準の集合です。Ultra という名前が付いた一連のパラレル SCSI 標準、そして IEEE 1394 (FireWire)、Fibre Channel、iSCSI (Internet SCSI)、新たに加わった SAS などの最近のシリアル SCSI ベースのプロトコルはいずれも SCSI-3 と俗称されています。これらの標準はストレージ・ネットワーク技術 (FC-AL、iSCSI など) の導入によってストレージの全体像を変えただけでなく、最大データ速度を毎秒 1 ギガビット (Gbit/s) を超えるまでに拡張し、アドレス可能な最大デバイス数を 100 以上に増やし、さらに 25 メートルを上回る最大ケーブル長を達成しています。図 1 に、1986年から 2007年にかけて進化した SCSI のデータ速度を示します。

図 1. SCSI データ速度の進化
SCSI データ速度の進化

SCSI のアクター

SCSI が実装する通信アーキテクチャーはクライアント/サーバー形式です。起動側がターゲット・デバイスにコマンド要求を送信し、ターゲットが要求を処理して起動側に応答を返します。起動側はホスト・コンピューターの SCSI デバイス、SCSI ターゲットはディスク・ドライブ、CD-ROM、テープ・ドライブ、あるいはエンクロージャー・サービスなどの特殊なデバイスにすることができます。


SCSI のコマンド

SCSI を転送するプロトコルは長年にわたり変更されてきましたが、SCSI コマンド・セットには今でも当初の要素が数多く残されています。SCSI コマンドは CDB (Command Descriptor Block) 内に定義されます。CDB には、実行する特定の操作を定義する操作コード、そして操作固有のパラメーターが含まれます。

SCSI コマンドはデータの読み取りと書き込み (それぞれに 4 つの変形) をサポートするだけでなく、test unit ready (デバイスが作動可能かどうか)、inquiry (ターゲット・デバイスに関する基本情報の取得)、read capacity (ターゲット・デバイスのストレージ容量の取得) 他、データ以外のコマンドも多数サポートします。ターゲット・デバイスがサポートするコマンドは(デバイスのタイプによって異なるため、起動側は inquiry コマンドによって(デバイスのタイプを識別します。表 1 は、もっともよく使われる SCSI コマンドのリストです。

表 1. 一般的な SCSI コマンド
コマンド目的
Test unit readyデバイスが転送に対応可能かどうかを問い合わせます。
Inquiryデバイスに関する基本情報を要求します。
Request sense最後に実行されたコマンドのエラー情報を要求します。
Read capacityストレージの容量情報を要求します。
Readデバイスからデータを読み取ります。
Writeデバイスにデータを書き込みます。
Mode senseモード・ページ (デバイス・パラメーター) を要求します。
Mode selectモード・ページでデバイス・パラメーターを構成します。

約 60 のコマンドが利用可能な SCSI は、広範なデバイス (ディスクなどのランダム・アクセス・デバイスやテープなどのシーケンシャル・ストレージ・デバイスを含む) に対応するコマンド機能を提供します。さらに、SCSI にはエンクロージャー・サービス (ストレージ・エンクロージャー内の電流感知および温度情報など) にアクセスするための特殊なコマンドも用意されています。詳細は、「参考文献」を参照してください。


Linux カーネル内の SCSI アーキテクチャー

図 2 に、Linux カーネル内で SCSI サブシステムが位置する場所を示します。カーネル空間の最上部にあるのはシステム・コール・インターフェース (System call interface) です。このインターフェースは、ユーザー空間からの呼び出しをカーネル空間内の該当する宛先にルーティングするための処理を行います (オープン、読み取り、書き込みなど)。仮想ファイルシステム (VFS: Virtual file system) はカーネルでサポートされる多数のファイルシステムの抽象化層で、要求を適切なファイルシステムにルーティングします。ファイルシステムのほとんどが通信に使用するバッファー・キャッシュ (Buffer cache) は、最近操作されたデータをキャッシュに入れることによって物理デバイスへのアクセスを最適化します。その下にあるのは、ベースにある各種デバイスのブロック・ドライバーが含まれるブロック・デバイス・ドライバー (Block device drivers) 層です。SCSI サブシステムは、このブロック・デバイス・ドライバーの 1 つです。

図 2. Linux カーネル内で SCSI サブシステムが位置する場所
Linux カーネル内で SCSI サブシステムが位置する場所

Linux カーネルに含まれる他の主要なサブシステムとは異なり、SCSI サブシステム (SCSI subsystem) は 3 つの明確に異なる層からなる階層化アーキテクチャーとして存在します。一番上の層は上位レベル (Upper level) と呼ばれ、SCSI のカーネルと主要なデバイス・タイプのドライバーの最上位レベルのインターフェースを表します。その下にあるのは共通層または統一層とも呼ばれる中間レベル (Mid level) です。この層には、SCSI スタックの上位レベルと下位レベル両方の共通サービス (Common services) があります。そして一番下にあるのは、SCSI に適用可能な物理インターフェースに対応する実際のドライバーを表す下位レベル (Lower level) です (図 3 を参照)。

図 3. Linux SCSI サブシステムの階層化アーキテクチャー
Linux SCSI サブシステムの階層化アーキテクチャー

SCSI サブシステムのソース (SCSI の上位レベル、中間レベル、および大量のドライバー) は ./linux/drivers/scsi にあります。SCSI データ構造は SCSI のソース・ディレクトリーと ./linux/include/scsi の両方に含まれます。


SCSI の上位レベル

SCSI サブシステムの上位レベルは、カーネルから続く最上位レベル (デバイス・レベル) のインターフェースを表します。上位レベルを構成するのは、ブロック・デバイス (SCSI ディスク・デバイスと SCSI CD-ROM デバイス) などのドライバーとキャラクター・デバイス (SCSI テープ・デバイスおよび SCSI 汎用デバイス) です。上位レベルはその上にある層 (VFS など) からの要求を受け入れて SCSI 要求に変換します。また、この層には SCSI コマンドを完了し、上の層にそのステータスを通知するという働きもあります。

SCSI ディスク・ドライバーの実装場所は ./linux/drivers/scsi/sd.c です。SCSI ディスク・ドライバーは register_blkdev を呼び出して (ブロック・ドライバーとして) 自己初期化し、scsi_register_driver を呼び出してすべての SCSI デバイスを表す関数の共通セットを提供します。ここで興味深い関数は sd_probesd_init_command の 2 つです。sd_probe は、新しい SCSI デバイスがシステムに接続されると常に SCSI の中間層から呼び出される関数です。sd_probe 関数は新しく接続されたデバイスが SCSI ディスク・ドライバーによって管理されるかどうかを判断し、そうである場合はそのデバイスを表す新しい scsi_disk 構造を作成します。一方の sd_init_command はファイルシステム層からの要求を受け取る関数で、受け取った要求を SCSI の読み取りまたは書き込みコマンドに変換します (この I/O 要求を完了するために sd_rw_intr が呼び出されます)。

SCSI テープ・ドライバーの実装場所は ./linux/drivers/scsi/st.c です。シーケンシャル・アクセス・デバイスであるこのテープ・ドライバーは、キャラクター・デバイスとしての自己登録を register_chrdev_region によって行います。SCSI テープ・ドライバーは st_probe というプローブ関数も提供します。この関数が新しいテープ・デバイスを作成して scsi_tapes と呼ばれるベクトルに追加します。SCSI テープ・ドライバーが他と異なるのは、可能であればユーザー空間から直接 I/O 転送を行うという点です。I/O 転送を直接実行できない場合、データはドライバー・バッファーを介して転送されます。

SCSI CD-ROM ドライバーの実装場所は ./linux/drivers/scsi/sr.c です。CD-ROM ドライバーは SCSI ディスク・ドライバーと同じくブロック・デバイス・ドライバーで、SCSI ディスク・ドライバーと同様の関数セットを提供します。そのうちの sr_probe 関数は、CD-ROM デバイスを表す scsi_sd 構造を作成するとともに、register_cdrom によって CD-ROM を登録します。SCSI テープ・ドライバーはまた、要求を SCSI CD-ROM 読み取り/書き込み要求に変換する sr_init_command をエクスポートします。

最後に、SCSI 汎用ドライバーの実装場所は ./linux/drivers/scsi/sg.c です。ユーザー・アプリケーションはこのドライバーを使用して SCSI コマンド (フォーマット設定、モード検出、診断コマンドなど) をデバイスに送信します。sg3utils パッケージを使用すると、ユーザー空間から SCSI 汎用ドライバーを利用することができます。このユーザー空間パッケージには、SCSI コマンドを送信してその応答を解析するための多種多様なユーティリティーが含まれています。


SCSI の中間レベル

SCSI の中間レベルは、SCSI の上位レベルと下位レベルに共通のサービス層で (一部は ./linux/drivers/scsi/scsi.c に実装されます)、上位レベルと下位レベルのドライバーが使用する多数の関数を提供し、この異なる 2 つの層の橋渡し役として機能します。この層は下位レベル・ドライバー (LLD: Low-Level Driver) の実装を抽象化するという点で重要であり、その一部は ./linux/drivers/scsi/hosts.c に実装されます。つまり、Fibre Channel のホスト・バス・アダプター (HBA) をそのインターフェースの違いに関わらず同じように使用できるということです。

下位レベルのドライバーの登録およびエラー処理は、SCSI の中間レベルによって行われます。中間レベルには、上位レベルと下位レベルの間でキューイングを行う SCSI コマンドもあります。SCSI 中間レベルの重要な側面は、上位層からのコマンド要求を SCSI 要求に変換するという点です。さらに、SCSI 固有のエラー・リカバリーも管理します。

基本的に SCSI サブシステムの上位レベルと下位レベルの橋渡し役として機能する中間層は、SCSI トランザクションの要求を受け入れて処理用のキューに入れます (./linux/drivers/scsi/scsi_lib.c を参照)。これらのコマンドが完了すると、中間層は LLD から SCSI 応答を受け取り、上位レベルに要求の完了を通知します。

中間層でとりわけ重要な側面の 1 つとして挙げられるのは、エラーおよびタイムアウトの処理です。SCSI コマンドが妥当な時間内に完了しない場合、あるいは SCSI 要求にエラーが返された場合には、中間レベルがエラーを処理して要求を再試行します。中間レベルは HBA (LLD) や SCSI デバイスのリセット要求といった上位レベルのリカバリーも管理します。SCSI エラーおよびタイムアウト・ハンドラーが実装されているのは、./linux/drivers/scsi/scsi_error.c です。


SCSI の下位レベル

最下位レベルにあるのは、SCSI LLD (Low-Level Driver) と呼ばれる一連のドライバーです。これらのドライバーが、HBA をはじめとする物理デバイスとのインターフェースをとります。LLD が提供するのは、共通中間層からデバイス固有の HBA への抽象化です。それぞれの LLD はそのベースにある特定ハードウェアへのインターフェースを提供しますが、中間層に対しては標準インターフェース・セットを使用します。

多種多様な SCSI アダプターからなる下位レベルは、もっとも多くのコードが含まれるレベルです。例えば、Fibre Channel プロトコルには Emulex や QLogic のアダプターに対応する LLD が含まれ、SAS プロトコルには Adaptec および LSI のアダプターに対応する LLD が含まれます。


Linux と SCSI の今後

確実なことが 1 つあるとしたら、それは SCSI には将来性があり、そしてその活躍の場は Linux だということです。Linux は今後も、SCSI の進化に合わせた最先端のサポートで対応していくと思います。Linux は現在、多数の HBA に対応したドライバーで新しい SAS プロトコルをサポートしています。プロトコルがさらに高速化するにつれ (6 Gb の SAS や 8 Gb の FC など)、Linux が開発およびデプロイメントの最前線に躍り出てくるはずです。

最先端の新しい SCSI プロトコルにも Linux は関与しています。なかでも言及すべきプロトコルは、FCoE (Fibre Channel over Ethernet) です。FCoE は Fibre Channel フレームを全二重 Ethernet ネットワーク (通常は 1Gb または 10Gb Ethernet) にマッピングします。極めて有力なエンタープライズ・ストレージ・プロトコルに、同じく極めて有力なネットワーク媒体を結び付ける FCoE は、重要なプロトコルです。今後の動向が注目されるこの新しい技術には、Linux が対応することでしょう。

T10 の新たなデータ・インテグリティー標準 (データ完全性の標準) によってもたらされるエンド・ツー・エンドのデータ保護も SCSI に適用される予定です。これは DIF (Data Integrity Field: データ・インテグリティー・フィールド) を各セクターに追加して媒体でのデータ保護を保守するという標準で、新しい 8 バイトの DIF フィールドにはデータを保護するための CRC (巡回冗長コード)、誤った書き込み操作を防止するための参照タグ、そしてアプリケーション・タグが組み込まれます。アプリケーション・タグはアプリケーションに固有なので、例えば PDF 文書の一部などといったデータの目的を定義することができます。詳細は、「参考文献」セクションを参照してください。


まとめ

Linux カーネルもまた、抽象化した階層化アーキテクチャーのモデル例で、タイプの異なるファイルシステムをさまざまな物理ストレージ媒体に結び付けます。これらのストレージ媒体が SCSI に関連する場合、共通した Linux のブロック要求は、SCSI サブシステムによってベースにある特定のデバイスに対する SCSI 要求に変換されます。SCSI サブシステム自体には長年にわたって多くの変更が加えられていますが、まだ変更が完了したわけではありません。エンド・ツー・エンドのデータ保護をはじめとする新しい技術も、FCoE などの新規プロトコルと同じく Linux にその活躍の場を探しているところです。

参考文献

学ぶために

  • Technical Committee T10 にアクセスして、基本的な SCSI コマンドから SAS などの最新 SCSI プロトコルに至るまで、さまざまな SCSI 仕様の詳細を学んでください。
  • Open Source Development Lab が発表しているこの記事では、2.6 カーネルと SCSI ディスク・ドライバーを重点に Linux カーネルでの SCSI 実装を掘り下げて説明しています。
  • ここにリストされた SCSI デバイスのクエリーや表示、管理を行うためのユーザー空間のツールは、Linux カーネルの SCSI ジェネリック・ドライバーを活用します (Linux は、この記事で言及した sg3utils をはじめ、多数の SCSI ツールをサポートします)。
  • Linux カーネルの徹底調査」(developerWorks、2007年6月) では、Linux カーネルの概要とその主要なサブシステムそれぞれについて説明しています。
  • Linux システム・コールを使用したカーネル・コマンド」(developerWorks、2007年3月) では、Linux カーネル内でのシステム・コール・インターフェースの詳細 (ユーザー空間呼び出しからカーネル完了まで) を説明しています。
  • Linux ネットワーク・スタックの徹底調査」(developerWorks、2007年6月) では、Linux のネットワーク・スタックの基本アーキテクチャーについて、関連する主要なコンポーネントと構造をまじえて紹介しています。
  • Linux ファイルシステムの徹底調査」(developerWorks、2007年10月) では、仮想ファイルシステム・スイッチとも呼ばれる Linux カーネルの仮想ファイルシステム (VFS) の詳細を掘り下げ、複数のファイルシステムを 1 つに束ねる主要な構造体をいくつか紹介しています。
  • FCoE (Fibre Channel over Ethernet) は、将来期待される SCSI プロトコルの 1 つです。このプロトコルはまだ利用できませんが、現在、多数のベンダーで盛んに開発が進められています。
  • DIF (Data Integrity Field) 手法に関するホワイト・ペーパーでエンド・ツー・エンドの保護についての詳細を学んでください。ディスクを保護する DIF は、誤った書き込み操作を検出し、保護を強化するためのデータをアプリケーション固有のタグに追加できるようにします。DIF はマルチベンダー技術なので、さまざまなベンダーのドライバーや HBA に DIF サポートが組み込まれています。
  • developerWorks Linux ゾーンに豊富に揃った Linux 開発者向けの資料を調べてください。記事とチュートリアルの人気ランキングも要チェックです。
  • developerWorks に掲載されているすべての Linux のヒントLinux チュートリアルを参照してください。
  • developerWorks technical events and webcasts で最新情報を入手してください。

製品や技術を入手するために

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux, Open source
ArticleID=276286
ArticleTitle=Linux SCSI サブシステムの徹底調査
publish-date=11142007