这两天在内部wiki上看到了一篇关于scsi设备地址映射的文章,感觉很不错,拿出来整理下。
———————————————————————————————————————————————————————————————-
一、SCSI设备地址映射的组成部分:
SCSI设备在Linux系统中的逻辑地址映射由4个部分组成:
[php]
SCSI adapter number [host]
channel number [bus]
id number [target]
lun [lun]
[/php]
将4部分通过“:”连在一起表示,即常见的4段式的地址映射,如2:0:0:1。

二、映射地址各部分的含义
第1部分:SCSI adapter number [host]
host说的是适配卡在计算机内部IO总线的位置(比如PCI,PCMCIA,ISA等),适配器也称为HBA,其编号由内核以0开始的升序分配。
host id,也就是scsi适配器的id,可以认为就是scsi适配器的序号。顺序一般情况下和通过lspci列出来scsi适配器的顺序是一致的。
例如:
一台服务器上自带了raid控制器,它在pci总线上的顺序比其他设备靠前,就是scsi0;光纤卡则靠后,按照顺序,被内核分配为scsi1、scsi2等。

第2部分:channel number [bus]
一个HBA可能控制一个或者多个SCSI总线。
SCSI总线类型有很多,常见的如:
(1)、SAS(Serial Attached SCSI,服务器自带的RAID控制器基本上都是这用SCSI总线)
(2)、FC(Fibre Channel,光纤通道,常见的SAN都是使用的这种总线)

channel id,对应不同的scsi总线类型。一个scsi适配器可以支持多种不同的总线类型,连接不同的scsi设备。但是实际上估计很少这么做,都是连接单一类型的设备。
例如:
现在服务器的RAID控制器,大部分都是SAS总线的,连接的都是SAS硬盘;光纤卡,也都是连接fc设备。所以这个值基本上都是0;

第3部分:id number [target]
每一个SCSI总线可以有多个SCSI设备连接在上面。在SCSI术语里,HBA称为“initiator“,占用一个SCSI id号(绝大部分是7,如果不是,改为7)。“initiator是负责和“target(也就是连接在总线上的SCSI设备)通信,所有的SCSI指令都通过它传递,从而完成数据I/O、甚至设备管理等操作。

一根SCSI并行缆线的id号数量和其宽度有关,如:8bits缆线(窄线)有8个id号。其中HBA占用1个。剩下7个给SCSI设备(当然,这个7个接口还可以接SCSI缆线);16bits的缆线对应的可以接15个SCSI设备(targets)。每一个id号就是所谓的target id。
target id,对应的是一个scsi target设备。

对于SAN来说,一个target id基本上是对应磁盘阵列上的一个控制器。

很多阵列都是双控制器的,所以当一块光纤卡通过光纤交换机连接到了2台磁盘阵列的4个控制器,那么在/proc/scsi/scsi中,就会发现对于同一个scsi host,会看到4个target id(0,1,2,3)。

第4部分:lun [lun]
每一个SCSI设备本身(绝大部分情况下说的是虚拟存储,比如RAID)能够包含多个LUN。

至于lun数目的限制,不同的存储设备情况不同,和磁盘阵列、光纤卡、光纤卡驱动都有关系。

如qla2xxx-v8.02.23_4,支持最多4096个(不同版本的具体限制,需要查阅该版本的release文件)。

三、映射地址的应用
因为SCSI设备的映射地址,以数字的形式表现,本身就具备了顺序性,因此映射地址的主要作用在:
(1)、内核通过映射地址为设备命名
(2)、用户通过映射地址确定系统设备文件和实际物理设备之间的对应关系。

查看SCSI设备的映射地址主要有3中方法:
查询映射地址的方法之一: /proc/scsi/scsi文件
该文件是所有内核识别到的SCSI设备的列表,可以直接查看:
[php]
# cat /proc/scsi/scsi
[/php]

查询映射地址的方法之二: dmesg命令
dmesg可以打印出内核的日志信息,不过因为内核日志缓冲区有固定的大小,所以当缓冲区写满之后,在dmesg命令的输出中有一部分日志信息是看不到的,不过可以通过日志文件/var/log/dmesg查看。 内核识别到SCSI设备时,内核日志中会出现该设备的各种信息,包括映射地址。
执行dmesg命令
[php]
# dmesg
[/php]

查看dmesg日志
[php]
# cat /var/log/dmesg
[/php]

查询映射地址的方法之三: sg_map命令
sg_map是sg3_utils工具包中的命令,加上 “-x” 参数可以打印出设备文件和SCSI映射地址之间的对应关系。
需要说明的是,使用sg3_utils工具包中的命令,都需要sg模块的支持,即如果系统没有自动加载sg模块,需要手动加载。
[php]
# modprobe sg
# sg_map -x
[/php]

参考:
英文的原文是The Linux 2.4 SCSI subsystem HOWTO中的一节“3.1. SCSI Addressing”。地址为:
http://www.linux.org/docs/ldp/howto/SCSI-2.4-HOWTO/scsiaddr.html 或者
http://tldp.org/HOWTO/SCSI-2.4-HOWTO/scsiaddr.html
虽然这份文档是针对2.4内核的,但是scsi设备的寻址基本上没有变化。