Chinaunix首页 | 论坛 | 博客
  • 博客访问: 499670
  • 博文数量: 80
  • 博客积分: 1475
  • 博客等级: 上尉
  • 技术积分: 1047
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-01 22:58
文章分类

全部博文(80)

文章存档

2012年(3)

2010年(77)

我的朋友

分类: 服务器与存储

2010-05-04 08:35:16

在Linux软RAID实现中,将多路径也作为一种特性进行支持。使用mdadm基于软RAID构造多路径的命令行格式相似。唯一的区别在于,在创建其它级别的RAID设备时,每个sd设备号都是代表不同的物理磁盘;但是在使用mdadm基于软件RAID创建multiple设备时,使用到的sd设备号都是指向相同的公用磁盘驱动器。Mdadm并不检查这两条路径是否指向同一个磁盘(LUN),因此在设置之初需要确保这一点。创建multipath的示例如下:

mdadm --create /dev/md1 --level=multipath --raid-devices=2 /dev/sdb /dev/sdc

这里,/dev/sdb和/dev/sdc是通过HBA驱动程序向上层呈现的对存储设备的同一个磁盘的逻辑块设备名。上述命令会将/dev/sdb和/dev/sdc这两个不同路径对应的成员磁盘“绑定”成为一个软RAID设备/dev/md1,而对该设备的访问相当于通过不同的物理链路访问同一个磁盘。

除了通用的表示RAID设备的内核结构mddev_t和标识成员磁盘的内核结构mdk_rdev_t之外,mulitpath设备有两个重要的数据结构。其中multipath_conf_t是表示multipath设备的的私有数据结构,定义如下:

struct multipath_info {
    mdk_rdev_t *rdev; //指向组成multiple device的第一个成员磁盘的内核结构的指针
};

struct multipath_private_data {
    mddev_t   *mddev;
    struct multipath_info *multipaths;
    int   raid_disks; //本multiple device的成员磁盘数目
    int   working_disks; //本multiple device中可工作的成员数目
    spinlock_t  device_lock;
    struct list_head retry_list; //本multiple device的重试链表
    mempool_t  *pool;
};
typedef struct multipath_private_data multipath_conf_t;

raid_disks给出了组成该设备的成员磁盘的个数,而working_disks给出了其中可工作的成员磁盘的个数。Multipaths指向成员磁盘数组。

而multipath_bh结构代表了在multiple device的某条路径(即该路径对应的成员磁盘)上执行I/O请求的缓冲头结构。

struct multipath_bh {
    mddev_t   *mddev;  //回指向multiple device的指针
    struct bio  *master_bio; //指向对RAID设备的原始bio
    struct bio  bio;  //在该路径对应的成员磁盘上执行的bio
    int   path;  //该路径对应的成员磁盘在multiple device中的索引
    struct list_head retry_list; //加入到multiple device的重试链表中
};

master_bio指向对multiple device的原始bio,path为路径编号,也就是这条路径对应的成员设备在multiple device的组成磁盘中的编号,bio则是该路径(成员磁盘)上执行的bio。

如果上层有针对multiple device的I/O请求,最终将到达multipath_make_request函数。它将为这个请求创建一个multipath_bh,在其中保存原始的请求master_bio,并从multiple device中获得一条路径。如果无法得到路径,则向上层报告错误;否则要构造在这条路径对应的成员磁盘上进行操作的bio,除了更改bio的起始扇区bi_sector和请求设备bi_bdev等域之外,还需要将上面的multipath_bh结构保存在bio的bi_private域中,并设定bi_end_io回调函数为multipath_end_request,之后在这条路径对应的成员磁盘上调度请求。

上面叙述中,bio设置的后面两步主要作用在于这个路径上调度请求完成之后。设置bi_private域的目的是期望找到multipath_bh结构,并通过它找到原始的I/O请求bio以及multiple device的内核结构mddev_t;设置multipath_end_request是在成员磁盘上请求执行完成之后作善后处理:如果执行成功,则通过保存的对multiple device的原始bio向上层报告成功;如果执行失败,且是预读,则向上层报告错误(也就是说,我们不对预读在其它路径上进行重试);如果对其它操作(读或写)执行失败,则需要将这个路径对应的成员磁盘设定为故障,将这个multipath_bh链接到multiple device的重试列表中,然后唤醒multipathd线程。

如果multipathd线程获得调度,会处理multiple device的重试链表中的所有bio。对于每个bio,重新获得一条路径(注意到上次处理过的成员磁盘已经设置为故障,对应的路径将不会再次使用),构造对应成员磁盘的bio请求,并调度之。

在multiple device中获得路径的方法是返回第一个可用的路径,未作读均衡等优化考虑。

阅读(1960) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~