From c4c58ccce4ba11335b6be4bb0b870cfe3c2c30c5 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Mon, 3 Feb 2020 15:59:58 -0500 Subject: [PATCH] rgw: use new Stopped state for special handling of 'bucket sync disable' some sync modules like pubsub can disable full sync, and only run incremental sync. without full sync, 'bucket sync disable/enable' will continuously restart incremental sync from the beginning of the bilog this adds a new Stopped state for 'bucket sync disable', which leaves the incremental marker position where it is (just past the SYNCSTOP entry). this means that when sync is reenabled, it can continue sync from where it left off Fixes: https://tracker.ceph.com/issues/43768 Signed-off-by: Casey Bodley --- src/rgw/rgw_data_sync.cc | 25 ++++++++++++++++++++----- src/rgw/rgw_data_sync.h | 1 + src/rgw/rgw_json_enc.cc | 3 +++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/rgw/rgw_data_sync.cc b/src/rgw/rgw_data_sync.cc index dddb0c6cecbda..67cbd7aa2b1b0 100644 --- a/src/rgw/rgw_data_sync.cc +++ b/src/rgw/rgw_data_sync.cc @@ -2768,21 +2768,35 @@ public: yield { auto store = sync_env->store; rgw_raw_obj obj(sync_env->svc->zone->get_zone_params().log_pool, sync_status_oid); + const bool stopped = status.state == rgw_bucket_shard_sync_info::StateStopped; + bool write_status = false; if (info.syncstopped) { - call(new RGWRadosRemoveCR(store, obj)); + if (stopped && !sync_env->sync_module->should_full_sync()) { + // preserve our current incremental marker position + write_status = true; + } } else { // whether or not to do full sync, incremental sync will follow anyway if (sync_env->sync_module->should_full_sync()) { status.state = rgw_bucket_shard_sync_info::StateFullSync; status.inc_marker.position = info.max_marker; } else { + // clear the marker position unless we're resuming from SYNCSTOP + if (!stopped) { + status.inc_marker.position = ""; + } status.state = rgw_bucket_shard_sync_info::StateIncrementalSync; - status.inc_marker.position = ""; } + write_status = true; + } + + if (write_status) { map attrs; status.encode_all_attrs(attrs); call(new RGWSimpleRadosWriteAttrsCR(sync_env->async_rados, sync_env->svc->sysobj, obj, attrs)); + } else { + call(new RGWRadosRemoveCR(store, obj)); } } if (info.syncstopped) { @@ -4085,11 +4099,11 @@ int RGWBucketShardIncrementalSyncCR::operate() tn->unset_flag(RGW_SNS_FLAG_ACTIVE); if (syncstopped) { - // transition back to StateInit in RGWRunBucketSyncCoroutine. if sync is + // transition to StateStopped in RGWRunBucketSyncCoroutine. if sync is // still disabled, we'll delete the sync status object. otherwise we'll // restart full sync to catch any changes that happened while sync was // disabled - sync_info.state = rgw_bucket_shard_sync_info::StateInit; + sync_info.state = rgw_bucket_shard_sync_info::StateStopped; return set_cr_done(); } @@ -4695,7 +4709,8 @@ int RGWRunBucketSyncCoroutine::operate() sync_pipe.info = sync_pair; do { - if (sync_status.state == rgw_bucket_shard_sync_info::StateInit) { + if (sync_status.state == rgw_bucket_shard_sync_info::StateInit || + sync_status.state == rgw_bucket_shard_sync_info::StateStopped) { yield call(new RGWInitBucketShardSyncStatusCoroutine(sc, sync_pair, sync_status)); if (retcode == -ENOENT) { tn->log(0, "bucket sync disabled"); diff --git a/src/rgw/rgw_data_sync.h b/src/rgw/rgw_data_sync.h index 29267ca40c45c..9a2174bed5c55 100644 --- a/src/rgw/rgw_data_sync.h +++ b/src/rgw/rgw_data_sync.h @@ -505,6 +505,7 @@ struct rgw_bucket_shard_sync_info { StateInit = 0, StateFullSync = 1, StateIncrementalSync = 2, + StateStopped = 3, }; uint16_t state; diff --git a/src/rgw/rgw_json_enc.cc b/src/rgw/rgw_json_enc.cc index f525c39893e99..1864f6cb63d7b 100644 --- a/src/rgw/rgw_json_enc.cc +++ b/src/rgw/rgw_json_enc.cc @@ -1803,6 +1803,9 @@ void rgw_bucket_shard_sync_info::dump(Formatter *f) const case StateIncrementalSync: s = "incremental-sync"; break; + case StateStopped: + s = "stopped"; + break; default: s = "unknown"; break; -- 2.39.5