2009年3月 のアーカイブ

言いだしっぺの法則(謎)に基づきFreeNASのスクリプトを提供開始しました

2009年3月28日 土曜日

追記:
r4531からFreeNAS本家trunkにマージされているので、ダウンロードは本家のnightly buildからできます。
http://sourceforge.net/project/showfiles.php?group_id=151951&package_id=229704

このスクリプトはテスト目的の為だけに作成してあります。
もしかしたら不具合が何かあるかもしれません。
しばらくここを見ている人には自明ですが、istgtではデバイスのサポートは
していませんのでファイル形式でエクステントを作成します。

最低限機能すると思われる特徴:
 o MCS/MPIOを使ったフェイルオーバー (最大255並列セッション)
 o マルチパスI/O (Microsoft MPIOとVMware ESXiのみサポート)
 o クラスタノード向けのSPC-3永続的装置予約
 o 2TBを超える媒体を扱える64bit LBA
 o CRC32Cによるヘッダ及びデータダイジェスト
(実験的実装)
 o Intel PRO/1000 Server Adaptersを使ったiSCSIブート機能
 o Windows7対応の準備

既存GUIからは設定できない機能:
 o 双方向または単方向CHAP認証
 o 複数のLUNおよびACL
(実験的実装)
 o コマンドキューイング (最大255の深さ)
 o 仮想DVDROM/DLTエミュレータ
 o パススルーデバイス (DA/SA/CD型のみサポート)

必要なもの:
(FreeNAS r4498/FreeBSD 7.1p4/istgt 20090326でテスト済み)
FreeNAS 0.7
FreeBSD 7.1 またはそれ以降
istgt 20090326 またはそれ以降
FreeNAS 0.7x用のistgt起動用スクリプト
http://shell.peach.ne.jp/~aoyama/wordpress/download/istgt-20090326-freenas.sh.gz
iSCSI initiator 2.1.1 またはそれ以降 (FreeBSD 7.xから利用する時のオプション)
http://www.cs.huji.ac.il/~danny/ftp/freebsd/iscsi-2.1.1.tar.gz

スクリプト使用上の制限:
 o 認証ファイルと制御用設定ファイルは空でないと更新されません。
 (変更が必要な場合は、削除した後に/etc/rc.d/iscsi_targetを起動してください)
 o マルチコネクション(MCS)、マルチパス(MPIO)が必要な場合は、
 すべてのインターフェースに固定IPを設定してください。
 o 許可するネットワークにはMCS/MPIOで利用するすべてのIPが
 含まれるように設定します。iscsi-targetは一個しか設定できないので、
 複数IPを利用する場合は注意が必要です。
 o 待ち受けポートは固定の1個になっています。iscsi-tagetには当該する
 機能が存在しません。

 

istgtインストール:
FreeBSD 7.xのマシンで以下を実行します。
1)Portsを最新版に更新します。(この記事を作成時点で20090326が最新です)
# portsnap fetch update

2)istgtのパッケージを作成します。
# cd /usr/ports/net/istgt
# make package -DNOPORTDOCS

3)作成した物をFreeNASをインストールしたマシンにコピーします。
# scp istgt-20090326.tbz user@host:/path

4)スクリプトを取得して(伸張して)、FreeNASにコピーします。
# fetch /path/to/istgt-20090326-freenas.sh.gz
# gunzip istgt-20090326-freenas.sh.gz
# scp istgt-20090326-freenas.sh user@host:/path

FreeNAS 0.7のマシンで以下を実行します。
1)パッケージを追加します。
# pkg_add istgt-20090326.tbz

2)NetBSD iscsi-targetを停止します。
(止める前にすべてのドライブをイニシエータからログオフします)
# /etc/rc.d/iscsi_target stop

3)起動用スクリプトをistgtのFreeNAS修正版で置き換えます。
# cd /etc/rc.d
# mv iscsi_target iscsi_target.old
# chmod -x iscsi_target.old
# cp /path/to/istgt-20090326-freenas.sh iscsi_target
# chmod 755 iscsi_target

4)istgtを開始します。
# /etc/rc.d/iscsi_target start

このステップまで終わるとGUIからiSCSIサービスの制御が可能になります。
設定ファイルは/var/etc/iscsiの中に作成されます。
まだiSCSIターゲットを有効にしていない場合はGUIから設定します。

