handlers.clear();
}
+static RGWPeriodHistory::Cursor find_oldest_log_period(RGWRados* store)
+{
+ // TODO: search backwards through the period history for the first period with
+ // no log shard objects, and return its successor (some shards may be missing
+ // if they contain no metadata yet, so we need to check all shards)
+ return store->period_history->get_current();
+}
+
int RGWMetadataManager::init(const std::string& current_period)
{
+ // find our oldest log so we can tell other zones where to start their sync
+ oldest_log_period = find_oldest_log_period(store);
+
+ // open a log for the current period
current_log = get_log(current_period);
return 0;
}
#include "include/types.h"
#include "rgw_common.h"
+#include "rgw_period_history.h"
#include "cls/version/cls_version_types.h"
#include "cls/log/cls_log_types.h"
#include "common/RWLock.h"
std::map<std::string, RGWMetadataLog> md_logs;
// use the current period's log for mutating operations
RGWMetadataLog* current_log = nullptr;
+ // oldest log's position in the period history
+ RGWPeriodHistory::Cursor oldest_log_period;
void parse_metadata_key(const string& metadata_key, string& type, string& entry);
int init(const std::string& current_period);
+ RGWPeriodHistory::Cursor get_oldest_log_period() const {
+ return oldest_log_period;
+ }
+
/// find or create the metadata log for the given period
RGWMetadataLog* get_log(const std::string& period);
void RGWOp_MDLog_Info::execute() {
num_objects = s->cct->_conf->rgw_md_log_max_shards;
- // TODO: return the period id of our oldest metadata log
- http_ret = 0;
+ period = store->meta_mgr->get_oldest_log_period();
+ http_ret = period.get_error();
}
void RGWOp_MDLog_Info::send_response() {
dump_errno(s);
end_header(s);
- s->formatter->open_object_section("num_objects");
+ s->formatter->open_object_section("mdlog");
s->formatter->dump_unsigned("num_objects", num_objects);
+ if (period) {
+ s->formatter->dump_string("period", period.get_period().get_id());
+ s->formatter->dump_unsigned("realm_epoch", period.get_epoch());
+ }
s->formatter->close_section();
flusher.flush();
}
class RGWOp_MDLog_Info : public RGWRESTOp {
unsigned num_objects;
+ RGWPeriodHistory::Cursor period;
public:
RGWOp_MDLog_Info() : num_objects(0) {}
~RGWOp_MDLog_Info() {}
void rgw_mdlog_info::decode_json(JSONObj *obj) {
JSONDecoder::decode_json("num_objects", num_shards, obj);
+ JSONDecoder::decode_json("period", period, obj);
+ JSONDecoder::decode_json("realm_epoch", realm_epoch, obj);
}
struct rgw_mdlog_entry {
return 0;
}
- auto num_shards = sync_status.sync_info.num_shards;
- if (!num_shards) {
+ auto& sync_info = sync_status.sync_info;
+ if (!sync_info.num_shards) {
rgw_mdlog_info mdlog_info;
int r = read_log_info(&mdlog_info);
if (r < 0) {
lderr(store->ctx()) << "ERROR: fail to fetch master log info (r=" << r << ")" << dendl;
return r;
}
- num_shards = mdlog_info.num_shards;
+ sync_info.num_shards = mdlog_info.num_shards;
+ sync_info.period = mdlog_info.period;
+ sync_info.realm_epoch = mdlog_info.realm_epoch;
}
RGWObjectCtx obj_ctx(store, NULL);
- return run(new RGWInitSyncStatusCoroutine(&sync_env, obj_ctx,
- sync_status.sync_info));
+ return run(new RGWInitSyncStatusCoroutine(&sync_env, obj_ctx, sync_info));
}
int RGWRemoteMetaLog::store_sync_info()
RGWObjectCtx obj_ctx(store, NULL);
+ // get shard count and oldest log period from master
rgw_mdlog_info mdlog_info;
int r = read_log_info(&mdlog_info);
if (r < 0) {
return r;
}
+ if (!mdlog_info.period.empty() && sync_status.sync_info.period.empty()) {
+ // restart sync if the remote has a period but our status does not
+ sync_status.sync_info.state = rgw_meta_sync_info::StateInit;
+ }
+
if (sync_status.sync_info.state == rgw_meta_sync_info::StateInit) {
ldout(store->ctx(), 20) << __func__ << "(): init" << dendl;
+ sync_status.sync_info.num_shards = mdlog_info.num_shards;
+ // use the period/epoch from the master's oldest log
+ sync_status.sync_info.period = mdlog_info.period;
+ sync_status.sync_info.realm_epoch = mdlog_info.realm_epoch;
r = run(new RGWInitSyncStatusCoroutine(&sync_env, obj_ctx,
sync_status.sync_info));
if (r == -EBUSY) {
struct rgw_mdlog_info {
uint32_t num_shards;
+ std::string period; //< period id of the master's oldest metadata log
+ epoch_t realm_epoch; //< realm epoch of oldest metadata log
- rgw_mdlog_info() : num_shards(0) {}
+ rgw_mdlog_info() : num_shards(0), realm_epoch(0) {}
void decode_json(JSONObj *obj);
};