ceph kernel rbd (二): rbd map , rbd unmap

4 篇文章 0 订阅
4 篇文章 1 订阅

当我们使用krbd 的时候,第一件事就是rbd map,这个命令的目的是将一个rbd image 挂载到linux 成为一个block 设备。

比如:

[root@atest-guest build]# rbd ls
test
[root@atest-guest build]# rbd info test
rbd image 'test':
        size 1 GiB in 256 objects
        order 22 (4 MiB objects)
        snapshot_count: 0
        id: 1726c754beda9
        block_name_prefix: rbd_data.1726c754beda9
        format: 2
        features: layering, exclusive-lock, object-map, fast-diff, deep-flatten, journaling
        op_features: 
        flags: 
        create_timestamp: Thu Jul 25 10:15:15 2019
        access_timestamp: Thu Jul 25 10:15:15 2019
        modify_timestamp: Thu Jul 25 10:15:15 2019
        journal: 1726c754beda9
        mirroring state: disabled
[root@atest-guest build]# rbd map test
/dev/rbd0
[root@atest-guest build]# lsblk /dev/rbd0
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
rbd0 250:0    0   1G  0 disk 
[root@atest-guest build]# mkfs.xfs -f /dev/rbd0
meta-data=/dev/rbd0              isize=512    agcount=8, agsize=32768 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=262144, imaxpct=25
         =                       sunit=16     swidth=16 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=16 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

如上,rbd map test 之后,linux 模拟出一个block 设备:/dev/rbd0 我们可以吧这个设备当做一块普通盘进行操作,比如mkfs.xfs。

下面我们来详细分析一下rbd map和unmap的过程:

(1) userspace rbd 命令:

首先看一下rbd map 命令的入口:src/tools/rbd/action/Kernel.cc

以上逻辑比较简单:

1, 用户执行rbd map test 命令,rbd 进程先注册一个udev monior,用来监听udev event。

2. 然后通过sysfs 告诉krbd driver 去添加一个rbd block device。这个过程在下面一部分详细介绍。添加结束之后,会发送一个kerne event 给udevd 服务。

3. udevd 服务执行rbd-rule,这个rule 的任务其实主要是建立一个link,/dev/rbd/rbd/test -> /dev/rbd0。另外回去读取block设备的superblock,如果有必要回去执行其他的rule。结束之后,会抛出一个udev 的event 给接受者。

4. rbd map 会接收到udev的event,解析之后发现设备添加结束,然后返回给user。退出进程。

其中有一个地方,rbd map 进程在等待udev event的时候,可能会出现一直等不到的情况,具体原因现在还不清楚。但是现在有timeout 在wait 里面,如果超时,就失败退出。

(2)do_rbd_add

在(1)里面可以看到,整个过程中,最重要的一部分就是krbd driver去添加block 设备的过程。可以看到代码如下:

 540 static BUS_ATTR_WO(add);
 541 static BUS_ATTR_WO(remove);
 542 static BUS_ATTR_WO(add_single_major);
 543 static BUS_ATTR_WO(remove_single_major);
 544 static BUS_ATTR_RO(supported_features);
 545 
 546 static struct attribute *rbd_bus_attrs[] = {
 547         &bus_attr_add.attr,
 548         &bus_attr_remove.attr,
 549         &bus_attr_add_single_major.attr,
 550         &bus_attr_remove_single_major.attr,
 551         &bus_attr_supported_features.attr,
 552         NULL,
 553 };

所以当我们去写入/sys/bus/rbd/add_single_major 的时候,会去调用

7138 static ssize_t add_single_major_store(struct bus_type *bus, const char *buf,
     /* [previous][next][first][last][top][bottom][index][help] [+7138 drivers/block/rbd.c] */
7139                                       size_t count)
7140 {
7141         return do_rbd_add(bus, buf, count);
7142 }

所以重点来了,主要的实现在do_rbd_add,下面来看看do_rbd_add 到底做了什么?

