rbd map 执行过程分析

分析的 ceph 代码版本:  12.2.4

分析的 kernel 代码版本:  4.16.0


在执行 `rbd map <pool_name>/<image_name>` ,整个执行流程是如何完成的呢?

这个 map 主要可以分为两个部分:

1. 通知 kernel ,告知 kernel 需要 map 的信息(pool_name, image_name, 延伸的还包含 ceph 集群信息)

2. kernel 完成剩下的工作


一、通知 kernel

执行 `rbd map <pool_name>/<image_name>`  是怎样通知 kernel 的呢?

大致流程是通过写 /sys/bus/rbd 下的文件来完成,具体过程如下:

1. 命令行的入口 src/tools/rbd/action/Kernel.cc

入口:

 520 Shell::Action action_map(
 521   {"map"}, {}, "Map image to a block device using the kernel.", "",
 522   &get_map_arguments, &execute_map);

 

2. 调用流程:

execute_map --> do_kernel_map --> krbd_map --> map_image --> do_map --> sysfs_write_rbd_add


sysfs_write_rbd_add 就是向 /sys/bus/rbd/add_single_major 写入添加的 image 及 ceph 集群信息,通知 kernel 。

写入的信息参考如下:

192.168.122.114:6789,192.168.122.25:6789,192.168.122.174:6789 name=admin rbd test -
|________________________ mon info _________________________| |________| |_| |__||_|
                                                                   |      |    |  |
                                                                  \|/     |    |  |
                                                                  auth    |    |  |
                                                                         \|/   |  |
                                                                         pool  |  |
                                                                               |  |
                                                                              \|/ |
                                                                              img |
                                                                                 \|/
                                                                                 snap


二、kernel 完成剩下的工作

1. 首先会安装 libceph, rbd 两个模块

这两个模块,如果`rbd map` 执行时没安装,则会在 map_image(参见 "一、通知 kernel --> 2. 调用流程") 中安装:

map_image 会探测 rbd 模块是否安装,没有会安装模块:

 302   /*
 303    * Modprobe rbd kernel module.  If it supports single-major device
 304    * number allocation scheme, make sure it's turned on.
 305    */
 306   if (access("/sys/bus/rbd", F_OK) != 0) {
 307     const char *module_options = NULL;
 308     if (module_has_param("rbd", "single_major"))
 309       module_options = "single_major=Y";
 310
 311     r = module_load("rbd", module_options);
 312     if (r) {
 313       cerr << "rbd: failed to load rbd kernel module (" << r << ")"
 314            << std::endl;
 315       /*
 316        * Ignore the error: modprobe failing doesn't necessarily prevent
 317        * from working.
 318        */
 319     }
 320   }

 

2. kernel 入口:

drivers/block/rbd.c

6471 module_init(rbd_init);

 

3. rbd_init:

a. rbd_slab_init

b. alloc_workqueue

c. register_blkdev

d. rbd_sysfs_init


4. rbd_sysfs_init 流程
rbd_sysfs_init --> device_register && bus_register

bus_register 注册时传入了 rbd_bus_type

rbd_bus_type --> rbd_bus_group --> rbd_bus_attrs

rbd_bus_attrs 中定义了 add/remove 相关的属性文件,

如果我们向 add_single_major 文件写入时,kernel 将调用相应的函数来完成相应工作,这里的函数是 rbd_add_single_major.


rbd_bus_type --> rbd_bus_group --> rbd_bus_attrs 相关的定义如下:

 503 static BUS_ATTR(add, S_IWUSR, NULL, rbd_add);
 504 static BUS_ATTR(remove, S_IWUSR, NULL, rbd_remove);
 505 static BUS_ATTR(add_single_major, S_IWUSR, NULL, rbd_add_single_major);
 506 static BUS_ATTR(remove_single_major, S_IWUSR, NULL, rbd_remove_single_major);
 507 static BUS_ATTR(supported_features, S_IRUGO, rbd_supported_features_show, NULL);
 508
 509 static struct attribute *rbd_bus_attrs[] = {
 510         &bus_attr_add.attr,
 511         &bus_attr_remove.attr,
 512         &bus_attr_add_single_major.attr,
 513         &bus_attr_remove_single_major.attr,
 514         &bus_attr_supported_features.attr,
 515         NULL,
 516 };
 517

...

 529 static const struct attribute_group rbd_bus_group = {
 530         .attrs = rbd_bus_attrs,
 531         .is_visible = rbd_bus_is_visible,
 532 };
 533 __ATTRIBUTE_GROUPS(rbd_bus);
 534
 535 static struct bus_type rbd_bus_type = {
 536         .name           = "rbd",
 537         .bus_groups     = rbd_bus_groups,
 538 };

 


5. rbd_add_single_major 分析:

                                      rbd_dev_create
                                     /
rbd_add_single_major --> do_rbd_add /
                                    \
                                     \
                                      rbd_dev_device_setup

rbd_dev_create, rbd_dev_device_setup 完成了 创建 rbd device 的工作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Ceph是一个分布式存储系统,包括多个组件,其中包括Librbd块存储库。在Ceph中,Librbd提供了一种将RBD(块设备)映射到客户端的方法,并使客户端能够读写这些设备。在本文中,我们将分析Librbd块存储库的源代码以及RBD的读写过程。 1. Librbd源码分析 Librbd块存储库的源代码位于src/librbd目录下。其中,包括librbd.cc、ImageCtx.cc、ImageWatcher.cc、Journal.cc等多个源代码文件。这些源代码文件组成了Librbd块存储库的核心。 其中,librbd.cc是Librbd块存储库的主要源代码文件。在这个文件中,包括了Librbd的初始化、映射、卸载等方法。ImageCtx.cc则是Image上下文,用于管理Image的状态、锁定、映射等信息。ImageWatcher.cc用于监控Image的状态变化,Journal.cc则是Librbd的Journal日志管理。 2. RBD读写流程源码分析 在Ceph中,RBD由client和server两个部分组成。client在客户端上运行,提供了将RBD映射到客户端的方法。server在存储集群中运行,提供了RBD的存储和管理。 RBD的读写流程如下: 1)客户端向Ceph Monitor请求RBD映射信息,Monitor返回Image ID和Image特性; 2)客户端向Ceph OSD请求RBD数据块,OSD返回数据块内容; 3)客户端将数据写入或读取到本地块设备; 4)客户端向Ceph OSD写入或读取数据块,OSD返回操作结果; 5)客户端向Ceph Monitor请求解除RBD映射,Monitor返回解除结果。 在上述过程中,涉及到的源代码文件有:librbd.cc、ImageCtx.cc、ImageWatcher.cc、Journal.cc等。 总结 Librbd块存储库和RBD读写流程是Ceph存储系统的核心组件之一,通过分析源代码可以更加深入地了解Ceph存储系统的实现原理。同时,对于开发者来说,也有助于在Ceph存储系统上构建更加高效、稳定的存储应用。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值