2009年2月 のアーカイブ

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

2009年2月27日 金曜日

更新>istgt 2009/2/28版

REPORT TARGET PORT GROUPとSET TARGET PORT GROUPS
PERSISTENT RESERVE INとPERSISTENT RESERVE OUTに対応しました。
まだ未完成ではあるが、WS2008のフェールオーバークラスタにある
構成の検証で2ノードによる記憶域検証を通過します。

クラスタ時のパフォーマンスはきっとダメだろうな。<未検証
なにしろ永続予約がある場合はSCSIコマンド実行時に毎回strcmp発行してるからね。
ハッシュ値にして数値比較とかにしないときっと重い。
そもそもスレッド同期仕様だから重いのです。
早くタグ付きキューイングをサポートすべきです。

検証用の接続は以下のような構成です。
各ノードからはシングルiSCSIセッション(シングルパス)として、
ターゲットからみるとマルチセッションな状態です。
(istgt設計上はシングルパスでもMCSのフェールオーバーは可能)

+---------------+  TSIH N  +-----------+
| Cluster Node1 |----------|           |
+---------------+          |iSCSI Node |
                           | (Target)  |
+---------------+  TSIH M  |           |
| Cluster Node2 |----------|           |
+---------------+          +-----------+

TSIH: Target Session Identifying Handle

マルチパスはまだ未対応です。マルチパス接続自体はすでに可能だけど、
各ポートを常時アクティブ/最適化とマークしているので、
パス障害時にターゲット側からフェールオーバー対応できないはず。

実際の結果はこんな感じに。
Hyper-Vに作った仮想マシン同士のせいなのかVPDの検証に失敗する。

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

作成方法:

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

デーモンの再起動方法:

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

MD5 (istgt-20090227.tar.gz) = 31323dcfade9976892698387d996a48e
SHA256 (istgt-20090227.tar.gz) = a63c236eec56a3a350b65957d06f2ffb9c365b4a8f9ae0f971f107773c0da6eb

主な修正点:
ポータルグループ及びロジカルユニットグループをINQUIRYに出力するようになりました。
immediateにマークされたPDUに対してCmdSNを進めていた問題を修正しました。
認証データのメモリリークを修正しました。
SCSIコマンドのREPORT TARGET PORT GROUPSに応答するようにしました。
SCSIコマンドのSET TARGET PORT GROUPSに応答するようにしました。
SCSIコマンドのPERSISTENT RESERVE INに応答するようにしました。
SCSIコマンドのPERSISTENT RESERVE OUTに応答するようにしました。
イニシエータやターゲット名を小文字で保持するように変更しました。
ディスク型のRELEASE(6)/RELEASE(10)/RESERVE(6)/RESERVE(10)を
NOPからPERSISTENT RESERVE OUTを使ったエミュレートに変更しました。

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

2009年2月23日 月曜日

更新>istgt 2009/2/28版

公開早々問題が・・・。
Securityステージを省略するイニシエータと通信できない問題が発覚しました。
iSCSI規格上はOperationalステージから開始することも許可されているけど、
istgtでは認証チェックを通らないと処理しないように実装していました。

詳細はRFC3720(5.3)を参照のこと。
認証要求がされないという事はAuthMethod=Noneを仮定しなければいけないと言うことですな。
合わせてStatSNの同期を行っていなかった。

うーむ。なんてこったい。すっかり見逃していた。
ちなみに省略するのはFreeBSDのイニシエータでした(汗)
それでも修正してもまだ動かない。(要追加検証)

あと些細な事だけど?
起動スクリプトやサンプル設定のパスが決め打ちだった。
Ports化する際の障害になっちゃうので修正しました。
Ports化の雛形はすでに作成したので動作確認できたら公開する予定です。

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

MD5 (istgt-20090223.tar.gz) = 4db15625be7f80fb1d984703c1db59a5
SHA256 (istgt-20090223.tar.gz) = a181f68097662a3c302d4ff721cb726ef41e940e2a7b65cea047394a5a1ea664

作成方法:


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

初版リリース istgt version 0.1 20090222版 for FreeBSD 7.x with ZFS

2009年2月23日 月曜日

更新>istgt 2009/2/23版

いままでやってきた作業をまとめたのでここに初期リリースとして公開します。
configure形式で作成しましたのでtarボールを展開したのち、

# ./configure
# make
# make install

としてください。バイナリと設定サンプルがインストールされます。

