RBD創建一個image

RBD創建一個image的過程分析。

rbd.cc
do_create(librbd::RBD &rbd, librados::IoCtx& io_ctx,const char *imgname,
          uint64_t size, int *order,int format, uint64_t features,
          uint64_t stripe_unit, uint64_t stripe_count) //創建一個image
    >rbd.create3(io_ctx, imgname, size, features, order,stripe_unit, stripe_count)/create(...) //rbd 創建image
        >librbd::create(io_ctx, name, size, false, features, order,stripe_unit, stripe_count) //librbd 創建image
            >detect_format(io_ctx, imgname, NULL, NULL) //獲取image的格式,這裏用它來判斷該image是否存在
            >uint64_t bid = rados.get_instance_id()
            >create_v1(io_ctx, imgname, bid, size, *order) //format == 1
            >create_v2(io_ctx, imgname, bid, size, *order, features,stripe_unit, stripe_count) //format ==2 以v2爲例
                >validate_pool(io_ctx, cct) //判斷pool是否有效
                >id_obj_name(imgname) //構建image的ID rbd_id.{imgname}
                >io_ctx.create(id_obj, true) //創建image的ID對象
                    >io_ctx_impl->create(obj, exclusive) //創建object_t的實例
                        >io_ctx_impl->create(obj, exclusive)
                            >op.create(exclusive) //op(ObjectOperation)
                                >::ObjectOperation *o = (::ObjectOperation *)impl;
                                >o->create(exclusive)
                                    >OSDOp& o = add_op(CEPH_OSD_OP_CREATE)
                            >operate(oid, &op, NULL)
                                >Objecter::Op *objecter_op = objecter->prepare_mutate_op(oid, oloc,*o, snapc, ut, flags,NULL, oncommit, &ver)
                                >objecter->op_submit(objecter_op) //提交Objecter::Op,進入Objecter層
                >cls_client::set_id(&io_ctx, id_obj, id) //設置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<SimpleMessenger*>(msgr)->send_message(m, this) //使用使用massenger層的SimpleMessenger的實例發生消息
                                                        >_send_message(m, con)
                                                            >submit_message(m, static_cast<PipeConnection*>(con),con->get_peer_addr(), con->get_peer_type(), false) //提交信息
                                                                >static_cast<PipeConnection*>(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中。


                >cls_client::dir_add_image(&io_ctx, RBD_DIRECTORY, imgname, id) //將新建的image註冊到RBD_DIRECTORY中
                    >ioctx->exec(oid, "rbd", "dir_add_image", in, out) //做用於跨網絡傳輸的序列化工作
                        >io_ctx_impl->exec(obj, cls, method, inbl, outbl) 
                            >rd.call(cls, method, inbl) //rd是(::ObjectOperation)的實例
                            >operate_read(oid, &rd, &outbl)
                                >Objecter::Op *objecter_op = objecter->prepare_read_op(oid, oloc,*o, snap_seq, pbl, flags,onack, &ver) //構建Objecter::Op的實例
                                >objecter->op_submit(objecter_op) //進入Objecter層
                                ...同上
                >header_name(id) //構建image的header標識
                >cls_client::create_image(&io_ctx, header_oid, size, order,features, oss.str()) //創建image的header對象
                    >ioctx->exec(oid, "rbd", "create", bl, bl2) //命令模式,爲跨網絡傳輸做序列化工作
                        >io_ctx_impl->exec(obj, cls, method, inbl, outbl) 
                            >rd.call(cls, method, inbl)
                            >operate_read(oid, &rd, &outbl)
                                >Objecter::Op *objecter_op = objecter->prepare_read_op(oid, oloc,*o, snap_seq, pbl, flags,onack, &ver)
                                >objecter->op_submit(objecter_op) //進入Objecter層
                                ...同上
                >cls_client::set_stripe_unit_count(&io_ctx, header_oid,stripe_unit, stripe_count) //設置image stripe的相關屬性,與header對象關聯
                    >ioctx->exec(oid, "rbd", "set_stripe_unit_count", in, out)
                        >io_ctx_impl->exec(obj, cls, method, inbl, outbl) 
                            >rd.call(cls, method, inbl)
                            >operate_read(oid, &rd, &outbl)
                                >Objecter::Op *objecter_op = objecter->prepare_read_op(oid, oloc,*o, snap_seq, pbl, flags,onack, &ver) //構建Objecter::Op的實例
                                >objecter->op_submit(objecter_op) //進入Objecter層
                >cls_client::object_map_resize(&op, Striper::get_num_objects(layout, size),OBJECT_NONEXISTENT) //構建op,該op用於resize object map
                    >rados_op->exec("rbd", "object_map_resize", in) //rados_op(librados::ObjectWriteOperation) 做序列化工作
                        >::ObjectOperation *o = (::ObjectOperation *)impl; 
                        >o->call(cls, method, inbl);
                >io_ctx.operate(ObjectMap::object_map_name(id, CEPH_NOSNAP), &op) //執行op
                    >io_ctx_impl->operate(obj, (::ObjectOperation*)o->impl, o->pmtime)
                        >Objecter::Op *objecter_op = objecter->prepare_mutate_op(oid, oloc,*o, snapc, ut, flags,NULL, oncommit, &ver) //創建Objecter::Op的實例,將ObjectOperation轉化成Objecter::Op
                        >objecter->op_submit(objecter_op) //提交Objecter::Op,進入Objecter層



創建一個Image的步驟(新image組成格式):
1.創建image的ID對象 rbd_id.{imagename}
2.創建image的id(隨機生產的,與image的ID對象完全不同)
3.將該image註冊到RBD_DIRECTORY中(imagename ,id)
4.創建image的header對象
6.將image的相關元信息,綁定到header對象上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章