]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
OSD: create a helper for handling OSDMap subscriptions, and clean them up
authorGreg Farnum <greg@inktank.com>
Tue, 11 Feb 2014 21:34:39 +0000 (13:34 -0800)
committerGreg Farnum <greg@inktank.com>
Sat, 15 Feb 2014 00:54:43 +0000 (16:54 -0800)
We've had some trouble with not clearing out subscription requests and
overloading the monitors (though only because of other bugs). Write a
helper for handling subscription requests that we can use to centralize
safety logic. Clear out the subscription whenever we get a map that covers
it; if there are more maps available than we received, we will issue another
subscription request based on "m->newest_map" at the end of handle_osd_map().

Notice that the helper will no longer request old maps which we already have,
and that unless forced it will not dispatch multiple subscribe requests
to a single monitor.
Skipping old maps is safe:
1) we only trim old maps when the monitor tells us to,
2) we do not send messages to our peers until we have updated our maps
from the monitor.
That means only old and broken OSDs will send us messages based on maps
in our past, and we can (and should) ignore any directives from them anyway.

Signed-off-by: Greg Farnum <greg@inktank.com>
src/osd/OSD.cc
src/osd/OSD.h

index 673b3a32d359e6f26f833f9d23d91422a235de76..bc490a8ff5715c2fb87ed491735a7c8a767b7ca3 100644 (file)
@@ -5011,6 +5011,18 @@ struct C_OnMapApply : public Context {
   }
 };
 
+void OSD::osdmap_subscribe(version_t epoch, bool force_request)
+{
+  OSDMapRef osdmap = service.get_osdmap();
+  if (osdmap->get_epoch() >= epoch)
+    return;
+
+  if (monc->sub_want_increment("osdmap", epoch, CEPH_SUBSCRIBE_ONETIME) ||
+      force_request) {
+    monc->renew_subs();
+  }
+}
+
 void OSD::handle_osd_map(MOSDMap *m)
 {
   assert(osd_lock.is_locked());
@@ -5062,6 +5074,9 @@ void OSD::handle_osd_map(MOSDMap *m)
     return;
   }
 
+  // even if this map isn't from a mon, we may have satisfied our subscription
+  monc->sub_got("osdmap", last);
+
   // missing some?
   bool skip_maps = false;
   if (first > osdmap->get_epoch() + 1) {
index cebceb7150e95e1f0812fbcaed0e1377ad638f2a..ed124c9ca8c037542ac21e55826e342d13caad61 100644 (file)
@@ -673,7 +673,7 @@ protected:
   Messenger   *cluster_messenger;
   Messenger   *client_messenger;
   Messenger   *objecter_messenger;
-  MonClient   *monc;
+  MonClient   *monc; // check the "monc helpers" list before accessing directly
   PerfCounters      *logger;
   PerfCounters      *recoverystate_perf;
   ObjectStore *store;
@@ -825,6 +825,23 @@ public:
   };
 
 private:
+  /**
+   *  @defgroup monc helpers
+   *
+   *  Right now we only have the one
+   */
+
+  /**
+   * Ask the Monitors for a sequence of OSDMaps.
+   *
+   * @param epoch The epoch to start with when replying
+   * @param force_request True if this request forces a new subscription to
+   * the monitors; false if an outstanding request that encompasses it is
+   * sufficient.
+   */
+  void osdmap_subscribe(version_t epoch, bool force_request);
+  /** @} monc helpers */
+
   // -- heartbeat --
   /// information about a heartbeat peer
   struct HeartbeatInfo {