如上图所示:do_rbd_add 主要三个步骤:

(2.1)解析参数,创建设备。(rbd_add_parse_args -> rbd_dev_create)

(2.2)读取设备信息,初始化设备metadata。并且读取和初始化parent信息,知道没有parent为止。(#define RBD_MAX_PARENT_CHAIN_LEN        16) 目前krbd 支持最多16 层父子链接。(rbd_dev_image_probe)

(2.3)创建disk 并且加入到linux device 的hierarchy。(rbd_dev_device_setup -> blk_put_queue)

(3)do_rbd_remove

do_rbd_remove 其实就很简单了,主要是将do_rbd_add 里面的事情逆向再做一遍:

7220         if (force) {
7221                 /*
7222                  * Prevent new IO from being queued and wait for existing
7223                  * IO to complete/fail.
7224                  */
7225                 blk_mq_freeze_queue(rbd_dev->disk->queue);
7226                 blk_set_queue_dying(rbd_dev->disk->queue);
7227         }
7228 
7229         del_gendisk(rbd_dev->disk);
7230         spin_lock(&rbd_dev_list_lock);
7231         list_del_init(&rbd_dev->node);
7232         spin_unlock(&rbd_dev_list_lock);
7233         device_del(&rbd_dev->dev);
7234 
7235         rbd_dev_image_unlock(rbd_dev);
7236         rbd_dev_device_release(rbd_dev);
7237         rbd_dev_image_release(rbd_dev);
7238         rbd_dev_destroy(rbd_dev);

唯一值得注意的是force 这个option,他会忽略其他打开这个rbd device 的进程,继续去做remove。但是如果有IO hang住了,即使有force 参数,也不能成功unmap。这里我们会实现一个full_force option,这个option会abort 掉inflight的所有request,然后进行remove。

 

综上,本文分三个部分介绍了一个rbd 设备的创建和删除过程。从userspace 到kernelspace,详细浏览了代码执行过程。其中rbd map 是一个复杂的过程,当然也还有可以优化空间。比如V1 已经从librbd 里面mark 成deprecated,甚至已经移除了v1 的支持。所以krbd 也可以开始考虑将v1的支持去掉了。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
当我们遇到Ceph客户端使用RBD(Rados Block Device,一种在Ceph集群上提供块存储的服务)时卡住的情况,可能有几个原因导致。以下是可能的解决方案: 1. 检查网络连接:首先需要确保Ceph客户端与Ceph集群之间的网络连接正常。可以通过ping命令或其他网络测试工具来验证连接的可靠性。如果发现网络问题,需要解决它们,例如修复物理网络故障或调整网络配置。 2. 检查集群状态:使用Ceph集群监控工具(如Ceph Dashboard或Ceph命令行工具)来检查集群的状态。确保集群中的所有节点都正常运行,并且没有任何错误或警告存在。如果发现问题,需要根据相应的错误信息来解决。 3. 检查硬件问题:如果Ceph客户端卡住,可能是由于底层存储硬件的故障。首先,检查磁盘驱动器、网络适配器和硬件接口的状态。确保它们都正常工作并与服务器正确连接。如果需要,可以更换故障硬件以解决问题。 4. 调整客户端配置:根据具体情况,可能需要调整Ceph客户端的配置参数。例如,可以增加读写超时时间、调整并发连接数或增加RBD缓存的大小等。这些配置参数的修改可以通过编辑相应的配置文件(如ceph.conf或rbdmap文件)来实现。 5. 更新软件版本:卡住的问题有可能是由于软件版本的问题导致的。检查Ceph客户端和Ceph集群的软件版本,确保它们都是最新的稳定版本。升级软件版本可能修复已知的问题和漏洞,改进性能和稳定性。 总之,当Ceph客户端使用RBD卡住时,我们需要逐步排查可能的问题,并在每个步骤上采取相应的解决方案。这需要综合考虑网络、集群状态、硬件、软件版本等各个方面,并根据具体情况采取适当的措施来解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值