※ 初回起動時にドライブがオフラインのまま認識されない事があります。
識別用の数値がiscsi-targetと違う為なので、手動でオンラインにしてください。

 

istgtアンインストール:
FreeNAS 0.7のマシンで以下を実行します。
1)iSCSIサービスを停止します。
# /etc/rc.d/iscsi_target stop

2)istgt用スクリプトを削除して、元のファイルに戻します。
# cd /etc/rc.d
# rm iscsi_target
# mv iscsi_target.old iscsi_target
# chmod +x iscsi_target

3)パッケージを削除します。
# pkg_delete istgt-20090326

4)NetBSD iscsi-targetを開始します。
# /etc/rc.d/iscsi_target start

 

追記:
FreeNASの本家リポジトリには20090309版がexperimentalにr4442より
コミットされていますが、ブログで書いた通り初期版から20090313版までの
MCS複数接続において根本的な設計ミスが見つかっています。
そのため最低でも20090314版(同期I/Oのみの最終版)を、
できれば20090326版以降(非同期I/O対応版,同期I/O部分は
20090314相当)が推奨です。

#ドキュメントがまったくないので設定難しいよって意見が(汗)

FreeNASでコマンドキューイングを試したい場合は
起動スクリプトとしてコピーしたiscsi_targetの222行目の部分を

-v "concat('  QueueDepth ','0')" -n \
↓
-v "concat('  QueueDepth ','16')" -n \

このように数値0を16に修正します。この数値を極端に大きくしても
消費メモリが増えるだけで現時点ではあまり意味はありません。

istgt (iSCSI target) 20090326版 for FreeBSD 7.x with ZFS

2009年3月27日 金曜日

更新>istgt 2009/4/12版

ワイルドカードアドレスの利用がサポートされました。
接続があったIPアドレスに自動置換するため任意のIPアドレスで
待ち受けできるようになりました。
これによりDHCP環境でもより楽に運用できるかと思います。
なおDiscoveryセッションにおけるSendTargetsの場合はIPv6とIPv4が
区別されるので、設定で両方指定してもTargetAddressとして、
どちらか一方しか返しません。

コマンドキューの利用効率が向上しました。
シーケンシャルライトやリードライトが混在する状況が改善されました。

従来はまったくコマンドの中止要求に対して何も行っていませんでしたが、
I_T/I_T_L/I_T_L_Q nexusに対してキュー内のクリアは行うようになりました。
ただし、キューから取り出して実行中のものはいずれもキャンセルできません。

前バージョンよりより安全にエラー処理ができるようになったはず?
今回からESXiにおけるマルチパスも考慮するようになりました。

新しい設定:
ポータルアドレスとして [::] と 0.0.0.0 がサポートされました。
[::]はすべてのIPv6アドレス、0.0.0.0はすべてのIPv4アドレスで接続を待ちます。

[PortalGroup1]
  Comment "ANY IP"
  # Portal Label(not used) IP(IPv6 or IPv4):Port
  Portal DA1 [::]:3260
  Portal DA1 0.0.0.0:3260

istgt (tarball): istgt-20090326.tar.gz
更新版をご利用ください。

作成方法:

# cd /path/to/work
# tar zxf /path/to/istgt-20090326.tar.gz
# cd istgt-20090326
# ./configure
# make
# make install
# make install-doc

デーモンの再起動方法:

# /usr/local/etc/rc.d/istgt restart

MD5 (istgt-20090326.tar.gz) = e7c0f3ddcfcf47cc0e9ebf0010e1fa61
SHA256 (istgt-20090326.tar.gz) = 8844e2ad571d92e43a364927a35ec58d17b7f21f1978f0c8780d88d43885c07f

既知の問題:
コマンドキューから実行状態に移行したものは中止できません。
マルチイニシエータ環境でのエラー時のキュー管理がおそらく不完全です。

主な修正点:
ワイルドカードアドレスを接続IPに変換する機能を追加しました。
LUN書き込み前に保留したPDUが次のCmdSNならキューに投入するようにしました。
エラー時のデッドロックを回避するように処理を追加しました。
無効なLUNに対するエラーログを抑制しました。
タスク管理コマンドでキューをクリアするようになりました。

追記:Send-PRしたら15分でコミットされました。
メールのお返事をいくつか書いている間に終わってた。
コミッターの人いつもありがとう!

