note:在之前的一篇FCoE模块设计和实现的文章,大致讲到了FCoE模块的设计。虽然很清楚地讲了FcoE模块的组成,可是没有站在整个存储子系统的角度来看FCoE,总是有点局限的感觉,然后存储子系统和网络子系统是怎么交互的也没有说清楚,希望在这里这些疑问都能得到解答。
我们知道linux内核是层次设计的设计模式,存储子系统也不例外。下面这张图(来自网络)表示了linux下面存储子系统的层次化模块。
根据上图,如果一个用户空间中的应用程序(假设是用c语言编写的)要读取存放在remote scsi磁盘上面的某个文件,那么这个应用程序就需要使用c库的程序,然后调用内核提供的系统调用read(),系统调用会访问VFS,也就是虚拟文件系统,那么虚拟文件系统是什么呢?虚拟文件系统其实是文件系统的抽象层(复用代码的设计思想?),然后由VFS 选择那个正确的文件系统,因为甚至有的文件系统就是网络文件系统呢。然后到了真正的文件系统,文件系统是一个组织文件在磁盘上面存放的管理系统,由文件系统找到文件对应的块。再然后到了块设备层。文件系统和块设备驱动层会有一个叫做buffer cache的层次,那是将磁盘上面的数据缓存的一段内存和相关的数据结构。
块设备驱动需要要和下面的接口打交道,对于scsi子系统来说,或者对于更加具体的fcoe接口,这个交互过程是怎样的?那么首先看一下块设备的作用吧。
当unix系统刚写出来的时候,它有一个大胆的设计,那就是把所有的物理设备也都看做是文件。但是不同的设备是有区别的,有的是随机存取,有的是按顺序存取方式。但是为什么还要用同样的接口(文件系统)来和一个打印机或一个磁盘设备通信呢?因为即使他们不一样,但是都抽象为文件还是可以的,并且这样可以让整个系统变得很简单。
字符设备又称为rawdevices,比如打印机和终端机,文件系统根据这个文件,然后使用字符设备驱动提供的API就可以往字符设备读写数据。块设备在文件系统里面为/dev/dsk,块设备是随机存取的,文件系统可以挂(mount)在块设备上面,而不可以挂在字符设备上面。
块设备驱动是为磁盘块设备和文件系统之间通信的一个桥。系统可以将文件系统加载在块设备上面,块设备驱动大概就是提供了这样的一个加载的功能,然后使得文件系统可以读写块设备。
块设备驱动下面可能是scsi子系统或者别的磁盘设备驱动,直接连接磁盘。至于scsi子系统,下面将单独介绍。
SCSI是一组标准集,定义了与大量设备通信所需的接口和协议。linux提供了一个SCSI子系统用于和SCSI设备通信。SCSI适合于可靠高性能远距离存储。
SCSI是客户机/服务器模型,客户机发出SCSI命令,然后由服务器接收和处理SCSI命令,SCSI目标通常为启动程序提供一个或者多个逻辑单元号(LUN),SCSI实际的I/O操作也只处理这种实体。在存储区域中,LUN通常表示一个主机能够执行读写操作的磁盘。
关于SCSI,我在FCoE模块设计和实现介绍的比较详细。总之,SCSI上层接收来自上层(比如通用块层,文件系统)的请求并将其转换成SCSI请求,及负责完成SCSI命令并将状态信息通知上层。中间层是上层和底层的公共服务层。底层是一组驱动器,称为SCSI底层驱动,可以与物理设备通信。
note:学习块设备编程和scsi块设备编程?参考http://www.tldp.org/LDP/khg/HyperNews/get/devices/scsi/1.html
从上面的分析中,我们发现FCoE模块是作为linux内核中SCSI子系统的底层驱动, 用来连接SCSI子系统和以太网系统,主要完成SCSI命令到FCoE帧的转化。
FCoE模块的协议处理依赖scsi_transport_fc模块、libfc模块和libfcoe模块。
note:因为FCoE模块设计和实现介绍的比较详细了,关于FCoE模块的相关component不再重复,主要说一下I/O component。
I/O模块完成FCoE协议处理,其中包含了SCSI命令(或数据)生成FC帧、FC帧到FCoE帧的映射、FCoE帧封装到以太网帧和发送到以太网核心。FCoE模块需要结合SCSI系统,libFC模块和以太网系统完成IO请求。发起端主要IO请求类型为读请求和写请求。
Ethernet模块是Linux内核网络处理的模块,工作在网络的l2层,负责将数据包发送到物理层(然后经过FCoE交换机达到storageserevr),或者将从link过来的层次转发到别的层次,比如说网络的上层,这里是指的l3,又或者根据头部的内容转发到FCoE模块,再由FCoE模块处理后,交给SCSI子系统和存储子系统进行处理。
相对于host中的存储子系统,虚拟机中的存储子系统则有更多的层次(既包括VM由包括hypervisor和host),还可以由于部署的不同,有更大的弹性(flex?)。
比如说对于基于fcoe的存储虚拟化,主要包括virtual disk, raw disk 和vm based storage。
Virtual disk是SCSI层的虚拟化,虚拟机通过SCSI层直接访问存储设备。虚拟机不需要考虑其存储设备是网络存储还是本地存储。Virtual disk是比较通用的模型,在不修改虚拟化平台和内核代码的情况下,可以在主流虚拟化平台上运行。在论文[IOFlow]中的存储方式就是这种Virtual disk的。
Raw disk的实现层次是FCoE协议栈,和FCoE的机制原理(FCoE的虚拟化)关系比较大。
NAS(Network Attached Storage)和iSCSI可以通过虚拟机的网络设备访问存储设备,不需要VMM(VirtualMachine Monitor)将存储设备映射给虚拟机。上述访问存储设备的模式,被称为VM-based storage,这种方式我在试验中部署过。
p.s.这里只是大概的讲了一下存储子系统,如果要精通存储子系统最好看看linux内核源码相关部分,顺带把网络子系统的源码看看~~