]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: periodically request newer map from mon if waiting peering events
authorSage Weil <sage@redhat.com>
Mon, 12 Mar 2018 14:16:12 +0000 (09:16 -0500)
committerSage Weil <sage@redhat.com>
Wed, 4 Apr 2018 13:26:58 +0000 (08:26 -0500)
If we have peering events waiting on a newer map than we have, request it
from the mon.  Do this periodically in tick so that we normally wait to get
it from a peer first.

This avoids a deadlock situation where we are, say, waiting for a newer
map to create a pg or but do not ever get the map to do it (because the
cluster is idle).

Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/OSD.cc
src/osd/OSD.h

index 1745f92a6af90532bc95437b9683ae6d6525e13f..dd42641bf348876cf6040baf66e6823c00e411f9 100644 (file)
@@ -4779,6 +4779,17 @@ void OSD::tick_without_osd_lock()
       send_failures();
     }
     map_lock.put_read();
+
+    epoch_t max_waiting_epoch = 0;
+    for (auto s : shards) {
+      max_waiting_epoch = std::max(max_waiting_epoch,
+                                  s->get_max_waiting_epoch());
+    }
+    if (max_waiting_epoch > get_osdmap()->get_epoch()) {
+      dout(20) << __func__ << " max_waiting_epoch " << max_waiting_epoch
+              << ", requesting new map" << dendl;
+      osdmap_subscribe(superblock.newest_map + 1, false);
+    }
   }
 
   if (is_active()) {
@@ -9319,6 +9330,18 @@ void OSDShard::wait_min_pg_epoch(epoch_t need)
   waiting_for_min_pg_epoch = false;
 }
 
+epoch_t OSDShard::get_max_waiting_epoch()
+{
+  Mutex::Locker l(sdata_op_ordering_lock);
+  epoch_t r = 0;
+  for (auto& i : pg_slots) {
+    if (!i.second->waiting_peering.empty()) {
+      r = std::max(r, i.second->waiting_peering.rbegin()->first);
+    }
+  }
+  return r;
+}
+
 void OSDShard::consume_map(
   OSDMapRef& new_osdmap,
   unsigned *pushes_to_free)
index e9a52fd011173d01b031f38a475fec34503ff3e4..9fd4ddcf07c516bf0b5bcec70577bfe41dc1a21a 100644 (file)
@@ -1171,6 +1171,9 @@ struct OSDShard {
   epoch_t get_min_pg_epoch();
   void wait_min_pg_epoch(epoch_t need);
 
+  /// return newest epoch we are waiting for
+  epoch_t get_max_waiting_epoch();
+
   /// push osdmap into shard
   void consume_map(
     OSDMapRef& osdmap,