From 8451effcac07289243c64730f0a0ba9d780f0149 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 12 Aug 2015 17:47:50 -0700 Subject: [PATCH] rgw: fetch all metadata entries Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_admin.cc | 19 ++++++++ src/rgw/rgw_sync.cc | 102 +++++++++++++++++++++++++++++++++++++++++-- src/rgw/rgw_sync.h | 3 ++ 3 files changed, 120 insertions(+), 4 deletions(-) diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index fefee44d070a8..8590954cf2ef2 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -293,6 +293,7 @@ enum { OPT_MDLOG_FETCH, OPT_MDLOG_SYNC_STATUS, OPT_MDLOG_SYNC_INIT, + OPT_MDLOG_SYNC_RUN, OPT_BILOG_LIST, OPT_BILOG_TRIM, OPT_DATALOG_LIST, @@ -570,6 +571,8 @@ static int get_cmd(const char *cmd, const char *prev_cmd, const char *prev_prev_ return OPT_MDLOG_SYNC_STATUS; if (strcmp(cmd, "init") == 0) return OPT_MDLOG_SYNC_INIT; + if (strcmp(cmd, "run") == 0) + return OPT_MDLOG_SYNC_RUN; } else if (strcmp(prev_cmd, "bilog") == 0) { if (strcmp(cmd, "list") == 0) return OPT_BILOG_LIST; @@ -3361,6 +3364,22 @@ next: } } + + if (opt_cmd == OPT_MDLOG_SYNC_RUN) { + RGWMetaSyncStatusManager sync(store); + + int ret = sync.init(); + if (ret < 0) { + cerr << "ERROR: sync.init() returned ret=" << ret << std::endl; + return -ret; + } + + ret = sync.run(); + if (ret < 0) { + cerr << "ERROR: sync.run() returned ret=" << ret << std::endl; + return -ret; + } + } if (opt_cmd == OPT_BILOG_LIST) { if (bucket_name.empty()) { cerr << "ERROR: bucket not specified" << std::endl; diff --git a/src/rgw/rgw_sync.cc b/src/rgw/rgw_sync.cc index 6530f64dd876a..bd1ad294fec87 100644 --- a/src/rgw/rgw_sync.cc +++ b/src/rgw/rgw_sync.cc @@ -663,6 +663,11 @@ public: call(new RGWSimpleRadosWriteCR(async_rados, store, store->get_zone_params().log_pool, mdlog_sync_status_oid, status)); } + yield { /* take lock again, we just recreated the object */ + uint32_t lock_duration = 30; + call(new RGWSimpleRadosLockCR(async_rados, store, store->get_zone_params().log_pool, mdlog_sync_status_oid, + lock_name, cookie, lock_duration)); + } yield { for (int i = 0; i < (int)status.num_shards; i++) { rgw_meta_sync_marker marker; @@ -670,10 +675,10 @@ public: RGWMetaSyncStatusManager::shard_obj_name(i), marker)); } } - /* - * no need to unlock, we've just completely overwritten the meta object, and overridden its - * lock - */ + yield { /* unlock */ + call(new RGWSimpleRadosUnlockCR(async_rados, store, store->get_zone_params().log_pool, mdlog_sync_status_oid, + lock_name, cookie)); + } yield { int ret = complete_spawned(); if (ret < 0) { @@ -727,6 +732,89 @@ int RGWReadSyncStatusCoroutine::finish() return complete_spawned(); } +class RGWFetchAllMetaCR : public RGWCoroutine { + RGWRados *store; + RGWHTTPManager *http_manager; + + int max_entries; + + RGWRESTReadResource *http_op; + + RGWAioCompletionNotifier *md_op_notifier; + + int req_ret; + + list sections; + list::iterator sections_iter; + list result; + +public: + RGWFetchAllMetaCR(RGWRados *_store, RGWHTTPManager *_mgr) : RGWCoroutine(_store->ctx()), store(_store), + http_manager(_mgr), + http_op(NULL), md_op_notifier(NULL), + req_ret(0) {} + + int operate() { + RGWRESTConn *conn = store->rest_master_conn; + + reenter(this) { + yield { + http_op = new RGWRESTReadResource(conn, "/admin/metadata", NULL, NULL, http_manager); + + http_op->set_user_info((void *)env->stack); + + int ret = http_op->aio_read(); + if (ret < 0) { + ldout(store->ctx(), 0) << "ERROR: failed to fetch metadata" << dendl; + log_error() << "failed to send http operation: " << http_op->to_str() << " ret=" << ret << std::endl; + http_op->put(); + return ret; + } + return block(0); + } + yield { + int ret = http_op->wait(§ions); + http_op->put(); + if (ret < 0) { + error_stream << "http operation failed: " << http_op->to_str() << " status=" << http_op->get_http_status() << std::endl; + ldout(store->ctx(), 0) << "ERROR: failed to wait for op, ret=" << ret << dendl; + return set_state(RGWCoroutine_Error); + } + sections_iter = sections.begin(); + } + for (; sections_iter != sections.end(); ++sections_iter) { + yield { + string entrypoint = string("/admin/metadata/") + *sections_iter; + http_op = new RGWRESTReadResource(conn, entrypoint, NULL, NULL, http_manager); + http_op->set_user_info((void *)env->stack); + int ret = http_op->aio_read(); + if (ret < 0) { + ldout(store->ctx(), 0) << "ERROR: failed to fetch metadata" << dendl; + log_error() << "failed to send http operation: " << http_op->to_str() << " ret=" << ret << std::endl; + http_op->put(); + return ret; + } + return block(0); + } + yield { + int ret = http_op->wait(&result); + http_op->put(); + if (ret < 0) { + error_stream << "http operation failed: " << http_op->to_str() << " status=" << http_op->get_http_status() << std::endl; + ldout(store->ctx(), 0) << "ERROR: failed to wait for op, ret=" << ret << dendl; + return set_state(RGWCoroutine_Error); + } + for (list::iterator iter = result.begin(); iter != result.end(); ++iter) { + ldout(store->ctx(), 20) << "list metadata: section=" << *sections_iter << " key=" << *iter << dendl; + } + } + } + yield return set_state(RGWCoroutine_Done); + } + } + return 0; +}; + class RGWCloneMetaLogCoroutine : public RGWCoroutine { RGWRados *store; RGWMetadataLog *mdlog; @@ -812,6 +900,12 @@ int RGWRemoteMetaLog::init_sync_status(int num_shards) return run(new RGWInitSyncStatusCoroutine(async_rados, store, obj_ctx, num_shards)); } +int RGWRemoteMetaLog::run_sync(rgw_meta_sync_status& sync_status) +{ + RGWObjectCtx obj_ctx(store, NULL); + return run(new RGWFetchAllMetaCR(store, &http_manager)); +} + int RGWCloneMetaLogCoroutine::operate() { reenter(this) { diff --git a/src/rgw/rgw_sync.h b/src/rgw/rgw_sync.h index ba8ab5e02d76d..6b5c2cd1eccff 100644 --- a/src/rgw/rgw_sync.h +++ b/src/rgw/rgw_sync.h @@ -144,6 +144,7 @@ public: int fetch(int num_shards, vector& clone_markers); int read_sync_status(rgw_meta_sync_status *sync_status); int init_sync_status(int num_shards); + int run_sync(rgw_meta_sync_status& sync_status); }; class RGWMetaSyncStatusManager { @@ -193,6 +194,8 @@ public: int init_sync_status() { return master_log.init_sync_status(num_shards); } int fetch() { return master_log.fetch(num_shards, clone_markers); } int clone_shards() { return master_log.clone_shards(num_shards, clone_markers); } + + int run() { return master_log.run_sync(sync_status); } }; #endif -- 2.39.5