]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add RGWPeriodPuller for RGWPeriodHistory
authorCasey Bodley <cbodley@redhat.com>
Thu, 17 Dec 2015 15:29:00 +0000 (10:29 -0500)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 12 Feb 2016 00:13:52 +0000 (16:13 -0800)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/CMakeLists.txt
src/rgw/Makefile.am
src/rgw/rgw_period_puller.cc [new file with mode: 0644]
src/rgw/rgw_period_puller.h [new file with mode: 0644]

index 8c63c1c8468c1991cce06b0b62acdddcf637b6df..f885ceeba8dbb1b684a7dcd3d49b1f603199ee8b 100644 (file)
@@ -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
index f091a79a362d7bf4723deedca3d5c8ebf874e02f..808a31773b61c7252d47d6697c8325be72f71f67 100644 (file)
@@ -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 (file)
index 0000000..a35591c
--- /dev/null
@@ -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 (file)
index 0000000..1cb8998
--- /dev/null
@@ -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