istgt (iSCSI target) 20090323版 for FreeBSD 7.x with ZFS

2009年3月23日 月曜日

更新>istgt 2009/3/26版

公開しようと準備したのにバグがあって動かなかった(汗)
20090321と20090322はなかったことに。。。
なのでちょっと遅れましたけど、コマンドキューイング対応版をアップします。

20090314をベースにコマンドキューイング対応した物をマージしました。
(正確にはリポジトリを新しく作成しました)
今後はこれをベースに修正を行います。

現時点では並列実行しない為スレッド間のオーバヘッドの方が大きくなり
シーケンシャルリード以外はキューなしより遅くなる可能性があります。
キャッシュ機能搭載まではまともに使えないかもしれない。
従来の方法にもマイナーチェンジを引き続き行っていく予定です。

コマンドキューを使ったシーケンシャルの威力はものすごくて、
先日の画像の通りMCSラウンドロビンとコマンドキューを組み合わせると、
GbE単体より平均レートで1.5倍から3倍程度の性能向上が見込める。
もちろん向上するかどうかはZFSプールとかの性能にもよる。

新しい設定:
キューの深さを各LU単位で設定できます。
現在サポートしているのはDisk型のみです。
深さ0はキューイングなしで従来と同じ仕様です。

  # Queuing 0=disabled, 1-255=enabled with specified depth.
  QueueDepth 16

※キューの深さに比例して割り当てるメモリ量が増加しますのでご注意ください。

エラー時(フェールオーバー含む)の処理がまだ完全ではない為、
デッドロックする可能性があるのでデフォルトは無効になっています。
不幸にもデッドロックしていると思われる場合はお手数ですが
デーモンの再起動をお願いします。

istgt (tarball): istgt-20090323.tar.gz
更新版をご利用ください。

作成方法:

# cd /path/to/work
# tar zxf /path/to/istgt-20090323.tar.gz
# cd istgt-20090323
# ./configure
# make
# make install
# make install-doc

デーモンの再起動方法:

# /usr/local/etc/rc.d/istgt restart

MD5 (istgt-20090323.tar.gz) = 61bd2897fdcc85dff13773100076f012
SHA256 (istgt-20090323.tar.gz) = 4de37bc360df78c6a00bcfa3b32e55fd0dc2ab4ccd9b8d9ce9657a69e070107d

現時点の仕様:
キューイングしたコマンド単位でメモリ割り当てを行い再利用しない。
キューイングしたコマンドが転送要求サイズより64KBを超える作業領域を
必要とした場合はエラーになります。
(通常はイニシエータが適切なサイズを割り当てるはずなので起こらない)
iSCSIデバイスのリードに比べてライト動作がとても遅い。

主な修正点:
MCSでCmdSNが逆順で到着した場合の待機時間を100msから1000msに変更しました。
再接続時に規定数以上接続がある場合は強制終了を発行するようになりました。
ディスク型にコマンドキューイングを実装しました。
SCSIセンスデータ領域を64Kから4Kに縮小しました。
接続専用固定バッファから各コマンド毎の独立バッファを利用できるようになりました。
LU RESETで自身の接続が消去されないようになりました。
AHSのサイズ計算を間違えていたのを修正しました。
iqn.以外にeui.とnaa.も完全指定を許可するようなりました。
小さいPDUはヘッダとデータ部分を一緒にwriteするようになりました。
エラーチェックが正しく行われていなかった問題を修正しました。


20090323での比較(別ドライブ)
コマンドキューの深さを0と16の場合で比べると以下のようになります。
0の場合は従来とほぼ同じ性能のはずです。

MCS/ラウンドロビン/1000MB/コマンドキュー16個

MCS/ラウンドロビン/1000MB/コマンドキュー0個(無効)

MCS/ラウンドロビン/100MB/コマンドキュー16個

MCS/ラウンドロビン/100MB/コマンドキュー0個(無効)

見ての通り100MBみたいなキャッシュに乗ることが
確実な状況では差が開くもののライト動作はちょっと遅い。
(ZFS RAID-Z2のダブルパリティなので元々書き込みは遅いけど)

いろいろ遅い

2009年3月21日 土曜日


(クリックで拡大)

