encode_json("period_config", period_config, f);
encode_json("realm_id", realm_id, f);
encode_json("realm_name", realm_name, f);
+ encode_json("realm_epoch", realm_epoch, f);
}
void RGWPeriod::decode_json(JSONObj *obj)
JSONDecoder::decode_json("period_config", period_config, obj);
JSONDecoder::decode_json("realm_id", realm_id, obj);
JSONDecoder::decode_json("realm_name", realm_name, obj);
+ JSONDecoder::decode_json("realm_epoch", realm_epoch, obj);
}
void RGWZoneParams::dump(Formatter *f) const
{
RGWSystemMetaObj::dump(f);
encode_json("current_period", current_period, f);
+ encode_json("epoch", epoch, f);
}
{
RGWSystemMetaObj::decode_json(obj);
JSONDecoder::decode_json("current_period", current_period, obj);
+ JSONDecoder::decode_json("epoch", epoch, obj);
}
void KeystoneToken::Metadata::decode_json(JSONObj *obj)
int RGWRealm::set_current_period(RGWPeriod& period)
{
+ // update realm epoch to match the period's
+ if (epoch > period.get_realm_epoch()) {
+ lderr(cct) << "ERROR: set_current_period with old realm epoch "
+ << period.get_realm_epoch() << ", current epoch=" << epoch << dendl;
+ return -EINVAL;
+ }
+ if (epoch == period.get_realm_epoch() && current_period != period.get_id()) {
+ lderr(cct) << "ERROR: set_current_period with same realm epoch "
+ << period.get_realm_epoch() << ", but different period id "
+ << period.get_id() << " != " << current_period << dendl;
+ return -EINVAL;
+ }
+ epoch = period.get_realm_epoch();
current_period = period.get_id();
int ret = update();
predecessor_uuid = id;
id = get_staging_id(realm_id);
period_map.reset();
+ realm_epoch++;
}
void RGWPeriod::update(const RGWZoneGroupMap& map)
<< dendl;
return -EINVAL;
}
+ // realm epoch must be 1 greater than current period
+ if (realm_epoch != current_period.get_realm_epoch() + 1) {
+ lderr(cct) << "period's realm epoch " << realm_epoch
+ << " does not come directly after current realm epoch "
+ << current_period.get_realm_epoch() << dendl;
+ return -EINVAL;
+ }
// did the master zone change?
if (master_zone != current_period.get_master_zone()) {
// store the current metadata sync status in the period
set_id(current_period.get_id());
set_epoch(current_period.get_epoch() + 1);
set_predecessor(current_period.get_predecessor());
+ realm_epoch = current_period.get_realm_epoch();
// write the period to rados
int r = store_info(false);
if (r < 0) {
class RGWRealm : public RGWSystemMetaObj
{
string current_period;
+ epoch_t epoch{0}; //< realm epoch, incremented for each new period
int create_control();
int delete_control();
ENCODE_START(1, 1, bl);
RGWSystemMetaObj::encode(bl);
::encode(current_period, bl);
+ ::encode(epoch, bl);
ENCODE_FINISH(bl);
}
DECODE_START(1, bl);
RGWSystemMetaObj::decode(bl);
::decode(current_period, bl);
+ ::decode(epoch, bl);
DECODE_FINISH(bl);
}
}
int set_current_period(RGWPeriod& period);
+ epoch_t get_epoch() const { return epoch; }
+
string get_control_oid();
/// send a notify on the realm control object
int notify_zone(bufferlist& bl);
string realm_id;
string realm_name;
+ epoch_t realm_epoch{1}; //< realm epoch when period was made current
CephContext *cct;
RGWRados *store;
const string& get_id() const { return id; }
epoch_t get_epoch() const { return epoch; }
+ epoch_t get_realm_epoch() const { return realm_epoch; }
const string& get_predecessor() const { return predecessor_uuid; }
const string& get_master_zone() const { return master_zone; }
const string& get_master_zonegroup() const { return master_zonegroup; }
int commit(RGWRealm& realm, const RGWPeriod ¤t_period);
void encode(bufferlist& bl) const {
- ENCODE_START(1, 1, bl);
+ ENCODE_START(1, 1, bl);
::encode(id, bl);
::encode(epoch, bl);
+ ::encode(realm_epoch, bl);
::encode(predecessor_uuid, bl);
::encode(sync_status, bl);
::encode(period_map, bl);
DECODE_START(1, bl);
::decode(id, bl);
::decode(epoch, bl);
+ ::decode(realm_epoch, bl);
::decode(predecessor_uuid, bl);
::decode(sync_status, bl);
::decode(period_map, bl);