From 1c9079abc0384f20bbe1e3cc881f5251e4797cb8 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 23 Jul 2015 23:06:28 -0700 Subject: [PATCH] rgw: read mdlog marker Use our local marker as a starting point for fetching the mater mdlog. Signed-off-by: Yehuda Sadeh --- src/rgw/rgw_metadata.cc | 64 +++++++++++++++++++++++++++++++++++++++++ src/rgw/rgw_metadata.h | 3 ++ src/rgw/rgw_rados.cc | 19 ++++++++++++ src/rgw/rgw_rados.h | 1 + src/rgw/rgw_sync.cc | 47 +++++++++++++++++++++++++----- src/rgw/rgw_sync.h | 1 + 6 files changed, 128 insertions(+), 7 deletions(-) diff --git a/src/rgw/rgw_metadata.cc b/src/rgw/rgw_metadata.cc index b4cbba750d7ad..9270d011066de 100644 --- a/src/rgw/rgw_metadata.cc +++ b/src/rgw/rgw_metadata.cc @@ -3,6 +3,7 @@ #include "common/ceph_json.h" #include "rgw_metadata.h" +#include "rgw_http_client.h" #include "cls/version/cls_version_types.h" #include "rgw_rados.h" @@ -168,6 +169,69 @@ int RGWMetadataLog::get_info(int shard_id, RGWMetadataLogInfo *info) return 0; } +static void _mdlog_info_completion(librados::completion_t cb, void *arg); + +class RGWMetadataLogInfoCompletion : public RefCountedObject { + RGWMetadataLogInfo *pinfo; + RGWCompletionManager *completion_manager; + void *user_info; + int *pret; + cls_log_header header; + librados::IoCtx io_ctx; + librados::AioCompletion *completion; + +public: + RGWMetadataLogInfoCompletion(RGWMetadataLogInfo *_pinfo, RGWCompletionManager *_cm, void *_uinfo, int *_pret) : + pinfo(_pinfo), completion_manager(_cm), user_info(_uinfo), pret(_pret) { + completion = librados::Rados::aio_create_completion((void *)this, _mdlog_info_completion, NULL); + } + + ~RGWMetadataLogInfoCompletion() { + completion->release(); + } + + void finish(librados::completion_t cb) { + *pret = completion->get_return_value(); + if (*pret >= 0) { + pinfo->marker = header.max_marker; + pinfo->last_update = header.max_time; + } + completion_manager->complete(user_info); + put(); + } + + librados::IoCtx& get_io_ctx() { return io_ctx; } + + cls_log_header *get_header() { + return &header; + } + + librados::AioCompletion *get_completion() { + return completion; + } +}; + +static void _mdlog_info_completion(librados::completion_t cb, void *arg) +{ + RGWMetadataLogInfoCompletion *infoc = (RGWMetadataLogInfoCompletion *)arg; + infoc->finish(cb); +} + +int RGWMetadataLog::get_info_async(int shard_id, RGWMetadataLogInfo *info, RGWCompletionManager *completion_manager, void *user_info, int *pret) +{ + string oid; + get_shard_oid(shard_id, oid); + + RGWMetadataLogInfoCompletion *req_completion = new RGWMetadataLogInfoCompletion(info, completion_manager, user_info, pret); + + int ret = store->time_log_info_async(req_completion->get_io_ctx(), oid, req_completion->get_header(), req_completion->get_completion()); + if (ret < 0) { + return ret; + } + + return 0; +} + int RGWMetadataLog::trim(int shard_id, const utime_t& from_time, const utime_t& end_time, const string& start_marker, const string& end_marker) { diff --git a/src/rgw/rgw_metadata.h b/src/rgw/rgw_metadata.h index 981f43782c52a..ba843c75cc694 100644 --- a/src/rgw/rgw_metadata.h +++ b/src/rgw/rgw_metadata.h @@ -135,6 +135,8 @@ struct RGWMetadataLogInfo { void decode_json(JSONObj *obj); }; +class RGWCompletionManager; + class RGWMetadataLog { CephContext *cct; RGWRados *store; @@ -175,6 +177,7 @@ public: int trim(int shard_id, const utime_t& from_time, const utime_t& end_time, const string& start_marker, const string& end_marker); int get_info(int shard_id, RGWMetadataLogInfo *info); + int get_info_async(int shard_id, RGWMetadataLogInfo *info, RGWCompletionManager *completion_manager, void *user_info, int *pret); int lock_exclusive(int shard_id, utime_t& duration, string&zone_id, string& owner_id); int unlock(int shard_id, string& zone_id, string& owner_id); }; diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index 2c598d0ef7c6c..53f44c78a5c0d 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -2370,6 +2370,25 @@ int RGWRados::time_log_info(const string& oid, cls_log_header *header) return 0; } +int RGWRados::time_log_info_async(librados::IoCtx& io_ctx, const string& oid, cls_log_header *header, librados::AioCompletion *completion) +{ + const char *log_pool = zone.log_pool.name.c_str(); + librados::Rados *rad = get_rados_handle(); + int r = rad->ioctx_create(log_pool, io_ctx); + if (r < 0) + return r; + + librados::ObjectReadOperation op; + + cls_log_info(op, header); + + int ret = io_ctx.aio_operate(oid, completion, &op, NULL); + if (ret < 0) + return ret; + + return 0; +} + int RGWRados::time_log_trim(const string& oid, const utime_t& start_time, const utime_t& end_time, const string& from_marker, const string& to_marker) { diff --git a/src/rgw/rgw_rados.h b/src/rgw/rgw_rados.h index 56cfef29f4c9e..832fa11d9ab52 100644 --- a/src/rgw/rgw_rados.h +++ b/src/rgw/rgw_rados.h @@ -2175,6 +2175,7 @@ public: int max_entries, list& entries, const string& marker, string *out_marker, bool *truncated); int time_log_info(const string& oid, cls_log_header *header); + int time_log_info_async(librados::IoCtx& io_ctx, const string& oid, cls_log_header *header, librados::AioCompletion *completion); int time_log_trim(const string& oid, const utime_t& start_time, const utime_t& end_time, const string& from_marker, const string& to_marker); diff --git a/src/rgw/rgw_sync.cc b/src/rgw/rgw_sync.cc index 3b2bea264705e..1d82a9daaa08c 100644 --- a/src/rgw/rgw_sync.cc +++ b/src/rgw/rgw_sync.cc @@ -182,6 +182,7 @@ static void _aio_completion_notifier_cb(librados::completion_t cb, void *arg) class RGWCloneMetaLogOp : public RGWAsyncOp { RGWRados *store; + RGWMetadataLog *mdlog; RGWHTTPManager *http_manager; int shard_id; @@ -194,17 +195,20 @@ class RGWCloneMetaLogOp : public RGWAsyncOp { AioCompletionNotifier *md_op_notifier; + int req_ret; + RGWMetadataLogInfo shard_info; rgw_mdlog_shard_data data; enum State { Init = 0, - ReadShardStatus = 1, - SendRESTRequest = 2, - ReceiveRESTResponse = 3, - StoreMDLogEntries = 4, - StoreMDLogEntriesComplete = 5, - Done = 6, - Error = 7, + ReadShardStatus = 1, + ReadShardStatusComplete = 2, + SendRESTRequest = 3, + ReceiveRESTResponse = 4, + StoreMDLogEntries = 5, + StoreMDLogEntriesComplete = 6, + Done = 100, + Error = 200, } state; int set_state(State s, int ret = 0) { @@ -214,15 +218,18 @@ class RGWCloneMetaLogOp : public RGWAsyncOp { public: RGWCloneMetaLogOp(RGWRados *_store, RGWHTTPManager *_mgr, RGWAsyncOpsManager *_ops_mgr, int _id, const string& _marker) : RGWAsyncOp(_ops_mgr), store(_store), + mdlog(store->meta_mgr->get_log()), http_manager(_mgr), shard_id(_id), marker(_marker), truncated(false), max_entries(CLONE_MAX_ENTRIES), http_op(NULL), md_op_notifier(NULL), + req_ret(0), state(RGWCloneMetaLogOp::Init) {} int operate(); int state_init(); int state_read_shard_status(); + int state_read_shard_status_complete(); int state_send_rest_request(); int state_receive_rest_response(); int state_store_mdlog_entries(); @@ -313,6 +320,12 @@ int RGWCloneMetaLogOp::operate() case Init: ldout(store->ctx(), 20) << __func__ << ": shard_id=" << shard_id << ": init request" << dendl; return state_init(); + case ReadShardStatus: + ldout(store->ctx(), 20) << __func__ << ": shard_id=" << shard_id << ": reading shard status" << dendl; + return state_read_shard_status(); + case ReadShardStatusComplete: + ldout(store->ctx(), 20) << __func__ << ": shard_id=" << shard_id << ": reading shard status complete" << dendl; + return state_read_shard_status_complete(); case SendRESTRequest: ldout(store->ctx(), 20) << __func__ << ": shard_id=" << shard_id << ": sending rest request" << dendl; return state_send_rest_request(); @@ -340,6 +353,26 @@ int RGWCloneMetaLogOp::state_init() { data = rgw_mdlog_shard_data(); + return set_state(ReadShardStatus); +} + +int RGWCloneMetaLogOp::state_read_shard_status() +{ + int ret = mdlog->get_info_async(shard_id, &shard_info, ops_mgr->get_completion_mgr(), (void *)this, &req_ret); + if (ret < 0) { + ldout(store->ctx(), 0) << "ERROR: mdlog->get_info_async() returned ret=" << ret << dendl; + return set_state(Error, ret); + } + + return yield(set_state(ReadShardStatusComplete)); +} + +int RGWCloneMetaLogOp::state_read_shard_status_complete() +{ + ldout(store->ctx(), 20) << "shard_id=" << shard_id << " marker=" << shard_info.marker << " last_update=" << shard_info.last_update << dendl; + + marker = shard_info.marker; + return set_state(SendRESTRequest); } diff --git a/src/rgw/rgw_sync.h b/src/rgw/rgw_sync.h index 084ec85062e16..428f5718a5443 100644 --- a/src/rgw/rgw_sync.h +++ b/src/rgw/rgw_sync.h @@ -74,6 +74,7 @@ public: virtual void report_error(RGWAsyncOp *op); AioCompletionNotifier *create_completion_notifier(RGWAsyncOp *op); + RGWCompletionManager *get_completion_mgr() { return &completion_mgr; } }; class RGWRemoteMetaLog : public RGWAsyncOpsManager { -- 2.39.5