From 6b6625e28c77ab5236fa275d78f082ee1635299c Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Thu, 18 Feb 2016 11:20:34 -0500 Subject: [PATCH] rgw: get period history cursor when starting sync Signed-off-by: Casey Bodley --- src/rgw/rgw_period_history.h | 2 +- src/rgw/rgw_sync.cc | 50 +++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/rgw/rgw_period_history.h b/src/rgw/rgw_period_history.h index 78049d03782..ca380251338 100644 --- a/src/rgw/rgw_period_history.h +++ b/src/rgw/rgw_period_history.h @@ -69,6 +69,7 @@ class RGWPeriodHistory final { class Cursor final { public: Cursor() = default; + explicit Cursor(int error) : error(error) {} int get_error() const { return error; } @@ -88,7 +89,6 @@ class RGWPeriodHistory final { // private constructors for RGWPeriodHistory friend class RGWPeriodHistory; - explicit Cursor(int error) : error(error) {} Cursor(Set::const_iterator history, std::mutex* mutex, epoch_t epoch) : history(history), mutex(mutex), epoch(epoch) {} diff --git a/src/rgw/rgw_sync.cc b/src/rgw/rgw_sync.cc index 4b491e2fd5c..4a230d09a00 100644 --- a/src/rgw/rgw_sync.cc +++ b/src/rgw/rgw_sync.cc @@ -1563,6 +1563,47 @@ int RGWRemoteMetaLog::store_sync_info() sync_env.status_oid(), sync_status.sync_info)); } +// return a cursor to the period at our sync position +static RGWPeriodHistory::Cursor get_period_at(RGWRados* store, + const rgw_meta_sync_info& info) +{ + if (info.period.empty()) { + // return an empty cursor with error=0 + return RGWPeriodHistory::Cursor{}; + } + + // look for an existing period in our history + auto cursor = store->period_history->lookup(info.realm_epoch); + if (cursor) { + // verify that the period ids match + auto& existing = cursor.get_period().get_id(); + if (existing != info.period) { + lderr(store->ctx()) << "ERROR: sync status period=" << info.period + << " does not match period=" << existing + << " in history at realm epoch=" << info.realm_epoch << dendl; + return RGWPeriodHistory::Cursor{-EEXIST}; + } + return cursor; + } + + // read the period from rados + RGWPeriod period(info.period); + int r = period.init(store->ctx(), store, store->realm.get_id()); + if (r < 0) { + lderr(store->ctx()) << "ERROR: failed to read period id " + << info.period << ": " << cpp_strerror(r) << dendl; + return RGWPeriodHistory::Cursor{r}; + } + // attach the period to our history + cursor = store->period_history->attach(std::move(period)); + if (!cursor) { + r = cursor.get_error(); + lderr(store->ctx()) << "ERROR: failed to read period history back to " + << info.period << ": " << cpp_strerror(r) << dendl; + } + return cursor; +} + int RGWRemoteMetaLog::run_sync() { if (store->is_meta_master()) { @@ -1617,6 +1658,7 @@ int RGWRemoteMetaLog::run_sync() return r; } + RGWPeriodHistory::Cursor cursor; do { r = run(new RGWReadSyncStatusCoroutine(&sync_env, obj_ctx, &sync_status)); if (r < 0 && r != -ENOENT) { @@ -1647,7 +1689,13 @@ int RGWRemoteMetaLog::run_sync() /* fall through */ case rgw_meta_sync_info::StateSync: ldout(store->ctx(), 20) << __func__ << "(): sync" << dendl; - meta_sync_cr = new RGWMetaSyncCR(&sync_env, sync_status); + // find our position in the period history (if any) + cursor = get_period_at(store, sync_status.sync_info); + r = cursor.get_error(); + if (r < 0) { + return r; + } + meta_sync_cr = new RGWMetaSyncCR(&sync_env, cursor, sync_status); r = run(meta_sync_cr); if (r < 0) { ldout(store->ctx(), 0) << "ERROR: failed to fetch all metadata keys" << dendl; -- 2.39.5