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)
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);
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";
#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."
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";
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;
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<int, version_t> versions;
+ string master_zonegroup;
+ map <string, RGWRegion> 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;