RGW多站点 -- RGWSystemMetaObj
源码
在多站点中,RGWZoneParams
、RGWZoneGroup
和RGWRealm
都直接继承RGWSystemMetaObj
。本文主要记录RGWSystemMetaObj
往RADOS层写入了哪些对象。
在创建realm、zonegroup及zone时,我们需要指定其name。创建成功后,每一个realm、zonegroup及zone都会有一个id。这个id和name就是有RGWSystemMetaObj
负责管理的。
粗略的观察一下SystemMetaObj
的部分成员函数:
protected:
int store_name(bool exclusive);
int store_info(bool exclusive);
int read_info(const std::string& obj_id, bool old_format = false);
int read_id(const std::string& obj_name, std::string& obj_id);
int read_default(RGWDefaultSystemMetaObjInfo& default_info,
const std::string& oid);
/* read and use default id */
int use_default(bool old_format = false);
public:
virtual int create(bool exclusive = true);
virtual rgw_pool get_pool(CephContext *cct) const = 0;
virtual const std::string get_default_oid(bool old_format = false) const = 0;
virtual const std::string& get_names_oid_prefix() const = 0;
virtual const std::string& get_info_oid_prefix(bool old_format = false) const = 0;
virtual const std::string& get_predefined_name(CephContext *cct) const = 0;
可以看到,其将id、name抽象为两个部分, name和info,有什么区别呢?
进入两者的实现:
int RGWSystemMetaObj::store_name(bool exclusive) {
rgw_pool pool(get_pool(cct));
string oid = get_names_oid_prefix() + name;
RGWNameToId nameToId;
nameToId.obj_id = id;
bufferlist bl;
using ceph::encode;
encode(nameToId, bl);
auto obj_ctx = sysobj_svc->init_obj_ctx();
auto sysobj = sysobj_svc->get_obj(obj_ctx, rgw_raw_obj(pool, oid));
return sysobj.wop().set_exclusive(exclusive).write(bl);
}
int RGWSystemMetaObj::store_info(bool exclusive) {
rgw_pool pool(get_pool(cct));
string oid = get_info_oid_prefix() + id;
bufferlist bl;
using ceph::encode;
encode(*this, bl);
auto obj_ctx = sysobj_svc->init_obj_ctx();
auto sysobj = sysobj_svc->get_obj(obj_ctx, rgw_raw_obj{pool, oid});
return sysobj.wop().set_exclusive(exclusive).write(bl);
}
可以看到,代码片段基本相似,区别在于 pool name 和 oid 的不同,这两个变量依赖于具体的子类实现。
store_name
将 RGWNameToId
写入到对象, 而store_info
将RGWSystemMetaObj
写入到对象。
以类图中提到的三个子类为例,其对应的 pool和oid如下:
SubClass | type | pool | oid | value |
---|---|---|---|---|
RGWRealm |
info | .rgw.root (rgw_realm_root_pool) | realms. | RGWSystemMetaObj |
-- | name | .rgw.root | realms_names. | RGWNameToId |
RGWZoneGroup |
info | .rgw.root (rgw_zonegroup_root_pool) | zonegroup_info. | RGWSystemMetaObj |
-- | name | .rgw.root | zonegroups_names. | RGWNameToId |
RGWZoneParams |
info | .rgw.root (rgw_zone_root_pool) | zone_info. | RGWSystemMetaObj |
-- | name | .rgw.root | zone_names. | RGWNameToId |
需要注意的时,在代码中,pool默认是
rgw.root
,只不过conf中默认是.rgw.root
当我们创建realm、zonegroup或zone时,最终都会调用到RGWSystemMetaObj::create
,再通过它间接调用store_info
和store_name
:
int RGWSystemMetaObj::create(bool exclusive) {
int ret;
//对于create,id必然是不存在的,所以需要生成一个id
ret = read_id(name, id);
if (id.empty()) {
/* create unique id */
uuid_d new_uuid;
char uuid_str[37];
new_uuid.generate_random();
new_uuid.print(uuid_str);
id = uuid_str;
}
//创建一个名为 {realms/zonegroup_info/zone_info}.{id}的对象,内容为 RGWSystemMetaObj
ret = store_info(exclusive);
if (ret < 0) {
ldout(cct, 0) << "ERROR: storing info for " << id << ": "
<< cpp_strerror(-ret) << dendl;
return ret;
}
//创建一个名为{realms_names/zonegroups_names/zone_names}.{name}的对象,对象内容为 RGWNameToId
return store_name(exclusive);
}
总结
在RGWSystemMetaObj
中,info对应的是id,而name则是name。