現時点でブロックサイズ8MBを使ってどの程度出るのか見たら210MB/sらしい。
ddでは300MB/s出ているZFSプールのiSCSIターゲットだからこれは普通だけど、
BurstRateがとっても遅い。
小さいブロックサイズでの結果もあまりよろしくない模様。
CPU Usageもすごい事に。Quadコアで29%ってことは
コア一個だと賄えないってことですね。
まぁ、Q6600っていう2.4GHzな遅いCPUですけど。

この結果から調べたのだけど、
どうもトレース関数も通るだけでかなりの負担になっている模様。
そしてこれを見て思ったけど、スレッドを分けて処理するのは
切り替えコストあがるだけであまり意味なかったような。

スレッドを2個使ったiSCSI処理

2009年3月19日 木曜日

現在細かい修正とエラーリカバリー対応を行っています。
今後のバージョンでは次のような動作をするようになります。
互換性のため従来の方法も残す方向で作業しています。

リードの場合はサイズに関係なく読み込み完了したデータとサイズを
taskに記録してソケット側に戻ってきます。
それをもとにデータとSCSI応答をイニシエータに返します。

ライトの場合はFirstBurstLength(デフォルト64KB)以下ならば
コマンドと一緒にデータも届くので、書き込みして完了したサイズを
taskに記録してソケット側に戻ってきます。
それをもとにSCSI応答をイニシエータに返します。

FirstBurstLength(デフォルト64KB)を超えるならば
追加データをイニシエータから受け取り、
まとめて一回で書き込みして完了したサイズを
taskに記録してソケット側に戻ってきます。
それをもとにSCSI応答をイニシエータに返します。

現在の仕様を流れ的に書くと以下のような感じで、
リードと64KB以下のライトはそんなに問題はない(と思う)。
でもtranscとexeccを待っている間にコネクションが死ぬと
LUNがデッドロックになりそうな流れ(汗)。
まだ改善の余地がある(と思う)。
少なくともデータOUTフェーズでパケットをキューにも
順次いれないとMCSの場合相当待たされてしまう可能性がある。
特にライトキャッシュ機能のない現状ではLUNライトが
実際にどの程度時間がかかるのかはOS(FS)次第だから。
ライトが遅いのはこのせいではないかと思っている。(未検証)

注意:現在のistgt仕様ではMCSの場合はSocketI/Oスレッドが複数になります。

----------------------------------------------------------------------
リード要求または64KB(FirstBurstLength)以下のライト要求の場合
              +---------------------------------------------+
              | istgt                                       |
Initiator       Socket I/O          Disk I/O(LUNs)
                                   wait(cmdc,cmdq)
iSCSI PDU ---> poll
(Read or       read(socket)
 Write <=FB)   create(task)
               lock(cmdq)
               enqueue(task)  ===>
               unlock(cmdq)
               signal(cmdc)   ---> wakeup
                                    (wait lock)
                                   lock(cmdq)
                                   dequeue(task)
                                   unlock(cmdq)
                                   lock(LU)              XXX
                                   execute(SCSI CDB)
                                   unlock(LU)            XXX
                                   lock(taskq)
                              <=== enqueue(task)
                                   unlock(taskq)
               poll           <--- write(pipe)
               read(pipe)
               lock(taskq)
               dequeue(task)
               unlock(taskq)
if Read
READDATA  <--- DATAIN(task)
endif
          <--- RESPONSE(iSCSI)
               destroy(task)
              | istgt                                       |
              +---------------------------------------------+
----------------------------------------------------------------------
64KB(FirstBurstLength)を超えるライト要求の場合
              +---------------------------------------------+
              | istgt                                       |
Initiator       Socket I/O          Disk I/O(LUNs)
                                   wait(cmdc,cmdq)
iSCSI PDU ---> poll
(Write >FB)    read(socket)
               create(task)
               lock(cmdq)
               enqueue(task)  ===>
               unlock(cmdq)
               signal(cmdc)   ---> wakeup
                                    (wait lock)
                                   lock(cmdq)
                                   dequeue(task)
                                   unlock(cmdq)
                                   lock(trans)
                                   lock(taskq)
                              <=== enqueue(task)
                                   unlock(taskq)
               poll           <--- write(pipe)
               read(pipe)          wait(transc,trans)
               lock(taskq)
               dequeue(task)
               unlock(taskq)
               lock(trans)
