您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > linux/Unix相关 > Linux SCSI 子系统剖析
LinuxSCSI子系统剖析SmallComputerSystemsInterface(SCSI)是一组标准集,它定义了与大量设备(主要是与存储相关的设备)通信所需的接口和协议。Linux®提供了一种SCSI子系统,用于与这些设备通信。Linux是分层架构的一个很好的例子,它将高层的驱动器(比如磁盘驱动器或光驱)连接到物理接口,比如FibreChannel或SerialAttachedSCSI(SAS)。本文向您介绍了LinuxSCSI子系统,并且讨论了这些子系统将来的发展方向。GNU/Linux和SCSI是很好的一个组合,因为二者在各自的环境中具有类似的特征。GNU/Linux是一种安全可靠的操作系统,可以不间断地运行。SCSI适合于可靠和高性能存储。二者都是开源的。您可以下载和查阅InternationalCommitteeonInformationTechnologyStandards(INCITS)T10TechnicalCommittee的各种SCSI规范。同样地,您也可以下载GNU/Linux源代码以理解其实现。它们在各自的行业都具有主导性,所以相对其他操作系统而言,GNU/Linux能更好地支持SCSI,这一点就不足为奇了。SCSI的演化SCSI是一种很有趣的接口,它是早期的接口之一,如今还在不断演化。第一种SCSI标准称为SCSI-1,是由ShugartAssociates在1979年前后创建的。SCSI-1定义了一种具有5MHz数据时钟的8-bit并行接口,能提供最高5兆字节每秒(5MB/s)的数据传输速率。SCSI-2标准出现于1985年,它的出现使数据速率更快(10MHz),总线也更宽(16位)。被称为Fast/Wide的SCSI-2允许的数据传输速率高达20MB/s,并具有与SCSI-1的向后兼容性,但是速率也会限制到SCSI-1的数据速率。SCSI-3的开发开始于1993年,现已成为了一组标准集,可以定义协议、命令集和信令方法。在SCSI-3中,包含一组命名为Ultra的并行SCSI标准和基于串行SCSI的协议,比如IEEE1394(FireWire)、FibreChannel,、InternetSCSI(iSCSI)和新兴的SAS。这些标准通过引入存储网络技术(比如FC-AL或iSCSI)改变了传统的存储理念,将数据速率扩展到了1Gbit/s,将最大的可寻址设备数增加到了100以上,并将最大的电缆长度扩展到了25米。图1展示了从1986至2007年SCSI的数据速率的变化图1.SCSI数据速率的演化SCSI工作原理SCSI实现了一种客户机/服务器风格的通信架构。发起者向目标设备发送命令请求。该目标处理此请求并向发起者返回响应。发起者可以是托管计算机中的一个SCSI设备,而SCSI目标则可以是一个磁盘、光盘和磁带设备或特殊设备(比如箱体设备)。SCSI命令SCSI传输所采用的协议已经时过境迁,SCSI命令却保持了最初的元素。SCSI命令是在CommandDescriptorBlock(CDB)中定义的。CDB包含了用来定义要执行的特定操作的操作代码,以及大量特定于操作的参数。SCSI命令支持读写数据(各有四个变量)以及很多非数据命令,比如test-unit-ready(设备是否已就绪)、inquiry(检索有关目标设备的基本信息)、read-capacity(检索目标设备的存储容量)等等。目标设备支持何种命令取决于设备的类型。发起者通过inquiry命令识别设备类型。表1列出了最常用的SCSI命令。表1.常见SCSI命令命令用途Testunitready查询设备是否已经准备好进行传输Inquiry请求设备基本信息Requestsense请求之前命令的错误信息Readcapacity请求存储容量信息Read从设备读取数据Write向设备写入数据Modesense请求模式页面(设备参数)Modeselect在模式页面配置设备参数借助大约60种可用命令,SCSI可适用于许多设备(包括随机存取设备,比如磁盘和像磁带这样的顺序存储设备)。SCSI也提供了专门的命令以访问箱体服务(比如存储箱体内部当前的传感和温度)。更多信息,请参见参考资料部分。Linux内核中的SCSI架构图2显示了SCSI子系统在Linux内核中的位置。内核的顶部是系统调用接口,处理用户空间调用到内核中合适的目的地的路由(例如open、read或write)。而虚拟文件系统(VFS)是内核中支持的大多数文件系统的抽象层。它负责将请求路由到合适的文件系统。大多数文件系统都通过缓冲区缓存来相互通信,这种缓存通过缓存最近使用的数据来优化对物理设备的访问。接下来是块设备驱动器层,它包括针对底层设备的各种块驱动器。SCSI子系统是这种块设备驱动器之一。图2.SCSI子系统在Linux内核中的位置与Linux内核中的其他主流子系统不同,SCSI子系统是一种分层的架构,共分为三层。顶部的那层叫做较高层,代表的是内核针对SCSI和主要设备类型的驱动器的最高接口。接下来的是中间层,也称为公共层或统一层。在这一层包含SCSI堆栈的较高层和较低层的一些公共服务。最后是较低层,代表的是适用于SCSI的物理接口的实际驱动器(参见图3)。图3.LinuxSCSI子系统的分层架构在./linux/drivers/scsi可以找到SCSI子系统(SCSI较高层、中间层和各种驱动器)的源代码。SCSI数据结构则位于SCSI源目录,在./linux/include/scsi也可以找到。SCSI较高层SCSI子系统的较高层代表的是内核(设备级)最高级别的接口。它由一组驱动器组成,比如块设备(SCSI磁盘和SCSICD-ROM)和字符设备(SCSI磁带和SCSIgeneric)。较高层接受来自上层(比如VFS)的请求并将其转换成SCSI请求。较高层负责完成SCSI命令并将状态信息通知上层。SCSI磁盘驱动器在./linux/drivers/scsi/sd.c内实现。SCSI磁盘驱动器通过调用register_blkdev(作为块驱动器)进行自初始化并通过scsi_register_driver提供一组函数以表示所有SCSI设备。其中sd_probe和sd_init_command这两个函数很重要。只要有新的SCSI设备附加到系统,SCSI中间层就会调用sd_probe函数。sd_probe函数可决定此设备是否由SCSI磁盘驱动器管理,如果是,就创建新的scsi_disk结构来表示它。sd_init_command函数将来自文件系统层的请求转变成SCSI读或写命令(为完成这个I/O请求,sd_rw_intr会被调用)。SCSI磁带驱动器在./linux/drivers/scsi/st.c内实现。磁带驱动器是顺序存取设备,会通过register_chrdev_region将自身注册为字符设备。SCSI磁带驱动器还提供了一个probe函数,称为st_probe。该函数会创建一种新磁带设备并将其添加到称为scsi_tapes的向量。SCSI磁带驱动器的独特之处在于,如果可能,它可以直接从用户空间执行I/O传输。否则,数据会通过驱动器缓冲被分段。SCSICD-ROM驱动器在./linux/drivers/scsi/sr.c内实现。CD-ROM驱动器是另一种块设备并为SCSI磁盘驱动器提供类似的函数集。sr_probe函数可用来创建scsi_sd结构以表示CD-ROM设备,并用register_cdrom注册此CD-ROM。SCSI磁带驱动器还会导出sr_init_command,以将请求转换成SCSICD-ROM读或写请求。SCSIgeneric驱动器在./linux/drivers/scsi/sg.c内实现。该驱动器允许用户应用程序向设备发送SCSI命令(比如格式化、模式感知或诊断命令)。通过sg3utils包还可以从用户空间利用SCSIgeneric驱动器。这个用户空间包包括多种实用工具,可用来发送SCSI命令和解析这些命令的响应。SCSI中间层SCSI中间层是SCSI较高层和较低层的公共服务层(可以在./linux/drivers/scsi/scsi.c内部分地实现)。它提供了很多可供较高层和较低层驱动器使用的函数,因而可以充当这两层间的连接层。中间层很重要,原因是它抽象化了较低层驱动器(LLD)的实现,可以在./linux/drivers/scsi/hosts.c中部分地实现。这意味着可以以同样的方式使用带不同接口的FibreChannel主机总线适配器(HBA)。低层驱动器注册和错误处理都由SCSI中间层提供。中间层还提供了较高层和较低层间的SCSI命令排队。SCSI中间层的一个重要功能是将来自较高层的命令请求转换成SCSI请求。它也负责管理特定于SCSI的错误恢复。中间层可以连接SCSI子系统的较高层和较低层。它接受对SCSI事务的请求并对这些请求进行排队以便处理(如./linux/drivers/scsi/scsi_lib.c中所示)。当这些命令完成后,它接受来自LLD的SCSI响应并通知较较高层此请求已经完成。中间层最重要的职责之一是错误和超时处理。如果SCSI命令没有在合理的时间内完成或者SCSI请求返回错误,中间层就会管理错误或重新发送此请求。中间层还可管理较高层恢复,比如请求HBA(LLD)或SCSI设备重置。SCSI错误和超时处理程序在./linux/drivers/scsi/scsi_error.c内实现。SCSI较低层在最低层的是一组驱动器,称为SCSI低层驱动器。它们是一些可与物理设备(比如HBA)链接的特定驱动器。LLD提供了自公共中间层到特定于设备的HBA的一种抽象。每个LLD都提供了到特定底层硬件的接口,但所使用的到中间层的接口却是一组标准接口。较低层包含大量代码,原因是它要负责处理各种不同的SCSI适配器类型。例如,FibreChannel协议包含了针对Emulex和QLogic的各种适配器的LLD。面向Adaptec和LSI的SAS适配器的LLD也包括在内。Linux和SCSI的未来展望毫无疑问,SCSI的发展前景很好,并且它会与Linux紧密相关。随着SCSI的演化,Linux将会一如既往地为不断发展的技术提供支持。Linux借助面向HBA的驱动器为新的SAS协议提供支持。随着协议向更快的速度发展(比如6GbSAS或8GbFC),Linux必将处在发展和部署的前沿。您还会发现Linux恰恰就是新SCSI协议的先进之处。FCoE(FibreChanneloverEthernet)颇值得一提。FCoE是全双工Ethernet网络(通常是1Gb或10GbEthernet)上的一种FibreChannel框架的映射。FCoE之所以重要,是因为它将主流的网络媒介与主流的企业存储协议连接起来。这种新技术必然受人瞩目,而且Linux也将不会例外。针对SCSI的端到端数据保护也在开发中,它源于T10的新数据完整性标准。这个标准为每扇区都增加了一个数据完整性字段(DIF)以保护介质上的数据。这个新的8字节DIF字段包括一个循环冗余代码(CRC)用以保护数据,一个参考标签用以保护数据免遭误导写入,以及一个应用程序标签。应用程序标签特定于应用程序,并且可以定义数据的用途,例如,一个PDF文件的一部分。请参见参考资料部分以获取更多信息。结束语Linux内核是抽象的分层结构的另一个典型示例。它将各种文件系统连接到不同的物理存储介质。若这些存储介质与SCSI相关,SCSI子系统会将公共Linux块请求转化为针对特定底层设备的SCSI请求。SCSI子系统本身在过去若干年中经历了很多变化,而且这些变化还在继续。诸如端到端数据保护这样的新技术,与FCoE这样的新协议一样,都在想方设法寻找与Linux建立关系的途径。
本文标题:Linux SCSI 子系统剖析
链接地址:https://www.777doc.com/doc-7027510 .html