]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ReplicatedPG/PGBackend: block all ops other than Pull prior to active
authorSamuel Just <sam.just@inktank.com>
Wed, 30 Oct 2013 18:21:56 +0000 (11:21 -0700)
committerSamuel Just <sam.just@inktank.com>
Tue, 19 Nov 2013 18:06:24 +0000 (10:06 -0800)
Previously, it was guarranteed that prior to activation, flushed would
be false on a replica.  Now, there may be a period where flushed is true
due to the flush in Stray completing prior to activation and flushed
being false again.  This is necessary since shortly it won't be possible
to determine from the osdmap whether a stray will be activated in a
particular interval.

Signed-off-by: Samuel Just <sam.just@inktank.com>
src/osd/PG.cc
src/osd/PGBackend.h
src/osd/ReplicatedBackend.cc
src/osd/ReplicatedBackend.h
src/osd/ReplicatedPG.cc

index 4f76a5190cd663049795d4b9de8a394d2d319a78..ef529c189f8496d30488cc121c1c42354b59f3c0 100644 (file)
@@ -6203,11 +6203,10 @@ PG::RecoveryState::Stray::Stray(my_context ctx)
   assert(!pg->is_active());
   assert(!pg->is_peering());
   assert(!pg->is_primary());
-  if (!pg->is_replica()) // stray, need to flush for pulls
-    pg->start_flush(
-      context< RecoveryMachine >().get_cur_transaction(),
-      context< RecoveryMachine >().get_on_applied_context_list(),
-      context< RecoveryMachine >().get_on_safe_context_list());
+  pg->start_flush(
+    context< RecoveryMachine >().get_cur_transaction(),
+    context< RecoveryMachine >().get_on_applied_context_list(),
+    context< RecoveryMachine >().get_on_safe_context_list());
 }
 
 boost::statechart::result PG::RecoveryState::Stray::react(const MLogRec& logevt)
index 408c589a08a06d7d04e2b9e8e8322fc2a92af0fc..42959664ea89b3f8b3f8d90f12860b424072598c 100644 (file)
      RecoveryHandle *h      ///< [in,out] handle to attach recovery op to
      ) = 0;
 
+   /**
+    * true if PGBackend can handle this message while inactive
+    *
+    * If it returns true, handle_message *must* also return true
+    */
+   virtual bool can_handle_while_inactive(OpRequestRef op) = 0;
+
    /// gives PGBackend a crack at an incoming message
    virtual bool handle_message(
      OpRequestRef op ///< [in] message received
index 9529e15ae7728e083839b64dcec57d166b003624..74b12ad4614c772ccc01f3acfbd9e592f942c6df 100644 (file)
@@ -91,6 +91,31 @@ void ReplicatedBackend::check_recovery_sources(const OSDMapRef osdmap)
   }
 }
 
+bool ReplicatedBackend::can_handle_while_inactive(OpRequestRef op)
+{
+  dout(10) << __func__ << ": " << op << dendl;
+  switch (op->get_req()->get_type()) {
+  case MSG_OSD_PG_PULL:
+    return true;
+  case MSG_OSD_SUBOP: {
+    MOSDSubOp *m = static_cast<MOSDSubOp*>(op->get_req());
+    if (m->ops.size() >= 1) {
+      OSDOp *first = &m->ops[0];
+      switch (first->op.op) {
+      case CEPH_OSD_OP_PULL:
+       return true;
+      default:
+       return false;
+      }
+    } else {
+      return false;
+    }
+  }
+  default:
+    return false;
+  }
+}
+
 bool ReplicatedBackend::handle_message(
   OpRequestRef op
   )
index a95a77b1a1dcd6420af324a9d51a1f6079bf1da4..0c03a7abb3e913f1c28c9335c07a0416761e80ff 100644 (file)
@@ -66,6 +66,9 @@ public:
 
   void check_recovery_sources(const OSDMapRef osdmap);
 
+  /// @see PGBackend::delay_message_until_active
+  bool can_handle_while_inactive(OpRequestRef op);
+
   /// @see PGBackend::handle_message
   bool handle_message(
     OpRequestRef op
index 5bcc82cdd0d6464c479c05bf98ee3efbf8cbd276..c91ed68505ac3ff7d0288206c148c39f2f698bba 100644 (file)
@@ -841,12 +841,25 @@ void ReplicatedPG::do_request(
     return;
   }
 
+  if (!is_active()) {
+    // Delay unless PGBackend says it's ok
+    if (pgbackend->can_handle_while_inactive(op)) {
+      bool handled = pgbackend->handle_message(op);
+      assert(handled);
+      return;
+    } else {
+      waiting_for_active.push_back(op);
+      return;
+    }
+  }
+
+  assert(is_active() && flushes_in_progress == 0);
   if (pgbackend->handle_message(op))
     return;
 
   switch (op->get_req()->get_type()) {
   case CEPH_MSG_OSD_OP:
-    if (is_replay() || !is_active()) {
+    if (is_replay()) {
       dout(20) << " replay, waiting for active on " << op << dendl;
       waiting_for_active.push_back(op);
       return;