]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: RGWRealmWatcher supports multiple watch types
authorCasey Bodley <cbodley@redhat.com>
Tue, 6 Oct 2015 21:12:14 +0000 (17:12 -0400)
committerYehuda Sadeh <yehuda@redhat.com>
Fri, 12 Feb 2016 00:13:35 +0000 (16:13 -0800)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/rgw/rgw_admin.cc
src/rgw/rgw_main.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h
src/rgw/rgw_realm_reloader.cc
src/rgw/rgw_realm_reloader.h
src/rgw/rgw_realm_watcher.cc
src/rgw/rgw_realm_watcher.h

index 85d1532eb5bbc29ba34e9c5dd76aedbdacd23b93..a2a81f4a707589d95633ce763cd3ca8a8b15d1c7 100644 (file)
@@ -34,6 +34,7 @@
 #include "rgw_sync.h"
 #include "rgw_data_sync.h"
 #include "rgw_rest_conn.h"
+#include "rgw_realm_watcher.h"
 
 using namespace std;
 
index 8dc5680ffbd890f0c9567b32df4f6bc3cd81a110..8718ed48da0a3da8c4b04bcb643381b82e3d2608 100644 (file)
@@ -1344,7 +1344,7 @@ int main(int argc, const char **argv)
   RGWRealmReloader reloader(store, &pauser);
 
   RGWRealmWatcher realm_watcher(g_ceph_context, store->realm);
-  realm_watcher.set_watcher(&reloader);
+  realm_watcher.add_watcher(RGWRealmNotify::Reload, reloader);
 
   wait_shutdown();
 
index c997e892a4ae33af70042fb83679028076533e44..bc379da2f20d970ce82e93d2d0e6460d35942768 100644 (file)
@@ -57,6 +57,7 @@ using namespace librados;
 #include "rgw_object_expirer_core.h"
 #include "rgw_sync.h"
 #include "rgw_data_sync.h"
+#include "rgw_realm_watcher.h"
 
 #define dout_subsys ceph_subsys_rgw
 
@@ -772,7 +773,7 @@ string RGWRealm::get_control_oid()
   return get_info_oid_prefix() + id + ".control";
 }
 
-int RGWRealm::notify_zone()
+int RGWRealm::notify_zone(bufferlist& bl)
 {
   // open a context on the realm's pool
   auto pool = get_pool_name(cct);
@@ -783,7 +784,6 @@ int RGWRealm::notify_zone()
     return r;
   }
   // send a notify on the realm object