istgt (tarball): istgt-20090222.tar.gz
問題があったため修正しました。

MD5 (istgt-20090222.tar.gz) = 9f7dcddd70c034103682b0a6bbe88347
SHA1 (istgt-20090222.tar.gz) = a0e936097e60f203e9ab03606824807c8218654f

設定ファイルは /usr/local/etc/istgt/ の下にインストールされます。
またデーモン起動用スクリプトが /usr/local/etc/rc.d/istgt として、
インストールされます。
設定ファイルはブログにいくつか載せていましたが、従来の iscsi-target
(netbsd-iscsi) とはまったく互換性がありませんので新たに作成してください。
仮想ディスク等のデータファイルは互換性がありますので、そのまま移行できます。
そもそもハードディスクは生ディスクそのものなのですが。

起動に必要なメイン設定ファイルは
/usr/local/etc/istgt/istgt.conf
です。
ここにメディア制御用ポートやターゲットグループを指定していきます。
制御ポートはまったくバインドせず無しにする事もできます。

このソフトはiscsi-targetを完全に置き換える目的をもって作成してあります。
MCS Extra パッチ 20090125の機能及びノウハウをベースにしているので
移行に支障はないと思いますが、不測の事態に備えてZFSスナップショットや
バックアップを必ず行ってください。
また、iSCSI上に展開してる仮想マシン等は一旦すべて終了してください。

無事に初版リリースを迎えた事により、従来のMCS Extra パッチの開発を一旦終了とさせて頂きます。
動作に支障のある重大なバグがあった場合は対処するかもしれませんが、
今後のバグフィックスおよび機能追加はistgtをベースに行います。
多数のダウンロード、ご助言ありがとうございました。
この場を借りてお礼申し上げます。
引き続きパワーアップしたistgtもよろしくお願いたします。

主な機能:
マルチコネクション(MCS)
複数ポータルグループ及びイニシエータグループ
複数グループマッピング
ヘッダ及びデータダイジェスト機能(CRC32C)
CHAP認証(相互認証も含む)
64bit LBA(最大8EBのストレージまで)
(以下実験的)
IntelサーバアダプタによるiSCSIブート
Windows7ベータ版での動作を確認済み
仮想DVDROM及び仮想テープドライブ(DLTエミュレータ)

現時点での主な制限:
ターゲットへのアクセス(SCSIコマンド)は常に排他ロック状態でアクセスを行う
同期オペレーションのみサポートしている(キューイングはしない)
LUN1以降のINQUIRYデータ等の一部はLUN0と共有している
(1ターゲットに異形式で混在できない)

ありがちなミス。なんだかな

2009年2月21日 土曜日

istgtcontrolの対応をしているわけだけど、少し余力があるので、
前回は仕様にしてしまった制御用の認証機能をつけました。
現在のMCS Extra 20090125ではCHAPのチャレンジデータ長として
iSCSI規格上の最大値である1024バイト、すなわち16進数文字列で
“0x”+2048バイトの構成になっています。
これを制御用コネクションでも確認しようと思ったら、
作業バッファが少なく(すぐに気が付かず)なっていたので、
何度やっても認証エラーになって頭抱えてました(汗)

CHAPアルゴリズムは、1オクテットの識別子、シークレット、チャレンジ
(可変長オクテット)の3個を並べてハッシュを計算した値でチェックします。

ハッシュ関数がバグってない限り間違えようのない単純なアルゴリズムです。

CHAPについて詳細はRFC1994を参照してください。
iSCSIの制限についてはRFC3720を参照してください。

以下RFC1994より引用

  The Challenge Value is a variable stream of octets.  The
  importance of the uniqueness of the Challenge Value and its
  relationship to the secret is described above.  The Challenge
  Value MUST be changed each time a Challenge is sent.  The length
  of the Challenge Value depends upon the method used to generate
  the octets, and is independent of the hash algorithm used.

  The Response Value is the one-way hash calculated over a stream of
  octets consisting of the Identifier, followed by (concatenated
  with) the "secret", followed by (concatenated with) the Challenge
  Value.  The length of the Response Value depends upon the hash
  algorithm used (16 octets for MD5).

認証系ルーチンの検証作業完了しました

2009年2月20日 金曜日