WRITEDATA ---> DATAOUT(task)
               signal(transc) ---> wakeup
                                    (wait lock)
               wait(execc,trans)
                                   lock(trans)
                                   lock(LU)              XXX
                                   execute(SCSI CDB)
                                   unlock(LU)            XXX
               wakeup         <--- signal(execc)
                (wait lock)
                                   unlock(trans)
               lock(trans)
               unlock(trans)
          <--- RESPONSE(iSCSI)
               destroy(task)
              | istgt                                       |
              +---------------------------------------------+
----------------------------------------------------------------------
FB:    FirstBurstLength
task:  iSCSI PDU w/local buffer, mutex, status, etc

LU:    mutex for entire LU(LUNs)
cmdq:  mutex for CmdSN queue on LUN
taskq: mutex for task queue on each connection
trans: mutex for transfer/execute

transc: cond for transfer
execc:  cond for execute
----------------------------------------------------------------------

MCSでラウンドロビンした場合は
以下のようなコマンドシーケンスになります。
もちろん事の本質はMCSがマルチスレッドな事ではなく、
DATAOUTが1個しか実行できないのとCmdSN3/CmdSN6を保留する事にある。

MCSスレッド1    MCSスレッド2      LUNスレッド
  (ExpCmdSN=1 全MCSコネクション共有データ)
                CmdSN1 =========> (CmdSN1キュー格納)
  (ExpCmdSN=2 全MCSコネクション共有データ)
                                  CmdSN1実行開始
CmdSN2 =========================> (CmdSN2キュー格納)
  (ExpCmdSN=3 全MCSコネクション共有データ)
                (タスクキュー) <= タスク実行を要求
                DATAOUT(CmdSN3保留)
CmdSN4待機
                DATAOUT完了    => 完了受理
                                  LUNロック
                                  LUNライト実行
                                  LUNロック解除
                CmdSN1結果受理 <= CmdSN1実行結果
                RESPONSE          CmdSN1終了
                (タスク削除)      CmdSN2実行開始
(タスクキュー) <================= タスク実行を要求
                保留CmdSN3処理 => (CmdSN3キュー格納)
  (ExpCmdSN=4 全MCSコネクション共有データ)
CmdSN4待機解除 =================> (CmdSN4キュー格納)
  (ExpCmdSN=5 全MCSコネクション共有データ)
                CmdSN5 =========> (CmdSN5キュー格納)
  (ExpCmdSN=6 全MCSコネクション共有データ)
DATAOUT(CmdSN6保留)
 .
 .
 .

エラーリカバリー対応も結構大変になるかも。
キュー内のコマンドはもちろん現在実行中のロックも
処分しないといけないから。

最新実験結果はこんな感じ。
istgt iSCSI Target (HDDx6 ZFS RAID-Z2)

ローカルに接続したWD5000ABYSに対してはこの程度出る。

MCSのシーケンシャルリードで二本のGbEを使った場合に
二本分としてそこそこ安定して出せるようになりました。
144MB/sなら1000MBもわずか7秒で読める!
次はめざせ150MB/sという所か。

istgtに関するいろいろな事

2009年3月18日 水曜日

配布ファイルの作成をミスった。
docディレクトリを常時作成するようになってた(汗)
やはりインストール作業とディレクトリ作成を分けて
Makefileに書くのがいけないのかなぁ。
おかげでコミッターの人の手間かける羽目に。
ほんとすみません。

そうそう、FreeNAS方面にも情報を投げてみた。
将来のバージョンで取り込んでもらえるといいなぁ。

よく質問されるので、書いておきます。
istgtが現在サポートしている形式は

ZFSの通常ファイル (/pool/path/to/filename)
ZFSのエミュレートボリューム (/dev/zvol/pool/path/to/volname)
USFの通常ファイル (/path/to/filename)

の3個です。
直接デバイス(/dev/ad1)みたいなものはサポート外です。

現在の進捗はというと・・・

以下のような関数を使ってスレッド間同期をとって転送しようと
試しているのだけどうまくいかない。。。

pthread_mutex_lock
pthread_mutex_unlock
pthread_cond_wait
pthread_cond_broadcast

デッドロックの危険性てんこ盛りな感じが。
しかも変更前よりだいぶ遅くなった(汗)
唯一、シーケンシャルリードだけあがったけどあまり意味ない。
しかも10個まで受け付けるのに3個までしかキューにはいらない。

MCS/ラウンドロビン/1000MB/コマンドキュー10個

