ceph的pool创建流程--代码分析

原链接

http://blog.csdn.net/carny/article/details/52240828


ceph中的pool有两种类型:replicated pool和erasure pool
这里从rados接口开始跟踪分析一下pool的创建过程


一、rados接口部分
1、rados里创建pool的接口是(librados.cc)
int librados::Rados::pool_create(const char *name);
int librados::Rados::pool_create(const char *name, uint64_t auid);
int librados::Rados::pool_create(const char *name, uint64_t auid, __u8 crush_rule);
int librados::Rados::pool_create_async(const char *name, PoolAsyncCompletion *c);
int librados::Rados::pool_create_async(const char *name, uint64_t auid, PoolAsyncCompletion *c);
int librados::Rados::pool_create_async(const char *name, uint64_t auid, __u8 crush_rule,
      PoolAsyncCompletion *c);

这些接口最终是会调用librados::RadosClient下的响应接口,比如
int librados::Rados::pool_create(const char *name, uint64_t auid, __u8 crush_rule);
调用的是
int librados::RadosClient::pool_create(string& name, unsigned long long auid,
      int16_t crush_rule);
这里就以这个接口为例跟踪


2、int librados::RadosClient::pool_create(string& name, unsigned long long auid,
      int16_t crush_rule)

   A、先是获取osdmap,获取失败后,则返回
   int librados::RadosClient::wait_for_osdmap()
   这里面是从radosclient的objecter里读取osdmap,如果没有osdmap,那么会等待objecter获取到osdmap,直到超时(默认一直等OPTION(rados_mon_op_timeout, OPT_DOUBLE, 0))
   B、调用reply = objecter->create_pool(name, onfinish, auid, crush_rule);
       开始创建pool,并设置了回调函数onfinish
   C、如果上面的函数调用成功,则会一直等待创建的结果
3、int create_pool(string& name, Context *onfinish, uint64_t auid=0,

 int crush_rule=-1);



4、void Objecter::pool_op_submit(PoolOp *op)
{
  // rwlock is locked
  if (mon_timeout > timespan(0)) {
    op->ontimeout = timer.add_event(mon_timeout,
   [this, op]() {
     pool_op_cancel(op->tid, -ETIMEDOUT); });
  }
  _pool_op_submit(op);
}


5、void Objecter::_pool_op_submit(PoolOp *op)
构建与mon通讯的对象,然后发送消息给monitor,请求创建创建pool
monc->send_mon_message(m);
消息的类型为CEPH_MSG_POOLOP




二、Monitor消息处理部分
monitor接收消息后,消息处理流程如下




CEPH_MSG_POOLOP是由OSDMonitor处理的
    case CEPH_MSG_POOLOP:
      paxos_service[PAXOS_OSDMAP]->dispatch(op);  //这里不应答客户端?
      break;


1、bool PaxosService::dispatch(MonOpRequestRef op)
   A、首先会丢弃旧消息
   
   
   B、确认osdmap是最新的
   
   m->version指的是客户端的osdmap的版本,如果m->version比本地的版本要新,则会通过paxos协议获取最新的osdmap版本
   wait_for_readable将当前的操作OP添加到proposal队列里,获取成功后,会通过回调函数重试
   
   C、preprocess_query是查询操作,在这里属于更新操作,所以与这个函数无关,这部分可以先学习paxos的内容
   D、更新操作,prepare_update()的实现是bool OSDMonitor::prepare_update(MonOpRequestRef op)
   该函数里调用bool OSDMonitor::prepare_pool_op(MonOpRequestRef op)
   
   然后函数里判断是创建pool操作,进一步调用prepare_pool_op_create
   
2、bool OSDMonitor::prepare_pool_op_create(MonOpRequestRef op)


prepare_new_pool函数根据参数,设置crush_ruleset,pg_num,pgp_num,副本数,以及纠删池的条带宽度等
在设置完上面的参数后,会到pending_inc.new_pool_names (OSDMap::Incremental pending_inc;)里查找,是否已经存在相同名字的pool,如果有则返回,不重复创建,否则,创建一个新的pool对象,并添加的pending_inc.new_pool_names里,一遍后续提交,最后为新的pool添加一些参数




在所有参数都设置完成后,需要commit当前的信息到各个monitor节点
wait_for_finished_proposal(op, new OSDMonitor::C_PoolOp(this, op, err, pending_inc.epoch));
上面的函数将操作压入paxos 的proposal队列,以便提交
在回调函数里,会根据提交结果,应答客户端




3、然后又回到了PaxosService::dispatch(MonOpRequestRef op)函数里,
prepare_update(op)根据返回值,决定是否需要触发paxos流程:




4、上面的propose_pending的实现是void PaxosService::propose_pending()
void PaxosService::propose_pending()的实现如下
   A、创建一个paxos事务
   MonitorDBStore::TransactionRef t = paxos->get_pending_transaction();
   B、调用encode_pending函数实现序列化,实际上是由void OSDMonitor::encode_pending(MonitorDBStore::TransactionRef t)实现
   encode_pending函数里会先拷贝一份当前的osdmap,然后将pending_inc(即OSDMap::Incremental pending_inc;)里的内容应用到拷贝出来的新的osdmap,生成一份新的完整的OSDMap
   
   同时将版本号,和最后提交的序号序列化进入事务里
   C、最后应用到paxos里面去
   // apply to paxos
  proposing = true;
  paxos->queue_pending_finisher(new C_Committed(this));
  paxos->trigger_propose();
  
  这里回调函数C_Committed(this)里会调用void PaxosService::_active()
  最终会调用finish_contexts(g_ceph_context, waiting_for_finished_proposal, 0);唤醒创建pool的op操作(在prepare_pool_op_create函数里设置了wait_for_finished_proposal(op, new OSDMonitor::C_PoolOp(this, op, err, pending_inc.epoch));)
  OSDMonitor::C_PoolOp的回调函数回根据paxos的结果,应答客户端
  
  

  至此,pool创建流程接收。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值