-  bufferlist bl;
   r = ctx.notify2(get_control_oid(), bl, 0, nullptr);
   if (r < 0) {
     lderr(cct) << "Realm notify failed with " << r << dendl;
@@ -794,7 +794,11 @@ int RGWRealm::notify_zone()
 
 int RGWRealm::notify_new_period(const RGWPeriod& period)
 {
-  return notify_zone();
+  bufferlist bl;
+  // reload the gateway with the new period
+  ::encode(RGWRealmNotify::Reload, bl);
+
+  return notify_zone(bl);
 }
 
 int RGWPeriod::init(CephContext *_cct, RGWRados *_store, const string& period_realm_id,
index b2f914722d6b2b2ff7a6a55b063153475e94f96a..7d28ea3e4080a60cafa51e79448d6f5f17fe1ec4 100644 (file)
@@ -1325,7 +1325,7 @@ public:
 
   string get_control_oid();
   /// send a notify on the realm control object
-  int notify_zone();
+  int notify_zone(bufferlist& bl);
   /// notify the zone of a new period
   int notify_new_period(const RGWPeriod& period);
 };
index 7b6da87e59dcd8b666601c3b874d858c6601eb31..295e374c5d2ebe44b570617fce2b8e8df779ee6f 100644 (file)
@@ -44,7 +44,8 @@ class RGWRealmReloader::C_Reload : public Context {
   void finish(int r) { reloader->reload(); }
 };
 
-void RGWRealmReloader::handle_notify(bufferlist::iterator& p)
+void RGWRealmReloader::handle_notify(RGWRealmNotify type,
+                                     bufferlist::iterator& p)
 {
   CephContext *const cct = store->ctx();
 
index 280262dc0f3c825b1d85f7bce3b8fa0138497dac..3e60cd49d1f4e1433a00846f6ae319c450592030 100644 (file)
@@ -37,7 +37,7 @@ class RGWRealmReloader : public RGWRealmWatcher::Watcher {
   ~RGWRealmReloader();
 
   /// respond to realm notifications by scheduling a reload()
-  void handle_notify(bufferlist::iterator& p) override;
+  void handle_notify(RGWRealmNotify type, bufferlist::iterator& p) override;
 
  private:
   /// pause frontends and replace the RGWRados instance
index bbbe70d5d59ad8c3e2fe48f0b13cedef872ac893..6e47c48460affd1cb48c32685a9cb0b405b84f1b 100644 (file)
@@ -13,7 +13,7 @@
 
 
 RGWRealmWatcher::RGWRealmWatcher(CephContext* cct, RGWRealm& realm)
-  : cct(cct), watcher(nullptr)
+  : cct(cct)
 {
   // no default realm, nothing to watch
   if (realm.get_id().empty()) {
@@ -35,9 +35,9 @@ RGWRealmWatcher::~RGWRealmWatcher()
   watch_stop();
 }
 
-void RGWRealmWatcher::set_watcher(Watcher* watcher)
+void RGWRealmWatcher::add_watcher(RGWRealmNotify type, Watcher& watcher)
 {
-  this->watcher = watcher;
+  watchers.emplace(type, watcher);
 }
 
 void RGWRealmWatcher::handle_notify(uint64_t notify_id, uint64_t cookie,
@@ -46,12 +46,26 @@ void RGWRealmWatcher::handle_notify(uint64_t notify_id, uint64_t cookie,
   if (cookie != watch_handle)
     return;
 
-  auto p = bl.begin();
-  watcher->handle_notify(p);
-
   // send an empty notify ack
   bufferlist reply;
   pool_ctx.notify_ack(watch_oid, notify_id, cookie, reply);
+
+  try {
+    auto p = bl.begin();
+    while (!p.end()) {
+      RGWRealmNotify notify;
+      ::decode(notify, p);
+      auto watcher = watchers.find(notify);
+      if (watcher == watchers.end()) {
+        lderr(cct) << "Failed to find a watcher for notify type "
+            << static_cast<int>(notify) << dendl;
+        break;
+      }
+      watcher->second.handle_notify(notify, p);
+    }
+  } catch (const buffer::error &e) {
+    lderr(cct) << "Failed to decode realm notifications." << dendl;
+  }
 }
 
 void RGWRealmWatcher::handle_error(uint64_t cookie, int err)
index d780891fd7884bb22e3af41e59a73d830ae17c4a..d0e87e6b0ea5e6f9abfe1add89746d1bb1b9244a 100644 (file)
@@ -5,12 +5,18 @@
 #define RGW_REALM_WATCHER_H
 
 #include "include/rados/librados.hpp"
+#include "include/assert.h"
 #include "common/Timer.h"
 #include "common/Cond.h"
 
 class RGWRados;
 class RGWRealm;
 
+enum class RGWRealmNotify {
+  Reload,
+};
+WRITE_RAW_ENCODER(RGWRealmNotify);
+
 /**
  * RGWRealmWatcher establishes a watch on the current RGWRealm's control object,
  * and responds to notifications by recreating RGWRados with the updated realm
@@ -26,14 +32,15 @@ class RGWRealmWatcher : public librados::WatchCtx2 {
    public:
     virtual ~Watcher() = default;
 
-    virtual void handle_notify(bufferlist::iterator& p) = 0;
+    virtual void handle_notify(RGWRealmNotify type,
+                               bufferlist::iterator& p) = 0;
   };
 
   RGWRealmWatcher(CephContext* cct, RGWRealm& realm);
   ~RGWRealmWatcher();
 
-  /// register a watcher to be notified
-  void set_watcher(Watcher* watcher);
+  /// register a watcher for the given notification type
+  void add_watcher(RGWRealmNotify type, Watcher& watcher);
 
   /// respond to realm notifications by calling the appropriate watcher
   void handle_notify(uint64_t notify_id, uint64_t cookie,
@@ -56,7 +63,7 @@ class RGWRealmWatcher : public librados::WatchCtx2 {
   int watch_restart();
   void watch_stop();
 
-  Watcher* watcher;
+  std::map<RGWRealmNotify, Watcher&> watchers;
 };
 
 #endif // RGW_REALM_WATCHER_H