librados是ceph rados对外提供服务的原生api,本文是libradso接口调用的过程(从之前的文中摘录)。
设置image 的id
ioctx->exec(oid, "rbd", "set_id", in, out)
>io_ctx_impl->exec(obj, cls, method, inbl, outbl)
>(::ObjectOperation)rd.call(cls, method, inbl) //将该操作封装成OSDOp,放入ObjectOperation对象的vector集合中
>add_call(CEPH_OSD_OP_CALL, cname, method, indata, NULL, NULL, NULL)
>operate_read(oid, &rd, &outbl) //发起读请求
>Objecter::Op *objecter_op = objecter->prepare_read_op(oid, oloc,*o, snap_seq, pbl, flags,onack, &ver) //创建Op的实例 数据结构变成Op
>objecter->op_submit(objecter_op) //提交到objecter层 操作对象为Objecter::Op
>_op_submit_with_budget(op, lc, ctx_budget)
>int op_budget = _take_op_budget(op) //减去该Op的预算for throttle;
>int op_budget = calc_op_budget(op) //预算值是该Op的字节大小
> _throttle_op(op, op_budget) //这里是Objecter的Throttle层,如果keep_balanced_budget=true,能实现对速度的限制(op_throttle_bytes&op_throttle_ops)
>_op_submit(op, lc)
>_calc_target(&op->target, &op->last_force_resend) //计算该op的操作对象(用到CRUSH算法)
>_get_session(op->target.osd, &s, lc) //为该Op构建与osd对应的OSDSession
>_send_op_account(op) //登记该次op操作
> m = _prepare_osd_op(op) //使用Op中的信息,初始化MOSDOp的实例
>_session_op_assign(s, op) //将Op与OSDSession相关联。
> _send_op(op, m)
>op->session->con->send_message(m) //进入Massenger层,操作对象MOSDOp
>static_cast(msgr)->send_message(m, this) //使用使用massenger层的SimpleMessenger的实例发生消息
>_send_message(m, con)
>submit_message(m, static_cast(con),con->get_peer_addr(), con->get_peer_type(), false) //提交信息
>static_cast(con)->try_get_pipe(&pipe) //获取该PipConnection对应的Pipe的实例
>pipe->_send(m) //通过Pipe发送消息,即:把消息放入到Pipe::out_q队列中,并通知Pipe中的写线程来做实际的发生操作。
>out_q[m->get_priority()].push_back(m);
>dispatch_queue.local_delivery(m, m->get_priority()) //如果发送端与接收端是同一个,则直接将消息投递到DispathcQueue::local_messages中。
写入数据
m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &m_write,m_snap_seq, m_snaps)
>io_ctx_impl->aio_operate(obj, (::ObjectOperation*)o->impl, c->pc,snapc, 0)
>objecter->mutate(oid, oloc, *o, snap_context, ut, flags, onack, oncommit,&c->objver) //进入Objecter层
>prepare_mutate_op(oid, oloc, op, snapc, mtime, flags, onack, oncommit, objver) //封装成Op
>objecter->op_submit(objecter_op) //提交到objecter层 操作对象为Objecter::Op
>_op_submit_with_budget(op, lc, ctx_budget)
>int op_budget = _take_op_budget(op) //减去该Op的预算for throttle;
>int op_budget = calc_op_budget(op) //预算值是该Op的字节大小
> _throttle_op(op, op_budget) //这里是Objecter的Throttle层,如果keep_balanced_budget=true,能实现对速度的限制(op_throttle_bytes&op_throttle_ops)
>_op_submit(op, lc)
>_calc_target(&op->target, &op->last_force_resend) //计算该op的操作对象(用到CRUSH算法)
>_get_session(op->target.osd, &s, lc) //为该Op构建与osd对应的OSDSession
>_send_op_account(op) //登记该次op操作
> m = _prepare_osd_op(op) //使用Op中的信息,初始化MOSDOp的实例
>_session_op_assign(s, op) //将Op与OSDSession相关联。
> _send_op(op, m)
>op->session->con->send_message(m) //进入Massenger层,操作对象MOSDOp
>static_cast(msgr)->send_message(m, this) //使用使用massenger层的SimpleMessenger的实例发生消息
>_send_message(m, con)
>submit_message(m, static_cast(con),con->get_peer_addr(), con->get_peer_type(), false) //提交信息
>static_cast(con)->try_get_pipe(&pipe) //获取该PipConnection对应的Pipe的实例
>pipe->_send(m) //通过Pipe发送消息,即:把消息放入到Pipe::out_q队列中,并通知Pipe中的写线程来做实际的发生操作。
>out_q[m->get_priority()].push_back(m);
>dispatch_queue.local_delivery(m, m->get_priority()) //如果发送端与接收端是同一个,则直接将消息投递到DispathcQueue::local_messages中。
摘录于
摘录于