关于题目:
想这个标题我想了很久?想了如下几个标题,
A:Linux最多支持的SCSI LUN是多少个?
B:Linux最多支持的SAN存储盘的个数是多少?
当我在查证了N圈之后,决定用现在这个标题。至于为什么稍后再给出答案。
实际情况:
事情本来很简单,那天客户打电话说扩容LVM。当时想了一下环境,无非就是存储划过来的盘,通过两个HBA卡,采用了SuSE自带的多路径软件Multipath-tools实现的。过程无非不就是控制一下HA的环境,然后设PV,加到VG,然后扩LV。再次跟客户确认了一下,客户强调这次用了两台存储划盘过来。打电话问老大,两个存储是否会有影响,老大说不会。于是回答客户OK,没有问题。周五过去讨论一下细节。当时就扩容的大小沟通了一下,扩到2.5T,当前只有400G左右。存储划的单个盘只有15G大小。想想无非就是划的盘多点。然后回去查查资料确认一下,到底支持多少个设备。当时没有做数学题,换算一下到底是多少个盘,这真是一个非常大的失败,而这也最终成为这次事件的起点。虽然没有具体换算有多少个,但是我心里清楚,必须要确定系统内到底支持多少个划过来的SCSI Luns.于是带着这个问题就开始了查询工作。
关于引用链接、事件过程:
[写在前面的KOOK名言:无论一个链接有多么官方,也不要轻易相信。这是我失败的教训。如果你问我应该相信什么,去看源码吧!]
为了确认Linux到底支持多少个存储设备,我开始我的google历程。以关键字"linux maximum scsi disk luns multiple scsi_mod sd_mod"等关键字多次配比。依次发现下面的链接。
第I阶段:出错阶段 (关键字: linux support maximum luns)
A:http://kbase.redhat.com/faq/docs/DOC-3293
看了一下文章,无非就是修改模块scsi_mod,加入max_luns=512,然后重做引导的initrd镜像,将模块参数变化加入到initrd里面。这肯定没有什么问题啊。可以搞定。
B:http://download.qlogic.com/sf/62552/ibm_dd_ds4kfc1_8.01.06_linux2.6_anycpu.txt
看了一下,找到让我眼睛一亮的一段。
7.1 Enable more than 1 scsi device per adapter
Support for multiple LUNs per device is standard in Linux 2.6 kernels. Currently, the maximum number of LUNs that can be scanned for each device is 256.
C:源码文件/usr/src/linux/drivers/scsi/scsi_scan.c
#define MAX_SCSI_LUNS 512
看到上面的引用链接后,我的感觉是,这岂不是完全没有问题。我带着这样的结论就去客户那里扩容了,4组HA的环境,分别扩容。先干掉了那个容量最大的那一组。扩容的时候是系统lsscsi认到330个盘,multipath处理后的盘165个,当时做起来还算顺利,就是发现系统重新启动时间过长。在开机自检的时候在devices-mapper那里停留过久、大概要10分钟。整个开机时间大概要不到30分钟。当时粗粗算了一下。系统太久没有重启,文件系统超期做了自检。所以加上这个也没太以为意。事实上,系统已经给了我警告。后面的三组,盘数较少没有超过100的,轻车熟路,非常快的就做完了。早晨6点出门,到客户那里8点开始,做到下午1点多,收了扩容后主机状态的support的日志,收其中最多Lun那组其中一台主机的时候,由于堡垒机超时,脚本中断,结果竟然造成主机失去响应,HA控制其自动重启。重启后系统正常,检查运行状态正常。回家已经4点多了。
晚间10点接到客户电话,系统异常,部分应用提示部分文件发送不完整。从客户的描述上看,应该是IO异常,造成数据文件不完整。赶紧打开日志查看。我靠,真的不正常。lsscsi的输出为330个sd*文件,但是fdisk -l的输出只有256个磁盘设备。再看多路径multipath的底层设备,有的两条路径正常,有的只有一条路径。统计加和256。崩溃。到了现场做如下尝试:
A:grub增加内核引导参数
max_scsi_luns = 512
结果:重启系统,问题依旧
B:修改scsi_mod的参数,max_luns=512
具体步骤如下:
1:修改/etc/modprobe.conf.local ,新增
options scsi_mod max_luns=512
2:创建镜像
/sbin/mk_initrd
3:检查镜像,将镜像解压后,检查后如下输出。
grep scsi_mod linuxrc
echo "Loading kernel/drivers/scsi/scsi_mod.ko $extra_scsi_params max_luns=512"
insmod /lib/modules/2.6.5-7.315-bigsmp/kernel/drivers/scsi/scsi_mod.ko $extra_scsi_params max_luns=512
结果:重启系统,问题依旧
客户不能再等了,一会天亮了,就该处理业务了,3点多,决定将扩容容量降低,降到系统可认到的256个以下。于是将备份文件,删除LV,VG,PV,重启系统。存储重新划盘。重建LVM,还原文件。中间还穿插了VG重建出错、一次网卡加载顺序变化,网络不通的插曲。真是应了那句祸不单行啊。还好,天亮之前,系统恢复了。在客户的宾馆睡到下午,系统运行正常。于是打车回家。
事实上事情还没有结束,当我晚上11点准备再睡觉的时候,客户的电话再次响起。当时的一个感觉就是崩溃啊!这后来的事情就不写到这个里面了。回头我再写一篇日志写后面的事情。
第II阶段:分析阶段 (关键字: linux scsi_mod sd_mod devices scsi disk maximum)
当我静下来仔细看日志的时候,仔细查看系统文件,一点一点的云雾渐渐拨开,但是有些地方还是不明白。
1:系统可以看到330个盘
A:lsscsi可以看到330个sd*设备
B:cat /proc/partition内的sd*设备为330个
C:cat /proc/scsi/qla2xxx/0、1 里面检测到设备分别为165个
2 系统可以用的设备为256个
A:fdisk -l 输出可以使用的块设备为 256
B:lsmod显示sd_mod 被使用为256
C:multipath -ll的输出中,真正用到的块设备为256。
进入为什么阶段?
1:lsscsi为什么可以识别?
http://sg.danny.cz/scsi/lsscsi.html
2:为什么lsmod里面sd_mod只有256个。
下面看一下为什么是这样的,SCSI这个东东回到本质上来,在物理上说是SCSI总线是计算机内部与外设进行通讯的总线,SCSI设备就是采用SCSI总线标准的设备。既然到了,这里那Linux里面关于这个最底层的支持是哪个东东?来查看一下。最基础的模块就是scsi_mod,什么意思?所有符合SCSI总线设备都需要调用这个模块。至于依赖他的模块有哪些,可以看看,cciss是HP硬盘的、st是scsi tape的,qla2xxx是qlogic hba卡的,sd_mod则是我们看到的scsi disk设备sd*了。
[root@server /]# lsmod
Module Size Used by
sg 54176 0
st 57500 0
sr_mod 33316 0
cdrom 55196 2 sr_mod,ide_cd
dm_round_robin 19968 1
dm_multipath 37512 2 dm_round_robin
dm_mod 73600 46 dm_multipath
qla2300 141056 0
qla2xxx 365496 169 qla2300
firmware_class 25984 1 qla2xxx
scsi_transport_fc 23296 1 qla2xxx
cciss 73796 7
sd_mod 37888 256
scsi_mod 134852 8 osst,sg,st,sr_mod,qla2xxx,scsi_transport_fc,cciss,sd_mod
# /sbin/modinfo scsi_mod
parm: scsi_logging_level:a bit mask of logging levels (int)
license: GPL
description: SCSI core
parm: inq_timeout:Timeout (in seconds) waiting for devices to answer INQUIRY. Default is 5. Some non-compliant devices need more. (int)
parm: max_report_luns:REPORT LUNS maximum number of LUNS received (should be between 1 and 16384) (int)
parm: max_luns:last scsi LUN (should be between 1 and 2^32-1) (int)
parm: default_dev_flags:scsi default device flag integer value (int)
parm: dev_flags:Given scsi_dev_flags=vendor:model:flags[,v:m:f] add black/white list entries for vendor and model with an integer value of flags to the scsi device info list (string)
depends:
supported: yes
vermagic: 2.6.5-7.246-bigsmp SMP PENTIUMII REGPARM gcc-3.3
# /sbin/modinfo sd_mod
description: SCSI disk (sd) driver
author: Eric Youngdale
license: GPL
depends: scsi_mod
supported: yes
vermagic: 2.6.5-7.246-bigsmp SMP PENTIUMII REGPARM gcc-3.3
通过上面的说明看出一些端倪没有?scsi_mod模块支持了所有硬件上支持scsi总线的设备,是最底层的驱动,而我们想知道Linux支持最多的scsi disk的数目的sd_mod模块这个里面竟然不带参数。我靠!最后一招去看源码吧。
查看sd_mod这个模块的源码文件:/usr/src/linux/drivers/scsi/sd.c
/* Device no to disk mapping:
*
* major disc2 disc p1
* |............|.............|....|....| <- dev_t
* 31 20 19 8 7 4 3 0
*
* Inside a major, we have 16k disks, however mapped non-
* contiguously. The first 16 disks are for major0, the next
* ones with major1, ... Disk 256 is for major0 again, disk 272
* for major1, ...
* As we stay compatible with our numbering scheme, we can reuse
* the well-know SCSI majors 8, 65--71, 136--143.
*/
static int sd_major(int major_idx)
{
switch (major_idx) {
case 0:
return SCSI_DISK0_MAJOR;
case 1 ... 7:
return SCSI_DISK1_MAJOR + major_idx - 1;
case 8 ... 15:
return SCSI_DISK8_MAJOR + major_idx - 8;
default:
BUG();
return 0; /* shut up gcc */
}
}
找到这里,终于知道为什么只有256个文件可以用了。查看内核文档/usr/src/linux/Documentation/devices.txt,找到了major为8,65-71,136-143的定义部分,保留给scsi disk的。
再查看一下内存里面的输出()。关于文件/proc/devices的bolock部分。
Block devices:
8 sd
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
自己查一下是不是16个major,这意味着什么?看看/usr/src/linux/Documentation/devices.txt里面的定义。major为8,65-71,136-143(共16个),而minor可以用到256个。而分区限制在16以内,其实就是15个分区。
下面就是结论了:Linux系统内可以用的SCSI Disk可以是多少个?就是major * minor / partitions = 16 * 256 / 16 = 256个。所以,对于存储划过来的盘,由于通过两个HBA卡走的,所以本来应该是165 * 2 =330个,但是实际上系统只能用其中的256个。这样上面的就都成立了。由于sd_mod自身的限制,让我们无法使用其全部的盘。而像HBA卡的驱动,直接使用的是scsi_mod模块,其自身就可以识别到所有的LUN,但是就是系统不能用而已。
看到这里好像是结束,但是事情并没有结束。我google到下面的链接。
SCSI disk limitations on Linux
http://publib.boulder.ibm.com/infocenter/dsichelp/ds8000ic/index.jsp?topic=/com.ibm.storage.ssic.help.doc/f2c_linuxscsilimit_2hsag9.html
Newer kernels are moving to a dynamic configuration method that will use any available major numbers after the first 16 reserved major numbers have been used. The latest SuSE SLES 8 kernel errata includes this change and imposes a limit of no more than 144 major numbers allocated to SCSI disk devices. Thus these kernels can support up to 2304 disk devices.
In general, the following formula provides the maximum number of devices for Linux host systems: Number of devices = (number of major numbers) x (number of minor numbers) ÷ (number of partitions). For example, Number of devices = 8 x 256 ÷ 16 = 128 or Number of devices = 144 x 256 ÷ 16 = 2304.
For the Linux 2.6 kernels the number of major and minor bits has been increased to 12 and 20 bits respectively, thus Linux 2.6 kernels can support thousands of disks. There is still the limitation of only up to 15 partitions per disk.
看完了,我新的问题来了,内核如何用到那些尚未定义的,可用的major的。我再次看了日志,略去其它,仅抽取major为16的设备,发现如下:
这是正常的设备,major是sd_mod里面定义的,minor也是16的整数倍,而且小于256
8 0 sda
8 16 sdb
8 32 sdc
8 48 sdd
8 64 sde
8 80 sdf
8 96 sdg
8 112 sdh
8 128 sdi
8 144 sdj
8 160 sdk
8 176 sdl
8 192 sdm
8 208 sdn
8 224 sdo
8 240 sdp
对于非正常的sd设备,如下:
8 256 sdiw
8 272 sdix
8 288 sdiy
8 304 sdiz
8 320 sdja
8 336 sdjb
8 352 sdjc
8 368 sdjd
8 384 sdje
8 400 sdjf
8 416 sdjg
8 432 sdjh
8 448 sdji
8 464 sdjj
8 480 sdjk
8 496 sdjl
我崩溃了,问题仍然没有结束。就我目前的理解程度,实在是无法了解了。这些无效的sd*设备的major和minor是怎么分配的?文档中描述的,超出sd_mod定义的16个,内核保留的可用的major是如何分配和使用的。而我又如何可以让系统使用超过256个的SCSI disk设备呢?
本文链接:http://linux.52zhe.info/read.php/237.htm
本文作者:kook(若就博客内所涉及的技术问题交流,请用下面的MSN或Gmail联系我)
联系方式:(MSN:kook#live.com) (Google talk:kookliu)