ceph 版本:0.94.7
rbd命令操作的资源有volume(默认)、snap、lock三类资源
using rbd to create empty image
rbd create --size 1024000 test1
ceph/src/rbd.cc
>main(...)
[code section 定义一些后期使用到的实例及局部变量]
[cs 提取传入的参数]
><global_init(...) [全局初始化工作]
[cs 解析输入参数,并初始化部分局部变量]
><common_init_finish(...) [完成通用组件的初始化]
[cs 确定操作符,并初始化部分局部变量]
[cs 检查输入参数是否合法]
[注:除OPT_MAP/OPT_UNMAP/OPT_SHOWMAPPED/OPT_MERGE_DIFF操作外其他的都需要与服务端建立连接]
><rados.init_with_context(...) [初始化rados handler]
><rados.connect() [连接服务端]
><rados.ioctx_create(poolname, io_ctx) [打开存储池, 初始化io_ctx]
[cs 注:order大小必须在12~25之间,即对象大小范围4KB~32MB]
>do_create(...) [创建volume]
[location src/librbd/librbd.cc]
>rbd.create(...) or rbd.create3(...) [创建volume]
[location src/librbd/internal.cc]
>librbd::create(...) [为创建volume,设置feature]
>librbd::create(...) [创建volume]
>detect_format(...) [探测对象的格式(do not care)]
[location src/librados/librados.cc]
>io_ctx.stat(...) [检查对象是否存在]
><io_ctx_impl->stat(...)
<io_ctx.stat(...)
<detect_format(...)
Rados rados(io_ctx)
><rados.get_instance_id(...)
>create_v1(...) [创建volume]
><validate_pool(...) [验证pool]
><tmap_set(...) [添加image到directory中]
struct rbd_obj_header_ondisk header
><init_rbd_header(...) [初始化header]
><io_ctx.write(...) [写入对象]
[注:image的header对象中保存该对象的元信息]
<create_v1(...)
<librbd::create(...)
<librbd::create(...)
<rbd.create(...) or rbd.create(...)
<do_create(...)
[location src/librados/librados.cc]
主要是实例化RadosClient(Dispatcher),相对于服务端的client。
rados.init_with_context(...)
>rados_create_with_context(...)
><libradso::RadosClient *radosp = new librados::RadosClient(...)
<rados_create_with_context(....)
rados.connect()
>client->connect()
><monclient.build_initial_monmap() [获取monmap]
><messenger = Messenger::create_client_messenger(...) [创建client端messenger层的实例]
><messenger->set_default_policy(...) [设置policy]
><objecter = new (std::nothrow) Objecter(...)
><monclient.set_messenger(messenger);
><objecter->init() [初始化性能计数器]
><messenger->add_dispatcher_tail(objecter)
><messenger->add_dispatcher_tail(this)
><messenger->start()
><monclient.init()
><monclient.authenticate(...)
><objecter->start()
><monclient.renew_subs()
><finisher.start()
><instance_id = monclient.get_global_id()
<client->connect()
获取mon map
monclient.build_initial_monmap()
messenger->start()