PXEでiSCSI boot (multipath)

前回の続き。今度はマルチパス構成でiSCSI bootさせてみる。
基本的な所は前回と共通なので差分がある箇所だけ記述。
ソフトウェアとしてはdevice-mapper-multipathを使用。

iSCSI Target設定

テストなのでiSCSI Enterprise Targetを使用。
同じSCSI identifierで見えれば良いだけなので一台のハードで問題ない。

Target iqn.sample.target0
        Lun 0 Path=/dev/sdaXX

で、IPアドレスを2つ付けて以下の様に見えるようにする。イニシエータからは
それぞれのIPに対して同じIQNでログインさせる。
IPアドレスを分けるのはパス障害のテストをやり易くするため(iptables等で遮断等)

iSCSI Initiator設定

バイナリは前回の物に加えて以下が必要。

dmsetup
 デバイスファイル作成用。
kpartx
 パーティション情報取得用。dmsetupで使う。
multipath
 マルチパス操作用。
 multipath.confはblacklistを空にしておく。
  /etc/multipath.conf
scsi_id
 unique SCSI identifier取得用。
  /etc/scsi_id.config
LKM(multipath用)
 依存関係によってinsmodに転けるのでロードする順番に注意
  dm-mod.ko
  dm-mirror.ko
  dm-multipath.ko
  dm-round-robin.ko

initスクリプトは以下のような感じ。
差分はmultipathの初期化と複数のディスクを認識させる所程度。
unique SCSI identifierが同じ物が見つかればそれを自動的に束ねてくれる。

 ...
 ##iSCSI+FS初期化
 insmod /lib/jbd.ko
 insmod /lib/ext3.ko
 insmod /lib/scsi_mod.ko
 insmod /lib/sd_mod.ko
 insmod /lib/scsi_transport_iscsi.ko
 insmod /lib/libiscsi.ko
 insmod /lib/iscsi_tcp.ko
 iscsid
 ##Disk 1つめ認識
 iscsiadm -m discovery -t sendtargets -p 
 iscsiadm -m node -T  -p  --login
 ##Disk 2つめ認識
 iscsiadm -m discovery -t sendtargets -p 
 iscsiadm -m node -T  -p  --login
 ##Multipathデバイス認識
 insmod /lib/dm-mod.ko
 insmod /lib/dm-mirror.ko
 insmod /lib/dm-multipath.ko
 insmod /lib/dm-round-robin.ko
 stabilized --hash --interval 250 /proc/scsi/scsi
 mkblkdevs
 multipath
 dmsetup ls --target multipath --exec "/sbin/kpartx -a -p p"
 ##Rootマウント
 mkrootdev -t ext3 -o defaults,ro /dev/mapper/mpath0p1
 mount /sysroot
 setuproot
 switchroot

通常、device-mapperのデバイスファイル作成はudevdに任せるが
作成が非同期になってしまうのでinitrd内部の処理では都合が悪い。
そのためdmsetupで直接作成させている。(内部でmknodが呼ばれる)


パスの監視や再投入はmultipathdの管轄なので、通常起動した後に
上げておく必要がある。
デフォルトではセクタ0のread可否によって疎通を確認している(readsector0)
他にもdirectio,tur,ベンダー固有のチェック(emc_clariion等)があるが
iscsiなので事実上readsector0,directio,tur以外は使えない感じ。
##追記
そんなことは無かった。
prio_callout,path_checker共にtargetが対応していればiscsiでもemcの物が使える。

# multipath -ll -v 3
...
sda: path checker = readsector0 (config file default)
...
sdb: path checker = readsector0 (config file default)


どのパスにI/Oを乗せるかはmultipath.confのpath_grouping_policyで設定できる。
Target側がActive-Activeに対応している場合はmultibus、Active-Standby
の場合はfailoverかな。multibus構成の場合はtcpdumpでパケットカウントした所、
大体均等に振り分けてくれていた。

path_grouping_policy  multibus
 # multipath -l
 mpath0 (XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) dm-0 IET,VIRTUAL-DISK
 [size=20.0G][features=0][hwhandler=0]
 \_ round-robin 0 [prio=2][undef]
  \_ 7:0:0:0  sdb 8:16  [active][ready]
  \_ 10:0:0:0 sda 8:32  [active][ready]

path_grouping_policy  failover
 # multipath -l
 mpath0 (XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX) dm-0 IET,VIRTUAL-DISK
 [size=20.0G][features=0][hwhandler=0]
 \_ round-robin 0 [prio=0][active]
  \_ 10:0:0:0 sda 8:32  [active][undef]
 \_ round-robin 0 [prio=0][enabled]
  \_ 7:0:0:0  sdb 8:16  [active][undef]

どちらの構成でも障害時には縮退して片側パスでの動作となる。