これで20090125とほぼ同等の機能は実装できたはず。
認証系は設定をグループ化して以下のように変更しました。
あとUnitSerialは廃止して、UnitInquiryに統合しました。
最終的な調整とパッケージング作業をやらねば。
最初に書いた通りFreeBSD7.x以外の事は考えてないのでconfigureを使ってるけど何も処理していない。

# istgt.conf
  AuthMethod CHAP Mutual
  AuthGroup AuthGroup1

# auth.conf
[AuthGroup1]
  # User Secret MutualUser MutualSecret (Mutual is optional)
  Auth "iqn.1991-05.com.microsoft:saturn"  "testchaptest" \
       "iqn.2007-09.jp.ne.peach:disk1"     "mutualtestxx"

ほぼ完了:
CHAP認証系ルーチン

未完成:
istgtcontrolの対応

調整必要:
エラー時のターゲットリセット処理

仮想テープドライブの移植完了しました

2009年2月18日 水曜日

仮想DVDROMの状況を分析したところ、iSCSI PDUの生成部分にバグがあることが判明しました(汗)
いくつか他の問題もあったので全体的に修正してます。
一応認証なしではあるけど動くので物理サーバ上でアクセスして、いつもの条件で実行してみました。
主要なデータフローはまだ変更していないので、大きく結果が変わることはなかった。
リードキャッシュぐらいは実装したほうがいいかもしれない。

ほぼ完了:
仮想DVDROM
仮想テープドライブ(DLT8000仕様)

未完成:
CHAP認証系ルーチン
istgtcontrolの対応

仮想DVDROMの移植完了しました

2009年2月16日 月曜日

新しいロジカルユニット制御ルーチン配下に置くことができました。
現在仮想テープドライブを移植中です。
まぁ移植といっても自分が0から書いたコードなのでI/F部分をちょいと修正するだけですが。
(ハードディスクは仮想DVDを参考に新規作成しました)
動作確認してわかったけど仮想DVDROMが2008で使えない(汗)
2003だと動くのであまり気にしてなかったよ。

それにしてもOSのインストール作業はとっても退屈だ
ディスクレスが正しく動くことを検証するためにOSのクリーンインストールを毎回行うのですが
これがとてつもなく退屈だったり。
OSインストール完了するまで他に何もできませんし。

認証系がさっぱり進んでないのでそろそろ気合いれないとまずい。

$ wc istgt*.c
(中略)
   15113   44741  361390 total

まぁまぁの規模になったね。

認証なしのiSCSI接続(MCS)に成功しました

2009年2月15日 日曜日

Windows Server 2008から認証なしで接続を確認しました。
ダイジェストはあり・なし共に可能でMCSはもちろん対応済み。

ポータルグループ1と3の二個、LUNを二個もつiSCSIターゲットを
グループ3のポータルからMCSで二本接続したときの画面は以下のようになります。

利用した設定ファイルはこんな感じ

[LogicalUnit1]
Comment "Hard Disk Sample"
# full specified iqn (same as below)
#TargetName iqn.2007-09.jp.ne.peach:disk1
# short specified non iqn (will add NodeBase)
TargetName disk1
TargetAlias "Data Disk1"
# use both portal group tag1 and tag3 for initiator tag1
Mapping PortalGroup3 InitiatorGroup1
Mapping PortalGroup1 InitiatorGroup1
AuthMethod CHAP Mutual
AuthUser $InitiatorName
MutualUser $TargetName
UseDigest Header Data
ReadOnly No
UnitType Disk
UnitOnline Yes
# serial (ASCII string) reported by INQUIRY command
#UnitSerial "12345678"
# SCSI standard INQUIRY - Vendor(8) Product(16) Revision(4)
#UnitInquiry "FreeBSD" "iSCSI Disk" "0123"
# one of 512,1024,2048,4096 (default 512 is strongly recommended)
#BlockLength 512
# LogicalVolume for this unit on LUN0
LUN0 Storage /tank/iscsi/istgt-disk1 10GB
LUN2 Storage /tank/iscsi/istgt-disk1.2 10GB
#

ほぼ完了:
64bitLBA対応ハードディスク
ヘッダおよびデータダイジェスト機能
MCSによる複数接続
複数ポータルグループのバインド

未完成:
CHAP認証系ルーチン
エラー処理ルーチン
仮想DVDROM
仮想テープドライブ

テスト待ち:
iSCSIディスクレスブート

iSCSI接続できないまま放置したらWindows2008が死んでしまった

2009年2月13日 金曜日

