• linux内核dm thin pool分析


    一、简介

    Docker现在非常火热,作为docker存储引擎之一的dm thin pool用的比较多,thin-pool由一个metadata设备和data设备组成,thin的概念就是按需分配数据块,删除时也回收数据块,提高存储空间利用率。

    a)         Dm thin pool创建命令如下:

    //清零metadata设备的第一个page, why??因为第一个page是thin-pool的superblock, thin pool 内核模块里是通过判断superbock是否全0来决定是重新格式化一个thin-pool还是打开已有的thin-pool

    dd if=/dev/zero of=$metadata_dev bs=4096 count=1

    //创建pool, --table的参数,0为起始扇区,20971520是扇区数,这里的扇区都是512字节来算的,data_block_size --- 数据块的大小,单位还是扇区,512字节,data_block_size最小为128,最大为2097152

    low_water_mark ---当空闲数据块个数小于water_mark时, dm thin-pool内核模块会给用户态daemon发送通知事件。

    dmsetup create pool

    b)         --table "0 20971520 thin-pool $metadata_dev $data_dev

    1. $data_block_size $low_water_mark"

    //调用pool设备的message接口,创建thin设备,其中0是thin设备的id, 因为一个pool可以创建N个thin设备,所以需要一个id来区别开这些thin设备。

    dmsetup message /dev/mapper/pool 0 "create_thin 0"

    //为上面的thin设备创建/dev/dm-x 设备文件。

    dmsetup create thin --table "0 2097152 thin /dev/mapper/pool 0"

    二、thin-pool磁盘布局

    a)         data设备

    data设备是以data_block_size,如果是128就是128*512=64KB 划分为块来管理的,data设备存储的全是数据,没有任何元数据,所以磁盘布局略。

    b)         Meta设备

     

     

    c)         如图, meta设备的磁盘布局如上,meta设备的块大小为4KB, 第一个块是superblock, 代码里定义如下:

    /*

    Little endian on-disk superblock and device details.

    */

    struct thin_disk_superblock {

    __le32 csum;    /* Checksum of superblock except for this field. */

    __le32 flags;

    __le64 blocknr; /* This block number, dm_block_t. */

    __u8 uuid[16];

    __le64 magic;

    __le32 version;

    __le32 time;

     

    __le64 trans_id;

     

    /*  

    Root held by userspace transactions.

    */

    __le64 held_root;

     

    __u8 data_space_map_root[SPACE_MAP_ROOT_SIZE];

    __u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];

     

    /*  

    2-level btree mapping (dev_id, (dev block, time)) -> data block

    */

    __le64 data_mapping_root;

    /*  

    Device detail root mapping dev_id -> device_details

    */

    __le64 device_details_root;

    __le32 data_block_size;     /* In 512-byte sectors. */

    __le32 metadata_block_size; /* In 512-byte sectors. */

    __le64 metadata_nr_blocks;

    __le32 compat_flags;

    __le32 compat_ro_flags;

    __le32 incompat_flags;

    } __packed;

    d)         重要的字段:

    l  Magic: pool设备的magic: 27022010

    l  Data_space_map_root: 管理数据块设备使用空间(使用位图)的map_root结构

    l  Metadata_space_map_root: 管理元数据块设备使用空间(使用位图)的map_root结构

    l  Data_mapping_root: thin设备从虚拟块地址到数据块设备上真实地址的映射btree根块号

    l  Device_details_root: 所有thin设备的信息以btree的方式存到Device_details_root指向的根块上

    l  Data_block_size: 数据设备块大小 =  data_block_size * 512B

    l  Meta_nr_blocks: 元数据设备总块数, 注元数据设备块大小为4KB

    三、寻址

    从thin设备的虚拟块地址到数据设备的实际块地址,thin-pool的寻址逻辑如下:

    a)         先用thin设备的dev_id作为key, 从data_mapping_root指向的块所包含的btree根节点中,去查找thin设备所对应的数据映射btree的块号

    b)         再用虚拟块号作为key从thin设备的数据映射btree里去查找实际的value, 查到的value就是数据块设备上对应的实际块号

    c)         整个过程用伪代码如下:

    block_t find_thin_block(dev_t dev_id, block_t block)

    {

    block_t thin_map_root;

    //从data_map_root btree中以dev_id为key查找对应的值,结果为dev_id对应的thin设备的具体btree根节点所在的块

    thin_map_root = btree_lookup(pool_data_map_root, dev_id);

    //从meta设备上读出根节点

    read_block(meta_dev, thin_map_root, &thin_map_tree);

    //从btree中以thin的虚拟块block查找data设备对应的实际块

    return btree_lookup(&thin_map_tree, block);

    }

    四、空间管理

    a)         整个thin-pool模块里,所有的空间管理都是基于btree的。

    b)         元数据块设备自身的空间管理: 这个是通过以Metadata_space_map_root为根块的btree来管理的,叶子节点存放的是管理空间的位图,与普通位图不同的是thin-pool的位图是一个单元2个位,一共能表示4个状态: 0为空闲,1为引用计数为1, 2位引用计数为2, 3表示引用计数>2, 需要从另一颗btree里去找实际的引用计数。

    c)         数据块设备空间管理: 跟元数据块设备自身空间管理类似,数据块设备也是一颗btree, 叶子节点指向包含管理位图的块,当然这些块都是在元数据设备上的。

    d)         空间释放:当引用bitmap里的引用计数变为0时, 块就变空闲了,这也就是thin设备的意义所在,不过,这需要上层文件系统discard的支持,thin-pool需要能知道哪些块上层不需要了,就可以减小位图的引用计数,释放块。

    五、总结

    thin-pool的存储格式还是比较清晰和简单的,总体看上面的布局结构图就已经很清晰了。

  • 相关阅读:
    Linux文件权限
    Linux命令
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    LeetCode
  • 原文地址:https://www.cnblogs.com/boring-codeer/p/6187879.html
Copyright © 2020-2023  润新知