diff options
author | Casey Bodley <cbodley@redhat.com> | 2015-12-17 16:29:00 +0100 |
---|---|---|
committer | Yehuda Sadeh <yehuda@redhat.com> | 2016-02-12 01:13:52 +0100 |
commit | d89d22474e815780ebc728ba529ecbae548ac959 (patch) | |
tree | 2fc74b386d6290dedc77388fdcd47c776308276f | |
parent | rgw: add exclusive param to RGWPeriod::set_latest_epoch (diff) | |
download | ceph-d89d22474e815780ebc728ba529ecbae548ac959.tar.xz ceph-d89d22474e815780ebc728ba529ecbae548ac959.zip |
rgw: add RGWPeriodPuller for RGWPeriodHistory
Signed-off-by: Casey Bodley <cbodley@redhat.com>
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/rgw/Makefile.am | 2 | ||||
-rw-r--r-- | src/rgw/rgw_period_puller.cc | 97 | ||||
-rw-r--r-- | src/rgw/rgw_period_puller.h | 20 |
4 files changed, 120 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8c63c1c8468..f885ceeba8d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1171,6 +1171,7 @@ if(${WITH_RADOSGW}) rgw/rgw_data_sync.cc rgw/rgw_dencoder.cc rgw/rgw_period_history.cc + rgw/rgw_period_puller.cc rgw/rgw_period_pusher.cc rgw/rgw_realm_reloader.cc rgw/rgw_realm_watcher.cc diff --git a/src/rgw/Makefile.am b/src/rgw/Makefile.am index f091a79a362..808a31773b6 100644 --- a/src/rgw/Makefile.am +++ b/src/rgw/Makefile.am @@ -60,6 +60,7 @@ librgw_la_SOURCES = \ rgw/rgw_quota.cc \ rgw/rgw_dencoder.cc \ rgw/rgw_period_history.cc \ + rgw/rgw_period_puller.cc \ rgw/rgw_period_pusher.cc \ rgw/rgw_realm_reloader.cc \ rgw/rgw_realm_watcher.cc \ @@ -206,6 +207,7 @@ noinst_HEADERS += \ rgw/rgw_keystone.h \ rgw/rgw_period_history.h \ rgw/rgw_period_pusher.h \ + rgw/rgw_period_puller.h \ rgw/rgw_realm_reloader.h \ rgw/rgw_realm_watcher.h \ rgw/rgw_civetweb.h \ diff --git a/src/rgw/rgw_period_puller.cc b/src/rgw/rgw_period_puller.cc new file mode 100644 index 00000000000..a35591ccb92 --- /dev/null +++ b/src/rgw/rgw_period_puller.cc @@ -0,0 +1,97 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "rgw_rados.h" +#include "rgw_rest_conn.h" +#include "common/ceph_json.h" +#include "common/errno.h" + +#define dout_subsys ceph_subsys_rgw + +#undef dout_prefix +#define dout_prefix (*_dout << "rgw period puller: ") + +namespace { + +// pull the given period over the connection +int pull_period(RGWRESTConn* conn, const std::string& period_id, + const std::string& realm_id, RGWPeriod& period) +{ + rgw_user user; + RGWEnv env; + req_info info(conn->get_ctx(), &env); + info.method = "GET"; + info.request_uri = "/admin/realm/period"; + + auto& params = info.args.get_params(); + params["realm_id"] = realm_id; + params["period_id"] = period_id; + + bufferlist data; +#define MAX_REST_RESPONSE (128 * 1024) + int r = conn->forward(user, info, nullptr, MAX_REST_RESPONSE, nullptr, &data); + if (r < 0) { + return r; + } + + JSONParser parser; + r = parser.parse(data.c_str(), data.length()); + if (r < 0) { + lderr(conn->get_ctx()) << "request failed: " << cpp_strerror(-r) << dendl; + return r; + } + + try { + decode_json_obj(period, &parser); + } catch (JSONDecoder::err& e) { + lderr(conn->get_ctx()) << "failed to decode JSON input: " + << e.message << dendl; + return -EINVAL; + } + return 0; +} + +} // anonymous namespace + +int RGWPeriodPuller::pull(const std::string& period_id, RGWPeriod& period) +{ + // try to read the period from rados + period.set_id(period_id); + int r = period.init(store->ctx(), store); + if (r < 0) { + ldout(store->ctx(), 14) << "pulling period " << period_id + << " from master" << dendl; + // request the period from the master zone + r = pull_period(store->rest_master_conn, period_id, + store->realm.get_id(), period); + if (r < 0) { + lderr(store->ctx()) << "failed to pull period " << period_id << dendl; + return r; + } + // write the period to rados + r = period.store_info(true); + if (r == -EEXIST) { + r = 0; + } else if (r < 0) { + lderr(store->ctx()) << "failed to store period " << period_id << dendl; + return r; + } + // XXX: if this is a newer epoch, we should overwrite the existing + // latest_epoch. but there's no way to do that atomically + bool exclusive = true; + r = period.set_latest_epoch(period.get_epoch(), exclusive); + if (r == -EEXIST) { + r = 0; + } else if (r < 0) { + lderr(store->ctx()) << "failed to update latest_epoch for period " + << period_id << dendl; + return r; + } + ldout(store->ctx(), 14) << "period " << period_id + << " pulled and written to local storage" << dendl; + } else { + ldout(store->ctx(), 14) << "found period " << period_id + << " in local storage" << dendl; + } + return 0; +} diff --git a/src/rgw/rgw_period_puller.h b/src/rgw/rgw_period_puller.h new file mode 100644 index 00000000000..1cb8998b2d5 --- /dev/null +++ b/src/rgw/rgw_period_puller.h @@ -0,0 +1,20 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_RGW_PERIOD_PULLER_H +#define CEPH_RGW_PERIOD_PULLER_H + +#include "rgw_period_history.h" + +class RGWRados; +class RGWPeriod; + +class RGWPeriodPuller : public RGWPeriodHistory::Puller { + RGWRados *const store; + public: + RGWPeriodPuller(RGWRados* store) : store(store) {} + + int pull(const std::string& period_id, RGWPeriod& period) override; +}; + +#endif // CEPH_RGW_PERIOD_PULLER_H |