static int commit_period(RGWRealm& realm, RGWPeriod& period,
string remote, const string& url,
- const string& access, const string& secret)
+ const string& access, const string& secret,
+ bool force)
{
const string& master_zone = period.get_master_zone();
if (master_zone.empty()) {
return ret;
}
// the master zone can commit locally
- ret = period.commit(realm, current_period, cerr);
+ ret = period.commit(realm, current_period, cerr, force);
if (ret < 0) {
cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl;
}
const string& period_id, const string& period_epoch,
bool commit, const string& remote, const string& url,
const string& access, const string& secret,
- Formatter *formatter)
+ Formatter *formatter, bool force)
{
RGWRealm realm(realm_id, realm_name);
int ret = realm.init(g_ceph_context, store);
return ret;
}
if (commit) {
- ret = commit_period(realm, period, remote, url, access, secret);
+ ret = commit_period(realm, period, remote, url, access, secret, force);
if (ret < 0) {
cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl;
return ret;
{
int ret = update_period(realm_id, realm_name, period_id, period_epoch,
commit, remote, url, access_key, secret_key,
- formatter);
+ formatter, yes_i_really_mean_it);
if (ret < 0) {
return -ret;
}
{
int ret = update_period(realm_id, realm_name, period_id, period_epoch,
commit, remote, url, access_key, secret_key,
- formatter);
+ formatter, yes_i_really_mean_it);
if (ret < 0) {
return -ret;
}
cerr << "period init failed: " << cpp_strerror(-ret) << std::endl;
return -ret;
}
- ret = commit_period(realm, period, remote, url, access_key, secret_key);
+ ret = commit_period(realm, period, remote, url, access_key, secret_key,
+ yes_i_really_mean_it);
if (ret < 0) {
cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl;
return -ret;
return r;
}
-int RGWPeriod::update_sync_status(const RGWPeriod ¤t_period)
+int RGWPeriod::update_sync_status(const RGWPeriod ¤t_period,
+ std::ostream& error_stream,
+ bool force_if_stale)
{
rgw_meta_sync_status status;
int r = read_sync_status(store, &status);
// no sync status markers for the current period
assert(current_epoch > status.sync_info.realm_epoch);
const int behind = current_epoch - status.sync_info.realm_epoch;
- lderr(cct) << "ERROR: This zone is " << behind << " period(s) behind "
- "the current master zone in metadata sync." << dendl;
- return -EINVAL;
+ if (!force_if_stale && current_epoch > 1) {
+ error_stream << "ERROR: This zone is " << behind << " period(s) behind "
+ "the current master zone in metadata sync. If this zone is promoted "
+ "to master, any metadata changes during that time are likely to "
+ "be lost.\n"
+ "Waiting for this zone to catch up on metadata sync (see "
+ "'radosgw-admin sync status') is recommended.\n"
+ "To promote this zone to master anyway, add the flag "
+ "--yes-i-really-mean-it." << std::endl;
+ return -EINVAL;
+ }
+ // empty sync status markers - other zones will skip this period during
+ // incremental metadata sync
+ markers.resize(status.sync_info.num_shards);
} else {
markers.reserve(status.sync_info.num_shards);
for (auto& i : status.sync_markers) {
}
int RGWPeriod::commit(RGWRealm& realm, const RGWPeriod& current_period,
- std::ostream& error_stream)
+ std::ostream& error_stream, bool force_if_stale)
{
ldout(cct, 20) << __func__ << " realm " << realm.get_id() << " period " << current_period.get_id() << dendl;
// gateway must be in the master zone to commit
// did the master zone change?
if (master_zone != current_period.get_master_zone()) {
// store the current metadata sync status in the period
- int r = update_sync_status(current_period);
+ int r = update_sync_status(current_period, error_stream, force_if_stale);
if (r < 0) {
ldout(cct, 0) << "failed to update metadata sync status: "
<< cpp_strerror(-r) << dendl;
const string get_period_oid_prefix();
// gather the metadata sync status for each shard; only for use on master zone
- int update_sync_status(const RGWPeriod ¤t_period);
+ int update_sync_status(const RGWPeriod ¤t_period,
+ std::ostream& error_stream, bool force_if_stale);
public:
RGWPeriod() : epoch(0), cct(NULL), store(NULL) {}
// commit a staging period; only for use on master zone
int commit(RGWRealm& realm, const RGWPeriod ¤t_period,
- std::ostream& error_stream);
+ std::ostream& error_stream, bool force_if_stale = false);
void encode(bufferlist& bl) const {
ENCODE_START(1, 1, bl);