summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCasey Bodley <cbodley@redhat.com>2015-12-17 16:29:00 +0100
committerYehuda Sadeh <yehuda@redhat.com>2016-02-12 01:13:52 +0100
commitd89d22474e815780ebc728ba529ecbae548ac959 (patch)
tree2fc74b386d6290dedc77388fdcd47c776308276f
parentrgw: add exclusive param to RGWPeriod::set_latest_epoch (diff)
downloadceph-d89d22474e815780ebc728ba529ecbae548ac959.tar.xz
ceph-d89d22474e815780ebc728ba529ecbae548ac959.zip
rgw: add RGWPeriodPuller for RGWPeriodHistory
Signed-off-by: Casey Bodley <cbodley@redhat.com>
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/rgw/Makefile.am2
-rw-r--r--src/rgw/rgw_period_puller.cc97
-rw-r--r--src/rgw/rgw_period_puller.h20
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