参考用(20090304の結果):
http://shell.peach.ne.jp/aoyama/archives/329

istgt (iSCSI target) 20090314版 for FreeBSD 7.x with ZFS

2009年3月15日 日曜日

更新>istgt 2009/3/23版

MCS接続における既存セッションの取得方法に問題がありました。
調査した所、最初のセッション構造体の設計時点ですでに問題がありました。
TSIHが同一になるのはデーモン起動時もしくは同数の接続・切断が行われた時
なので修正版を再起動した場合に発現する可能性がありました。

原因:
既存セッションの検索時にポータルタグとイニシエータポート
(イニシエータ名+ISID)とTSIHのみチェックしていた為

影響を受ける環境:
o MCS接続を利用して、かつ同一イニシエータから同一ポータルグループに
2個以上の接続があり、かつTSIHが同一の場合

影響を受けない環境:
o MCSを利用していない場合
o 同一ポータルグループに複数のターゲットを定義していない場合
o 同一イニシエータで1接続(1セッション)のみの場合

さらに気が向いたのでNetBSDではどんなものかと見てみた。
NetBSD 5.0 RC2 i386では
srandomdev
pthread_yield
の関数が存在しないですね。
コンパイルすらできないのは悔しいので、修正してみた。
configureを最初から使ったのは正解だったみたいだ。
NetBSDへの移植もすごい楽だった。
CAMがない場合にパススルーデバイスをサポート外にするようした。

実際に試してみたら、セッションロックのミスを発見!
二重ロックした上にエラー時に解放忘れてる(汗)
せっかくなので、問題になりそうな部分も修正。
20090313をNetBSD用に改善したものをFreeBSD側にマージして修正。

これでCAMを使っているパススルーデバイスを除くデバイスに対して、
少なくともファイル形式はNetBSD 5.0 RC2 i386でも動作する。
もちろん動作検証していないので、利用する時は自己責任でよろしく。
むしろNetBSDはiscsi-targetが最初から入っているからわざわざ外部に持つ意味ないよね。

istgt (tarball): istgt-20090314.tar.gz
更新版をご利用ください。

作成方法:

# cd /path/to/work
# tar zxf /path/to/istgt-20090314.tar.gz
# cd istgt-20090314
# ./configure
# make
# make install
# make install-doc

デーモンの再起動方法:

# /usr/local/etc/rc.d/istgt restart

MD5 (istgt-20090314.tar.gz) = 1de82ab37a420332cc2bd9e295de120a
SHA256 (istgt-20090314.tar.gz) = 1f75eaa2e9152257a16e94b250aff3302e076e03a6ccc4ce9cb749bbff9f688e

主な修正点:
同一のポータルタグ、イニシエータからMCS接続した時の問題を修正しました。
CAMライブラリがない場合もコンパイルできるように修正しました。
NetBSDに存在しない関数を置き換えました。

istgt (iSCSI target) 20090313版 for FreeBSD 7.x with ZFS

2009年3月14日 土曜日

更新>istgt 2009/3/14版

さすがにドキュメントなしはまずいだろうと思ったので簡単な物を追加しました。
日本語版はブログにポストしたものと同じです。

istgt (tarball): istgt-20090313.tar.gz
更新版をご利用ください。

作成方法:

# cd /path/to/work
# tar zxf /path/to/istgt-20090313.tar.gz
# cd istgt-20090313
# ./configure
# make
# make install
# make install-doc

デーモンの再起動方法:

# /usr/local/etc/rc.d/istgt restart

MD5 (istgt-20090313.tar.gz) = a1409c2a3e0073b8eedd070dadd682fa
SHA256 (istgt-20090313.tar.gz) = f9ba10bd69e6c667bcaf52ff0dd5bd302c3d5ea88a30a9e0d1aabd1ef89edf58

主な修正点:
パススルーにシーケンシャルデバイスを追加しました。
CAMエラーを正しく処理できていなかったのを修正しました。
簡単なドキュメントを添付しました。

istgt.confの設定とistgtデーモンの起動

2009年3月13日 金曜日

Portsからでもtarballからでもインストールを実行すると、
デフォルトで/usr/local/etc/istgtの中にサンプル定義ファイルが
作成されますのでこれをコピーして起動用の設定を作成します。

