虚拟硬盘机制
虚拟硬盘机制 1. 虚拟硬盘是什么虚拟硬盘,即Virtual Disk,是由RAID DISK向上提供给RAID LUN使用的空间形式。我们在创建RAID LUN时,RAID DISK按照RAID LUN的大小提供给RAID LUN固定数量的虚拟磁盘,而RAID LUN在这些虚拟磁盘上实现RAID算法。虚拟磁盘的出现是为了支持非连续的物理段,可以将两个或多个不连续的空闲段从逻辑上组合成一个连续的空间,因此它既可以是连续的物理段,也可以整合非连续的物理空间,这样就能解决物理硬盘(Physical disk,简写成PD)分配时产生的碎片问题,提高物理磁盘的利用率。一个物理磁盘可以虚拟成多个虚拟磁盘(虚拟化操作是在创建RAID LUN过程中由RAID Group实现的),而每个虚拟磁盘整合的非连续物理段不能超过64个,也即RAID LUN最多包含的段个数为64,每个段的最小值为1MB。虚拟磁盘进行非连续物理段整合时,优先选择较大的物理段组成逻辑段,段选择算法同逻辑资源。 VD、PD、RAID Group和RAID LUN四者关系2. 虚拟磁盘的应用与实现虚拟硬盘是RAID DISK与RAID LUN这两个模块的接口目标之一。在DISK层,只有物理磁盘的概念,亦是我们可以手动接触,拔插磁盘和磁盘上下电处理等等。而在LUN层,看到的则是虚拟磁盘,其上处理实现LUN的各种功能。这两个层之间的很多功能都会涉及到虚拟磁盘的处理,如LUN的创建删除,热备盘替换,以及RG与LUN的扫描等。2.1 LUN创建创建RAID LUN时,RAID DISK接收到LUN的虚拟磁盘申请,从PD中剩余的未分配的物理段找到大小总和可以满足RAID LUN要求的几个物理段,组合成一个逻辑上连续的段即虚拟磁盘,并分配VID返回给LUN。RAID LUN就可以直接使用该ID号,不需关心虚拟磁盘里的物理段是否连续。也就是说LUN只关注自己存放的内容,并不知道自己存储在物理磁盘上的实际物理地址,RAID Group负责LUN的空间分配。磁盘在虚拟化时,DISK会告知该虚拟磁盘的uuid,所属LUN中的其他虚拟磁盘,亦会告知该虚拟磁盘所处的物理磁盘以及该物理磁盘上是否还有其他虚拟磁盘等等信息,LUN创建好之后,LUN的超级块即LUN DDF, 放置在物理磁盘上的一块特殊空间,位于 DDF分配的位置, 该空间不能用于存储业务数据,亦不算作LUN的容量大小。2.2 DDFDDF即物理硬盘数据格式(DISK DATA FAMAT)的简称,指物理硬盘上的一块特殊空间,一般位于物理硬盘的最尾部,使用该物理硬盘创建阵列时阵列容量不能包含该部分空间,因此该物理硬盘空间不能用于存储业务数据。 当硬盘用于创建RAID Group时,每个物理硬盘要为此保留1GB空间,用于存放各种配置信息,包括LUN DDF信息。目前开发实现一个RG上只允许创建一个LUN ,即一个PD上只能创建一个VD,DDF格式如下:uint32_t signature; /* 区段的签名,0xa92b4efc */uint32_t major_version; /* 1 */uuid_t rg_uuid; /* RAID Group全局唯一标识符 */char rg_nameMAX_RAID_GROUP_NAME_LEN; /* RAID Group名称 */uint64_t ctime; /* RAID Group创建的时间戳,低40位是秒,高24位是微秒或0 */uint64_t disk_sectors; /* RAID Group占用的物理硬盘容量,512字节扇区数量 */int32_t level; /* -4 (多路径), -1 (JBOD), 0,1,4,5 */* 硬盘常量信息 - 64 bytes */uint64_t data_off; /* 该硬盘的用户数据区域的起始扇区,通常是0 */uint64_t data_sectors; /* 该硬盘可用于保存数据的512字节扇区数量 */uint64_t rg_pri_ddf_off; /* RAID Group DDF主区起始于硬盘中的哪个扇区 */uint64_t rg_sec_ddf_off; /* RAID Group DDF备区起始于硬盘中的哪个扇区 */uint64_t vd_pri_ddf_off; /* 虚拟硬盘DDF主区起始于硬盘中的哪个扇区 */uint64_t vd_sec_ddf_off; /* 虚拟硬盘DDF备区起始于硬盘中的哪个扇区 */int32_t disk_idx; /* 该硬盘在RAID Group中的永久标识符 */ /* RAID Group状态信息 - 64 bytes */uint64_t utime; /* 最近一次更新DDF的时间,低40位是秒,高24位是微秒或0 */uint64_t events; /* 每次更新RAID Group DDF时,增加这个计数 */uint64_t vd_size; /* 虚拟硬盘个数 */uuid_t vd_uuid; /* 虚拟硬盘全局唯一标识符 */int32_t nr_disks; /* 包括热备盘在内所有成员硬盘的数量 */int32_t nr_data_disks; /* 不包括热备盘在内所有成员硬盘的数量 */int32_t max_disk; /* disk_roles数组的长度 */uint32_t ddf_csum; /* 整个DDF信息(从开始到disk_rolesmax_disk)的校验码 */上述参数是DISK实现的硬盘DDF信息,不包含LUN DDF部分。其中,vd_pri_ddf_off和vd_sec_ddf_off只表示一个VD,如若该磁盘上有多个VD,则对应的DDF格式会有变化,请参考测试组其他相关DDF的文档,本文档不再补充其后续的实现。LUN DDF区位于硬盘DDF中的LUN DDF Static Space,这个Space大小约为32MB,里面存放的是LUN的超级块信息,分主和备两大区,如下图所示。 LUN DDF结构示意图根据存储内容来划分,可以分为六大类(可扩展):本地索引区(Local Header)、控制器相关数据区(Controller Data)、LUN基本数据区(LUN Basic Data)、LUN中虚拟磁盘相关数据区(LUN DISK Data)、LUN扩展数据区(LUN Extensive Data)、共享空间管理管理区(Share Space Management)。Free Space为暂时没有使用空间,用于以后扩展使用。每一个LUN DDF表示一个LUN,如果该RG上有128个LUN,就会有128个LUN DDF区,全部都位于LUN DDF Static Space区。虚拟磁盘数据区字段格式如下表所示:表1 虚拟磁盘数据字段表字段大小(Byte)含义Signature4唯一标识该区段:0xA4333333CRC4CRC校验,该校验覆盖整个虚拟磁盘数据区段Local_Disk_Index4本虚拟磁盘在VDEs中的索引Max_VD_Supported4LUN支持的最大虚拟磁盘个数Current_VDEs4该区段中物理虚拟磁盘条目的个数VDE_Length4Visual Disk Entry的长度(单位字节),默认128字节Reserved104预留Visual_Disk_EntriesVariable每个VDE长度为VDE_Len;VDE最大个数为Max_VD_Supported;本空间存有VDE个数为Populated_VDEsVDE(Visual Disk Entry)字段格式如下表所示:表2 VDE字段表字段大小(Byte)含义VD_Index4虚拟磁盘在LUN中的索引号VD_UUID16虚拟磁盘全局唯一标识VD_Type40表示虚拟磁盘为LUN中数据盘1表示虚拟磁盘为LUN中重建盘VD_State4使用位映射虚拟磁盘的状态:Bit 0:0Offline 1OnlineBit 1:0OK 1FailedBit 2:0Not Missing 1Missing Bit 3:0Not kicked 1Kicked(该虚拟磁盘已被踢)Bit 4:0Not in Transition 1Transition(本虚拟磁盘正在替换一个物理虚拟磁盘)Bit 5:0No Write Errors 1Write ErrorsBit 6-31:预留Rebuild_Check_Point8当VD_State的Bit4为1时,记录已经完成重建的位置Reserved92预留2.3 LUN删除RAID LUN执行LUN删除命令后,会向RAID Group提出删除虚拟硬盘的请求,RAID DISK由此回收释放该虚拟空间,完成删除结果。释放的虚拟硬盘空间重新成为可再分配的空闲物理段。我们知道,RAID LUN被删除时,实际上只是被标记为已经删除,数据通道服务被停止。只要该LUN的DDF数据和业务数据区没有被破坏,系统可以重新恢复该LUN。根据上文,LUN DDF信息被放置在物理磁盘的DDF区,正常情况下执行LUN的删除操作,该区域不会被清理。而所谓的业务数据区,也就是该LUN的虚拟磁盘空间。只要刚被RAID DISK回收释放的虚拟空间没有被用于其他LUN的创建,并且LUN DDF信息完整,被删除的LUN则可以恢复。2.4热备盘替换理论上,热备盘的定义是一块空闲的无DDF信息的物理磁盘,但目前的实现则是只要不属于阵列,其角色为vacant的磁盘都可以当热备盘。当RAID Group中的数据盘被拔出或出现故障时,Disk模块会上报相应的事件,RAID LUN在接收到事件后,最终决定踢出VD,下发重建请求给RAID Group,RAID Group在接收到下发事件后,会依据规格要求来寻找顶替盘给RAID LUN重建 。当RAID Group找到了合适的热备盘,对其写入DDF信息加入RAID Group,并更新RAID Group里所有磁盘的DDF。RAID Group在虚拟化该热备盘后上报给LUN,由LUN启动重建,同时由LUN更新磁盘上LUN DDF信息。2.5 虚拟硬盘与扫描扫描流程分RAID Group部分和RAID LUN部分。当物理磁盘加入时,RAID Group需读取该磁盘的DDF分析磁盘身份,若磁盘为成员磁盘,则DISK还需判断是否向LUN报告VD事件。一个物理硬盘插入后,其可能经历的扫描过程如下:RG扫描流程:1. 接收PD加入的消息,启动扫描流程2. 从磁盘的RG DDF区读取DDF的数据3. 判断fauty位是否置位,如果置位则通知PD故障盘点灯4. 如果不是故障盘,则通过in_group位判断是否为成员盘5. 如果是成员盘则判断对应uuid的RG是否存在6. 如果RG存在则加入RG,(需要判断其他成员盘的记录里是否有