dm-thin-provision架构及实现简析

本文介绍了dm-thin-provision的原理和实现,包括其作为device mapper的一种,如何实现存储设备映射,支持快照和元数据独立存储。详细讲解了通过dmsetup和lvm创建thin provision的步骤,并探讨了其架构、关键数据结构以及IO操作流程。文章最后指出,尽管dm-thin-provision在空间利用上表现出色,但在导出增量修改时可能存在挑战。
摘要由CSDN通过智能技术生成
前言:

    最近对快照感兴趣, 初步分析了下dm-thin-provision的代码, 初步感觉实现方式很不错, 但不足的是性能比较差, metadata写了数据过多.

但整体实现方式还是值得参考的.

dm-thin-provision简介

    thin-provision是device mapper的一种, 可以完成存储设备的特定映射, 这种设备有下面的特点:

(1)允许多个虚拟设备存储在相同的数据卷中,从而达到共享数据,节省空间的目的;

(2)支持任意深度的快照。之前的实现的性能为O(n),新的实现通过一个单独的数据避免了性能随快照深度的增加而降低。

(3)支持元数据存储到单独的设备上。这样就可以将元数据放到镜像设备或者更快的SSD上。

 创建thin provision

    有两种方法创建dm thin-provision, 一种是通过dmsetup工具创建, 另外一种是通过lvm管理工具创建.

    通过dmsetup创建dm-thin-provision

    a:  创建pool

          # dmsetup create pool \

               --table "0 20971520 thin-pool $metadata_dev $data_dev \

                   $data_block_size $low_water_mark"

         # dmsetup create yy_thin_pool --table '0 409600 thin-pool /dev/loop6 /dev/loop7 128 0'

         # dmsetup table /dev/mapper/yy_thin_pool

         0 409600 thin-pool 7:6 7:7 128 0 0

    b: 创建thin volume

         # dmsetup message /dev/mapper/yy_thin_pool 0 "create_thin 0"

         # dmsetup table /dev/mapper/thin

         0 40960 thin 253:3 0

    c: 创建快照snapshot    

         # dmsetup suspend /dev/mapper/thin

         # dmsetup message /dev/mapper/yy_thin_pool 0 "create_snap 1 0"

         # dmsetup resume /dev/mapper/thin

         # dmsetup create snap --table "0 40960 thin /dev/mapper/yy_thin_pool 1"

   通过lvm创建thin provision

     a: 创建thin pool

         # dd if=/dev/zero of=lvm0.img bs=1024k count=256

         # losetup /dev/loop7 lvm0.img

         # pvcreate /dev/loop7

           Physical volume "/dev/loop7" successfully created

         # vgcreate vg_test /dev/loop7

           Volume group "vg_test" successfully created

         # lvcreate -L 200M -T vg_test/mythinpool

           Logical volume "lvol0" created

           Logical volume "mythinpool" created

         # ls /dev/mapper/* |grep mythin

          /dev/mapper/vg_test-mythinpool

          /dev/mapper/vg_test-mythinpool_tdata

          /dev/mapper/vg_test-mythinpool_tmeta

          /dev/mapper/vg_test-mythinpool-tpool

     b: 创建thin

        # lvcreate -T vg_test/mythinpool -V 300M -n lvol1

          Logical volume "lvol1" created

     c: 创建snapshot

        # lvcreate -s --name mysnapshot1 vg_test/lvol1

          Logical volume "mysnapshot1" created

dm-thin-provision架构


  thin-provision记录了每次写的block的映射关系, 具体对应关系放到了metadata dev中, 每个block介于64k 和1G中间, 创建pool的时候传入, 在pool_ctr中有检查

/*

 * The block size of the device holding pool data must be

 * between 64KB and 1GB.

 */

#define DATA_DEV_BLOCK_SIZE_MIN_SECTORS (64 * 1024 >> SECTOR_SHIFT)

#define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT)

  而无论读写, 首先会有一个从metadata中找block的过程, 例如:

  thin_bio_map-> dm_thin_find_block.  如果是读命令, 结果却发现找不到block的情况, 这种情况就说明之前根本没有写入数据,所以应该返回全0.

如果是写命令, 没有找到block, 就可以往metadata的树中插入新的项目, 当下次写命令查找时能返回正确的block信息.

snapshot和对应的thin一样, 也是一种thin device, 只不过这种thin device是有一部分能共享. 当对某个thin创建snapshot时, 需要怎么来处理呢?

a: 创建snapshot也就是创建了一个新的thin_id的设备, 只不过有一个time值记录当前的snapshotted_time, 如果找到的block的时间小于当前设备的time, 则说明是共享的,代表当前block是比较老的版本.

b: 如果是共享的, 其实已经找到了block号,

c: 如果不是共享的,则需要重新创建一个block, 并于当前bio进行map, 同时写入map的结果到metadata dev中保存.

关键的数据结构

pool ,代表最开始创建的pool

 Collapse source
struct pool_c {
 
         struct dm_target *ti;
 
         struct pool *pool;
 
         struct dm_dev *data_dev;
 
         struct dm_dev *metadata_dev;
 
         struct dm_target_callbacks callbacks;
 
  
 
         dm_block_t low_water_blocks;
 
         struct pool_features requested_pf; /* Features requested during table load */
 
         struct pool_features adjusted_pf;  /* Features used after adjusting for constituent devices */
 
};

Thin_c, 代表已创建好的thin dev

 Collapse source
struct thin_c {
 
         struct list_head list;
 
         struct dm_dev *pool_dev;
 
         struct dm_dev *origin_dev;
 
         sector_t origin_size;
 
         dm_thin_id dev_id;
 
  
 
         struct pool *pool;
 
         struct dm_thin_device *td;
 
         struct mapped_device *thin_md;
 
  
 
         bool requeue_mode: 1 ;
 
         spinlock_t lock;
 
         struct list_head deferred_cells;
 
         struct bio_list deferred_bio_list;
 
         struct bio_list retry_on_resume_list;
 
         struct rb_root sort_bio_list; /* sorted list of deferred bios */
 
  
 
         /*
 
          * Ensures the thin is not destroyed until the worker has finished
 
          * iterating the active_thins list.
 
          */
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值