Chinaunix首页 | 论坛 | 博客
  • 博客访问: 100259
  • 博文数量: 17
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 241
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-06 13:16
个人简介

- -

文章分类

全部博文(17)

文章存档

2014年(9)

2013年(7)

2012年(1)

我的朋友

分类: 其他平台

2013-08-11 23:15:25

linux 3.10
drivers/md/md.c, Multiple Device driver, RAID

drivers/md/dm.c, Device mapper

针对不同的设备类型, 把bio转发到不同设备,
https://www.ibm.com/developerworks/cn/linux/l-devmapper/
http://blog.csdn.net/sonicling/article/details/5460311

LVM的类型和定义
https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Cluster_Logical_Volume_Manager/lv_overview.html#linear_volumes

dm初始化, 载入不同类型的target,

点击(此处)折叠或打开

  1. static int (*_inits[])(void) __initdata = {
  2. local_init, // 本地,
  3. dm_target_init, // 什么也不是, 提供框架
  4. dm_linear_init, // 根据target, 修改bio->bi_sector, sector进行线性转换,
  5. // 即只要加上offset, 不修改bio->bi_bdev
  6. dm_stripe_init,
  7. dm_io_init,
  8. dm_kcopyd_init,
  9. dm_interface_init,
  10. }
dm.c 中只是最基本的target类型


调用dm_register_target(stripe_target), 如

点击(此处)折叠或打开

  1. static struct target_type stripe_target = {
  2. .name = "striped",
  3. .version = {1, 5, 1},
  4. .module = THIS_MODULE,
  5. .ctr = stripe_ctr, // 创建
  6. .dtr = stripe_dtr, // 销毁
  7. .map = stripe_map, // 核心, bio的映射
  8. .end_io = stripe_end_io,
  9. .status = stripe_status,
  10. .iterate_devices = stripe_iterate_devices,
  11. .io_hints = stripe_io_hints,
  12. .merge = stripe_merge,
  13. }




io入口,
dm_setup_md_queue(md),
为指定的md构造标准bio io queue,
之后发给这个的bio都会在内部进行再次分发
=> dm_init_request_based_queue()
构造request_queue, 依次调用
md->queue = blk_init_allocated_queue(md->queue, dm_request_fn, NULL);

dm_init_md_queue(md);
blk_queue_softirq_done(md->queue, dm_softirq_done);
blk_queue_prep_rq(md->queue, dm_prep_fn);
blk_queue_lld_busy(md->queue, dm_lld_busy);

// 注册到系统磁盘elvator
elv_register_queue(md->queue);




dm-ioctl.c,
lookup_ioctl(), 与用户态控制程序对接, 加载lvm设置,
{DM_TABLE_LOAD_CMD, 0, table_load}, =>
dm_setup_md_queue(), dm.c



dm-snap.c
dm_snapshot_init()

dm_register_target(&snapshot_target);
dm_register_target(&origin_target);
dm_register_target(&merge_target);

lvm 使用COW实现snapshot

/usr/sbin/lvcreate -L10G -n snap-root -s lvmvolume/root
命令lvcreate 使用参数-s创建snapshot, 从当前点开始, 原始lv被称为origin,
并新建snap, 即origin_target和snapshot_target

origin_target: do nothing
snapshot_target:
lvm snap实现基于COW, origin与普通读写没有任何区别,
snap由dm_kcopyd_client(dm-kcopyd.c)实现COW,
即将改变的block原始数据写到snap进行备份(原始的做法)

snapshot_ctr() =>
dm_get_device(), 获取origin和cow设备
dm-exception-store.c,
dm_exception_store_create(), 可以为snapshot的metadata额外指定存储空间,
struct dm_exception_store_type type = _get_exception_store_type(),
两种, p: persistent, 即重启之后snap依然可用, 记录进行执行过COW的区域,
当前内核中的lvm snap实现完全不考虑兼容性, 不同磁盘上的snap不保证可互用,
lvcreate应从全新的COW设备上执行snap.
t: transient, 除了框架, 啥也没有
dm_kcopyd_client_create(), dm-kcopyd.c
register_snapshot(),
将新建dm_snapshot 按chunk_size顺序链接到list origin->snapshots

merge, 参考
https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Logical_Volume_Manager_Administration/snapshot_merge.html
将COW copy到origin

snapshot_merge_resume() =>
snapshot_resume()
start_merge() =>
dm_kcopyd_copy()







阅读(2559) | 评论(0) | 转发(0) |
0

上一篇:vimrc

下一篇:kernel module makefile example

给主人留下些什么吧!~~