infi.storagemodelでストレージデバイスのhtclパラメータを取得する方法
3828 ワード
infi.storagemodelはgithubのオープンソースプロジェクトで、次のリンクがあります.https://github.com/Infinidat/infi.storagemodel
その中の/infi/storagemodel/linuxディレクトリの下のLinuxStorageModel(UnixStorageModel)クラスでは、同じディレクトリの下のsysfs()オブジェクトを取得する必要がある.py実装では、Sysfsオブジェクトの内部にhctlオブジェクトがあります.このhctlオブジェクトは何ですか.
一、HCTLパラメータ
linuxでは、scsiには4つのレベルのアドレススキームがあります. SCSI adapter number [host] channel number [bus] id number [target] lun [lun]
説明:SCSIアダプタ番号は通常、コンピュータ内部のIOバス上の任意の番号であり、これらのアダプタは通常HBA(host bus adapter)と呼ばれ、SCSIアダプタ番号はカーネルによって指定され、0から増加します.各HBAは、1つまたは複数のSCSIバスを制御する.各SCSIバスには複数のSCSIデバイスが接続されており、SCSIではHBAをinitiator、initiator、通常SCSIデバイスと呼ばれるtargetsと通信している.
lsscsiコマンドのmanpageでは、次のような解釈が見られます.
Generic SCSI devices can also be accessed via the bsg driver in Linux. By default, the bsg driver's device node names are of the form '/dev/bsg/H:C:T:L'.
lsscsiを実行すると、次の結果が表示されます.
前の[0:0:1:0]の4つの数字は、このscsiデバイスのhctlパラメータを表し、それぞれ: host: SCSI hosts currently attached to the system.lsscsi-Hを呼び出すと、すべてのhost が表示されます. channel target: lun:論理ユニット数 二、HCTLの取得
HCTLを取得するにはlsscsiを直接呼び出すことができ、より効果的な方法はdeviceにioctlの要求を直接送信することであり、infi.stragemodelでは後者を使用しています.
hctlの取得方法を追跡し、Sysfsクラスでメソッドを呼び出します.
この方法の実現:
scsi_ioctl_get_idlunの実装:
scsi_ioctl_get_idlunは2つのパラメータを返しますfour_in_oneとhost_unique_id,このfour in oneのパラメータは実は私たちが必要とするhctlパラメータで、get_を見に戻ります.hctl_for_sd_デバイス関数はどのようにこのfour in oneを解析しますか?
このパラメータは4*8=32ビットのint型変数であり、hostは1番目の8ビット、channelは2番目の8ビット、lunは3番目の8ビット、targetは4番目の8ビット、lsscsiが出てくる[0:0:1:0]対応するfour_in_oneパラメータは:0|0|0|1であり,この32ビットのバイナリ数の10進数は1である.
その中の/infi/storagemodel/linuxディレクトリの下のLinuxStorageModel(UnixStorageModel)クラスでは、同じディレクトリの下のsysfs()オブジェクトを取得する必要がある.py実装では、Sysfsオブジェクトの内部にhctlオブジェクトがあります.このhctlオブジェクトは何ですか.
一、HCTLパラメータ
linuxでは、scsiには4つのレベルのアドレススキームがあります.
説明:SCSIアダプタ番号は通常、コンピュータ内部のIOバス上の任意の番号であり、これらのアダプタは通常HBA(host bus adapter)と呼ばれ、SCSIアダプタ番号はカーネルによって指定され、0から増加します.各HBAは、1つまたは複数のSCSIバスを制御する.各SCSIバスには複数のSCSIデバイスが接続されており、SCSIではHBAをinitiator、initiator、通常SCSIデバイスと呼ばれるtargetsと通信している.
lsscsiコマンドのmanpageでは、次のような解釈が見られます.
Generic SCSI devices can also be accessed via the bsg driver in Linux. By default, the bsg driver's device node names are of the form '/dev/bsg/H:C:T:L'.
lsscsiを実行すると、次の結果が表示されます.
[0:0:0:0] disk VMware, VMware Virtual S 1.0 /dev/sda
[0:0:1:0] disk VMware, VMware Virtual S 1.0 /dev/sdb
[2:0:0:0] cd/dvd NECVMWar VMware IDE CDR10 1.00 /dev/sr0
前の[0:0:1:0]の4つの数字は、このscsiデバイスのhctlパラメータを表し、それぞれ:
HCTLを取得するにはlsscsiを直接呼び出すことができ、より効果的な方法はdeviceにioctlの要求を直接送信することであり、infi.stragemodelでは後者を使用しています.
hctlの取得方法を追跡し、Sysfsクラスでメソッドを呼び出します.
from infi.sgutils.sg_map import get_hctl_for_sd_device
#dev_path='/dev/sdb'
hctl = get_hctl_for_sd_device(dev_path)
この方法の実現:
def get_hctl_for_sd_device(device_path):
from ..ioctl import scsi_ioctl_get_idlun as _ioctl
# SCSI_IDLUN
struct = _ioctl(device_path)
# http://tldp.org/HOWTO/SCSI-Generic-HOWTO/scsi_g_idlun.html
# "four_in_one" is made up as follows:
# (scsi_device_id | (lun << 8) | (channel << 16) | (host_no << 24))
host = (struct.four_in_one >> 24)
channel = (struct.four_in_one >> 16) & 0xFF
target = (struct.four_in_one) & 0xFF
lun = (struct.four_in_one >> 8) & 0xFF
result = HCTL(host, channel, target, lun)
return HCTL(host, channel, target, lun)
scsi_ioctl_get_idlunの実装:
def scsi_ioctl_get_idlun(device_path):
from array import array
struct_cls = structures.SCSI_IDLUN
size = struct_cls.min_max_sizeof().max
buffer = array("B", [0]*size)
# ,op 0x5382, buffer
result = ioctl(device_path, opcodes.SCSI_IOCTL_GET_IDLUN, buffer)
struct = struct_cls.create_from_string(buffer)
# SCSI_IDLUN(four_in_one=1, host_unique_id=0)
return struct
def ioctl(device_path, op_number, buffer=None):
# /dev/sdb,
fd = os.open(device_path, os.O_RDONLY | os.O_NONBLOCK)
try:
from fcntl import ioctl as _ioctl
args = [fd, op_number,]
if buffer is not None:
args.extend([buffer, True])
#args=[3, 21378, array('B', [0, 0, 0, 0, 0, 0, 0, 0]), True]
return _ioctl(*args)
finally:
os.close(fd)
scsi_ioctl_get_idlunは2つのパラメータを返しますfour_in_oneとhost_unique_id,このfour in oneのパラメータは実は私たちが必要とするhctlパラメータで、get_を見に戻ります.hctl_for_sd_デバイス関数はどのようにこのfour in oneを解析しますか?
host = (struct.four_in_one >> 24)
channel = (struct.four_in_one >> 16) & 0xFF
target = (struct.four_in_one) & 0xFF
lun = (struct.four_in_one >> 8) & 0xFF
result = HCTL(host, channel, target, lun)
このパラメータは4*8=32ビットのint型変数であり、hostは1番目の8ビット、channelは2番目の8ビット、lunは3番目の8ビット、targetは4番目の8ビット、lsscsiが出てくる[0:0:1:0]対応するfour_in_oneパラメータは:0|0|0|1であり,この32ビットのバイナリ数の10進数は1である.