]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osdc/Objecter: fix tick_event handling in shutdown vs tick race 2795/head
authorSage Weil <sage@redhat.com>
Fri, 24 Oct 2014 16:32:20 +0000 (09:32 -0700)
committerSage Weil <sage@redhat.com>
Fri, 24 Oct 2014 16:32:20 +0000 (09:32 -0700)
If we fail to cancel the tick_event, we rely on tick() itself to clear
tick_event.  I'm not quite sure how we got this wrong in the previous
commit, but this boils down to two cases:

1) shutdown() successfully cancels the event and clears tick_event.  tick()
   never runs.  tick_event == NULL when we finish.
2) shutdown() fails to cancel the event because it has already started.  In
   this case tick itself is blocking (or about to block) waiting on the
   rlock.  When it does run it will clear tick_event itself, then see
   initiazed == 0 and exit without rescheduling.

Fixes: #9873
Signed-off-by: Sage Weil <sage@redhat.com>
src/osdc/Objecter.cc

index 035127acc99ce1f89d96231ad38fd372c4baffb8..c7ea0770a71cc68807b82ae11529813a2c61ab34 100644 (file)
@@ -375,8 +375,10 @@ void Objecter::shutdown()
 
   if (tick_event) {
     Mutex::Locker l(timer_lock);
-    if (timer.cancel_event(tick_event))
+    if (timer.cancel_event(tick_event)) {
+      ldout(cct, 10) <<  " successfully canceled tick" << dendl;
       tick_event = NULL;
+    }
   }
 
   if (m_request_state_hook) {
@@ -400,6 +402,7 @@ void Objecter::shutdown()
     timer.shutdown();
   }
 
+  assert(tick_event == NULL);
 }
 
 void Objecter::_send_linger(LingerOp *info)
@@ -1546,15 +1549,16 @@ void Objecter::tick()
 
   ldout(cct, 10) << "tick" << dendl;
 
+  // we are only called by C_Tick
+  assert(tick_event);
+  tick_event = NULL;
+
   if (!initialized.read()) {
     // we raced with shutdown
+    ldout(cct, 10) << __func__ << " raced with shutdown" << dendl;
     return;
   }
 
-  // we are only called by C_Tick
-  assert(tick_event);
-  tick_event = NULL;
-
   set<OSDSession*> toping;
 
   int r = 0;