↓のようなエラーを吐き続けていたら、2008がフリーズしてお亡くなりに(汗)
異常シーケンスを続けるのはよくない。あたりまえだけど。
とりあえず、Normalセッションのログインに必要な情報は揃いました。
まだLogicalUnitが未完成です。
ログはSCSIコマンドのREPORT LUNS(0xa0)を iqn.2007-09.jp.ne.peach:disk1
のLogicalUnitが処理できずにエラーが発生した所です。

istgt_iscsi.c:1543:worker: BHS read 48
istgt_iscsi.c:110:istgt_iscsi_read: Read 48 bytes (no padding)
istgt_iscsi.c:1701:worker: isid=400001370000, tsih=1, cid=1, op=1
istgt_iscsi.c:1445:istgt_iscsi_execute: opcode 1
CDB
a0 00 00 00 00 00 00 00 ........
00 10 00 00 00 00 00 00 ........
istgt_iscsi.c:1375:istgt_iscsi_op_scsi: I=0, F=1, R=1, W=0, Attr=0, ITT=63, TL=16
istgt_iscsi.c:1380:istgt_iscsi_op_scsi: CmdSN=99, ExpStatSN=3, StatSN=2, ExpCmdSN=99, MaxCmdSN=99
Execute Name = iqn.2007-09.jp.ne.peach:disk1
istgt_iscsi.c:1416:istgt_iscsi_op_scsi: ***ERROR*** lu_execute() failed
istgt_iscsi.c:1450:istgt_iscsi_execute: ***ERROR*** iscsi_op_scsi() failed
istgt_iscsi.c:1709:worker: ***ERROR*** iscsi_execute() failed
istgt_iscsi.c:1738:worker: loop ended (14)
istgt_iscsi.c:1750:worker: worker 14 end

iSCSIのDiscoveryセッションが通るようになった

2009年2月10日 火曜日

iSCSIの高速化フロントエンドでもできないかと検討したけど、
Windows7ベータ版を見てやっぱり1から書き直そうと思い立って、
コードを書き直して自前であれこれやって、
ついにWindowsServer2008とDiscoveryセッションが確立できる事を確認しました。
iSCSIにはDiscoveryとNormalという二つのセッションタイプがあり、
前者はターゲットのアドレス、ポート、グループタグを調べる為に使います。
IPアドレスを調べるだけといってもログイン、ログアウトとパラメータネゴシエーション
というiSCSIの要的コマンドを処理するのでこれができるかどうかはかなり進歩です。
これらに加えデータI/Oコマンドを処理できるようになれば論理装置へのアクセスが可能になります。
現在のところ論理装置が未完成のためNormalセッションは未確認です。

開発コンセプトは出来るだけ楽しよう(笑)
FreeBSD7.1より前のOSでの運用は考えない。
論理ボリュームはZFSの冗長ボリューム上に確保されると仮定して余計な事はしない。
各ポータルを物理I/Fに確実に振り分けたり設定ファイルを矛盾なく設定するのはサーバ管理者が責任をもつ。
当面はpthreadを使ってマルチスレッドで各コネクションを独立で管理し排他ロックする。

pthreadはメモリとかコンテキストスイッチとかmutexの負担が大きいかも。
mutex処理は元々かなり重いのでできれば避けたいところ。
マルチスレッドはいろいろ大変ですよ(汗)
ある変数を読み書きするスレッドが複数いた場合、アトミックにその値を取ってこないとまずいのは言うまでもない。
FreeBSD7.xに搭載されているgcc4にはbuiltin atomic命令があるのでそれも活用するとよさげ。
もしくはmachine/atomic.hを使うのかな?
読みだけが自明なら共有ロックしてもいいけど今後の検討事項です。

余談になるけど以前書いた設定部分に誤字があった
>  AuthMethod CHAP, Mutaul
これはMutualでした。

進捗はこんな感じ。

ほぼ完了:
設定ファイルの読み込み及び解析
ポータル及びイニシエータグループの作成
iSCSIパケット送受信(ダイジェスト機能含む)
iSCSIパラメータネゴシエーション
Discoveryセッションのパケットシーケンス
論理装置の設定読み込み及び解析

未完成:
CHAP認証パケット処理
データI/Oパケット処理
論理装置の動作

リリースを早く行う為に初期版で一時保留する機能:
メディアライブラリ機能
実行中の設定/状態のファイルへの書き出し