From 5342660071d5901d13b5aa2b4f68561e90119be7 Mon Sep 17 00:00:00 2001 From: Orit Wasserman Date: Thu, 25 Jun 2015 10:45:24 +0200 Subject: [PATCH] rgw: Add RGWPeriod Signed-off-by: Orit Wasserman --- src/common/config_opts.h | 2 + src/rgw/rgw_json_enc.cc | 30 +++++++ src/rgw/rgw_rados.cc | 189 +++++++++++++++++++++++++++++++++++++++ src/rgw/rgw_rados.h | 95 +++++++++++++++++++- 4 files changed, 315 insertions(+), 1 deletion(-) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index f500757aca027..979cbe6a64bbd 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -1209,6 +1209,8 @@ OPTION(rgw_default_region_info_oid, OPT_STR, "default.region") // oid where def OPTION(rgw_realm, OPT_STR, "") // realm name OPTION(rgw_realm_root_pool, OPT_STR, ".rgw.root") // pool where all realm info is stored OPTION(rgw_default_realm_info_oid, OPT_STR, "default.realm") // oid where default realm info is stored +OPTION(rgw_period_root_pool, OPT_STR, ".rgw.root") // pool where all period info is stored +OPTION(rgw_period_latest_epoch_info_oid, OPT_STR, ".latest_epoch") // oid where current period info is stored OPTION(rgw_log_nonexistent_bucket, OPT_BOOL, false) OPTION(rgw_log_object_name, OPT_STR, "%Y-%m-%d-%H-%i-%n") // man date to see codes (a subset are supported) OPTION(rgw_log_object_name_utc, OPT_BOOL, false) diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index dad17a65e07e5..d799249842034 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -728,6 +728,36 @@ void RGWSystemMetaObj::decode_json(JSONObj *obj) JSONDecoder::decode_json("name", name, obj); } +void RGWPeriodLatestEpochInfo::dump(Formatter *f) const { + encode_json("latest_epoch", epoch, f); +} + +void RGWPeriodLatestEpochInfo::decode_json(JSONObj *obj) { + JSONDecoder::decode_json("latest_epoch", epoch, obj); +} + +void RGWPeriod::dump(Formatter *f) const +{ + encode_json("id", id , f); + encode_json("epoch", epoch , f); + encode_json("predecessor_uuid", predecessor_uuid, f); + encode_json("versions", versions, f); + encode_json("master_zonegroup", master_zonegroup, f); + encode_json("zonegroups", zonegroups, f); + encode_json("master_zone", master_zone, f); +} + +void RGWPeriod::decode_json(JSONObj *obj) +{ + JSONDecoder::decode_json("id", id, obj); + JSONDecoder::decode_json("epoch", epoch, obj); + JSONDecoder::decode_json("predecessor_uuid", predecessor_uuid, obj); + JSONDecoder::decode_json("versions", versions, obj); + JSONDecoder::decode_json("master_zonegroup", master_zonegroup, obj); + JSONDecoder::decode_json("zonesgroup", zonegroups, obj); + JSONDecoder::decode_json("master_zone", master_zone, obj); +} + void RGWZoneParams::dump(Formatter *f) const { encode_json("domain_root", domain_root.data_pool, f); diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index ebe9546d33570..47d96b0d61d26 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -74,6 +74,8 @@ static string region_info_oid_prefix = "region_info."; static string realm_names_oid_prefix = "realms_names."; static string realm_info_oid_prefix = "realms."; static string default_region_info_oid = "default.region"; +static string period_info_oid_prefix = "periods."; +static string period_latest_epoch_info_oid = ".latest_epoch"; static string region_map_oid = "region_map"; static string log_lock_name = "rgw_log_lock"; static string default_realm_info_oid = "default.realm"; @@ -85,6 +87,7 @@ static RGWObjCategory main_category = RGW_OBJ_CATEGORY_MAIN; #define RGW_DEFAULT_ZONE_ROOT_POOL "rgw.root" #define RGW_DEFAULT_REGION_ROOT_POOL "rgw.root" static string RGW_DEFAULT_REALM_ROOT_POOL = "rgw.root"; +static string RGW_DEFAULT_PERIOD_ROOT_POOL = "rgw.root"; #define RGW_STATELOG_OBJ_PREFIX "statelog." @@ -615,6 +618,192 @@ const string& RGWRealm::get_info_oid_prefix() return realm_info_oid_prefix; } +int RGWRealm::get_current_period_id() +{ + return -ENOTSUP; +} + +int RGWPeriod::init(const string& period_realm_id, const string& period_realm_name, bool setup_obj) +{ + realm_id = period_realm_id; + + if (!setup_obj) + return 0; + + RGWRealm realm(realm_id, period_realm_name); + int ret = realm.init(cct, store); + if (ret < 0) { + return ret; + } + + /* update realm_id incare we used a period_name */ + if (realm_id.empty()) { + realm_id = realm.get_id(); + } + + if (id.empty()) { + ret = realm.get_current_period_id(); + if (ret < 0) { + return ret; + } + } + + if (!epoch) { + ret = use_latest_epoch(); + if (ret < 0) { + return ret; + } + } + + return read_info(id); +} + +const string& RGWPeriod::get_latest_epoch_oid() +{ + if (cct->_conf->rgw_period_latest_epoch_info_oid.empty()) { + return period_latest_epoch_info_oid; + } + return cct->_conf->rgw_period_latest_epoch_info_oid; +} + +const string& RGWPeriod::get_info_oid_prefix() +{ + return period_info_oid_prefix; +} + +int RGWPeriod::read_latest_epoch(RGWPeriodLatestEpochInfo& info) +{ + string pool_name = get_pool_name(cct); + string oid = get_info_oid_prefix() + id + + get_latest_epoch_oid(); + + rgw_bucket pool(pool_name.c_str()); + bufferlist bl; + RGWObjectCtx obj_ctx(store); + int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL); + if (ret < 0) + return ret; + + try { + bufferlist::iterator iter = bl.begin(); + ::decode(info, iter); + } catch (buffer::error& err) { + derr << "error decoding data from " << pool << ":" << oid << dendl; + return -EIO; + } + + return 0; +} + +int RGWPeriod::get_latest_epoch(epoch_t& latest_epoch) +{ + RGWPeriodLatestEpochInfo info; + + int ret = read_latest_epoch(info); + if (ret < 0) { + return ret; + } + + latest_epoch = info.epoch; + + return 0; +} + +int RGWPeriod::use_latest_epoch() +{ + RGWPeriodLatestEpochInfo info; + int ret = read_latest_epoch(info); + if (ret < 0) + return ret; + + epoch = info.epoch; + + return 0; +} + + +int RGWPeriod::delete_obj() +{ + string pool_name = get_pool_name(cct); + rgw_bucket pool(pool_name.c_str()); + string oid = get_info_oid_prefix() + id; + + rgw_obj object_id(pool, oid); + int ret = store->delete_system_obj(object_id); + if (ret < 0) { + lderr(cct) << "Error delete object id " << id << ": " << cpp_strerror(-ret) << dendl; + } + + return ret; +} + +int RGWPeriod::read_info(const string& obj_id) +{ + string pool_name = get_pool_name(cct); + + rgw_bucket pool(pool_name.c_str()); + bufferlist bl; + + string oid = get_info_oid_prefix() + obj_id; + + RGWObjectCtx obj_ctx(store); + int ret = rgw_get_system_obj(store, obj_ctx, pool, oid, bl, NULL, NULL); + if (ret < 0) { + lderr(cct) << "failed reading obj info from " << pool << ":" << oid << ": " << cpp_strerror(-ret) << dendl; + return ret; + } + + try { + bufferlist::iterator iter = bl.begin(); + ::decode(*this, iter); + } catch (buffer::error& err) { + ldout(cct, 0) << "ERROR: failed to decode obj from " << pool << ":" << oid << dendl; + return -EIO; + } + + return 0; +} + +int RGWPeriod::create() +{ + int ret; + + /* create unique id */ + uuid_d new_uuid; + char uuid_str[37]; + new_uuid.generate_random(); + new_uuid.print(uuid_str); + id = uuid_str; + + ret = store_info(true); + if (ret < 0) { + ldout(cct, 0) << "ERROR: storing info for " << id << ": " << cpp_strerror(-ret) << dendl; + } + + return ret; +} + +int RGWPeriod::store_info(bool exclusive) +{ + string pool_name = get_pool_name(cct); + + rgw_bucket pool(pool_name.c_str()); + + string oid = get_info_oid_prefix() + id; + + bufferlist bl; + ::encode(*this, bl); + return rgw_put_system_obj(store, pool, oid, bl.c_str(), bl.length(), exclusive, NULL, 0, NULL); +} + +const string& RGWPeriod::get_pool_name(CephContext *cct) +{ + if (cct->_conf->rgw_period_root_pool.empty()) { + return RGW_DEFAULT_PERIOD_ROOT_POOL; + } + return cct->_conf->rgw_period_root_pool; +} + void RGWZoneParams::init_default(RGWRados *store) { domain_root = "rgw.data.root"; diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 5a43cedb743cd..29d07eb6cef46 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -781,7 +781,6 @@ public: int rename(const string& new_name); int update() { return store_info(false);} - virtual const string& get_pool_name(CephContext *cct) = 0; virtual const string& get_default_oid() = 0; @@ -1188,9 +1187,103 @@ public: void dump(Formatter *f) const; void decode_json(JSONObj *obj); + + int get_current_period_id(); }; WRITE_CLASS_ENCODER(RGWRealm) +struct RGWPeriodLatestEpochInfo { + epoch_t epoch; + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(epoch, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(epoch, bl); + DECODE_FINISH(bl); + } + + void dump(Formatter *f) const; + void decode_json(JSONObj *obj); +}; +WRITE_CLASS_ENCODER(RGWPeriodLatestEpochInfo) + +class RGWPeriod +{ + string realm_id; + string id; + epoch_t epoch; + string predecessor_uuid; + map versions; + string master_zonegroup; + map zonegroups; + string master_zone; + + CephContext *cct; + RGWRados *store; + + int store_info(bool exclusive); + int read_info(const string& obj_id); + int read_latest_epoch(RGWPeriodLatestEpochInfo& epoch_info); + int use_latest_epoch(); + int set_latest_epoch(const epoch_t& epoch); + int use_current_period(); + +public: + RGWPeriod(CephContext *_cct, RGWRados *_store, + const string& period_id = "", epoch_t _epoch = 0) + : id(period_id), epoch(_epoch), cct(_cct), store(_store) {} + + string get_id() { return id;} + epoch_t get_epoch() { return epoch;} + string get_predecessor() { return predecessor_uuid;} + string get_master_zonegroup() { return master_zonegroup;} + string get_master_zone() { return master_zone;} + + const string& get_pool_name(CephContext *cct); + const string& get_latest_epoch_oid(); + const string& get_info_oid_prefix(); + + int get_latest_epoch(epoch_t& epoch); + int init(const string& realm_id = "", const string &realm_name = "", bool setup_obj = true); + + int create(); + int delete_obj(); + int update(); + int activate() { return -ENOTSUP;} + + void encode(bufferlist& bl) const { + ENCODE_START(1, 1, bl); + ::encode(id, bl); + ::encode(epoch, bl); + ::encode(predecessor_uuid, bl); + ::encode(versions, bl); + ::encode(master_zonegroup, bl); + ::encode(zonegroups, bl); + ::encode(master_zone, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::iterator& bl) { + DECODE_START(1, bl); + ::decode(id, bl); + ::decode(epoch, bl); + ::decode(predecessor_uuid, bl); + ::decode(versions, bl); + ::decode(master_zonegroup, bl); + ::decode(zonegroups, bl); + ::decode(master_zone, bl); + DECODE_FINISH(bl); + } + void dump(Formatter *f) const; + void decode_json(JSONObj *obj); +}; +WRITE_CLASS_ENCODER(RGWPeriod) + class RGWDataChangesLog; class RGWReplicaLogger; -- 2.39.5