# cd /usr/local/etc/istgt
# cp auth.conf.sample auth.conf
# cp istgt.conf.sample istgt.conf
# cp istgtcontrol.conf.sample istgtcontrol.conf

最低修正が必要な場所は以下の3箇所です。
[PortalGroup1] のサーバIPアドレス
[InitiatorGroup1] のイニシエータ名とネットマスク
[LogicalUnit1] のLUN0に割り当てる領域とサイズ

[PortalGroup1]
  Portal DA1 192.168.2.36:3260
↑192.168.2.36を利用するサーバのIPアドレスに変更します。
3260は標準のiSCSIポート番号なので通常は変更する必要はありません。

[InitiatorGroup1]
  InitiatorName “iqn.1991-05.com.microsoft:saturn”
  Netmask 192.168.2.0/24
↑接続を許可するイニシエータ名とIPアドレスまたはCIDR表記に変更します。
任意の名前やIPを許可するには特殊ワード ALL を指定します。

[LogicalUnit1]
  LUN0 Storage /tank/iscsi/istgt-disk1 10GB
↑サンプルではファイル形式(/tank/iscsi/istgt-disk1)で
10GBを割り当てるようになっています。
環境に合わせてパスを変更し、ディスクの容量を指定します。
単位はMBやTBで指定することも可能です。

設定できたら起動スクリプトを使ってデーモンを起動します。

# /usr/local/etc/rc.d/istgt forcestart

初期化ルーチンのエラーは標準エラー出力に出されますが、
それ以降のエラーはsyslogに書き込むので/var/log/messagesも確認します。

正しく動くようになったら /etc/rc.conf に
istgt_enable=”YES”
を加えてサーバ起動時にデーモンも自動起動するように設定します。

LUNに対するアクセス制限は以下のように適用されます。

IG(イニシエータグループ)で指定したイニシエータが
ネットマスクで許可されたIPアドレスから、
PG(ポータルグループ)で指定したネットワークポータル(IP/ポート番号)を通して、
LU(iSCSI LUN)にアクセスした場合に許可されます。

イニシエータ名とIPアドレスの両方もしくはいずれかの設定により
許可するべき範囲を設定できるようになっています。
現時点では最低1個のアクセス許可を設定しないと起動しません。

※LUというのは元々LUN0しか想定していない時代の名残で、
本来ならLUではなくLUGになるべきかもしれません。

初期リリースがPortsにコミットされました

2009年3月11日 水曜日

正確には初期リリースの1個修正後の20090223版だけど。
http://www.freshports.org/net/istgt/
20090309版も更新要求を送ったのでそのうち取り込まれるはず。

今更だけど、manなしというのはちょっとよろしくない。
ソース展開ならREADMEが読めるけどパッケージだとまったくわからないですね。
今後は簡単な物でいいから作成しないとまずいかもしれず。
Portsインストール時にREADMEをshareに入れればよかったのかな?
なにはともあれ、どうもありがとうございました。
今後ともよろしくお願いします。

若干補足を。
ZFSは推奨要件であって、istgtの必要要件ではないです。
UFS環境下においても同様に利用できると思います。
ただし、こちらではZFSでのみOSクリーンインストール等の完全テストの実行
及び仮想マシンの格納領域として利用しています。
UFSは接続確認などの軽いテストのみです。

現行のFreeBSD iscsi initiatorでは接続できません。
Dannyさんからの情報によると、
/sys/dev/iscsi/initiator/isc_sm.c
にあるExpStSNを修正するだけで接続できるようです。

bhs->ExpStSN = htonl(sn->stat);
 ↓
bhs->ExpStSN = htonl(sn->stat+1);

この修正が取り込まれるのはいつになるかわかりませんが、
当面、istgtの検証をFreeBSDで行うには上記修正が必要です。
上記修正後、カーネルモジュール(または組み込みカーネル)
の作成及び更新を行ってください。

FreeBSD 7.1 RELp3 + fbs71-200809-hvpatch.bz2 + iscsi-2.1.tar.gz + 上記patch
の組み合わせをHyper-V仮想マシンに入れた環境から接続できる事を確認しました。

追記:
ブログを書いているうちに更新要求がコミットされたらしい。
素早い対応をしてくれたコミッターの人ありがとう!
追記:
iSCSI initiatorの新バージョンがMLで公開されました。
http://www.cs.huji.ac.il/~danny/ftp/freebsd/iscsi-2.1.1.tar.gz