]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: fix agent thread shutdown 1395/head
authorSage Weil <sage@inktank.com>
Fri, 7 Mar 2014 00:12:30 +0000 (16:12 -0800)
committerSage Weil <sage@inktank.com>
Fri, 7 Mar 2014 00:12:30 +0000 (16:12 -0800)
We had an old invariant that agent_queue would have at least 1 entry in
it to simplify some other code paths, but it turns out that it is simpler
not to do that.

In particular, this was triggering a failed assertion on shutdown when we
assert that the queue is empty.

Dump offending items on shutdown if they are there, tho, to catch any
future bugs.

Fixes: #7637
Signed-off-by: Sage Weil <sage@inktank.com>
src/osd/OSD.cc
src/osd/OSD.h

index f229bc08503e78eb5866a4e7446ee6f3b3235e15..8aee20185f99a996edd674a7074cb4de2351c2b0 100644 (file)
@@ -471,11 +471,12 @@ void OSDService::agent_entry()
   dout(10) << __func__ << " start" << dendl;
   agent_lock.Lock();
 
-  // stick at least one level in there to simplify other paths
-  if (agent_queue.empty())
-    agent_queue[0];
-
   while (!agent_stop_flag) {
+    if (agent_queue.empty()) {
+      dout(20) << __func__ << " empty queue" << dendl;
+      agent_cond.Wait(agent_lock);
+      continue;
+    }
     uint64_t level = agent_queue.rbegin()->first;
     set<PGRef>& top = agent_queue.rbegin()->second;
     dout(10) << __func__
@@ -515,7 +516,11 @@ void OSDService::agent_stop()
     // By this time all ops should be cancelled
     assert(agent_ops == 0);
     // By this time all PGs are shutdown and dequeued
-    assert(agent_queue.empty());
+    if (!agent_queue.empty()) {
+      set<PGRef>& top = agent_queue.rbegin()->second;
+      derr << "agent queue not empty, for example " << (*top.begin())->info.pgid << dendl;
+      assert(0 == "agent queue not empty");
+    }
 
     agent_stop_flag = true;
     agent_cond.Signal();
index b3e290aab6eaf345c2f0838c0fc2441be3293c26..7ee3442793c7cbe51316f91c25a4e6b505a4c9f1 100644 (file)
@@ -487,7 +487,7 @@ public:
     if (p == agent_queue_pos)
       ++agent_queue_pos;
     oq.erase(p);
-    if (oq.empty() && agent_queue.size() > 1) {
+    if (oq.empty()) {
       if (agent_queue.rbegin()->first == old_priority)
        agent_valid_iterator = false;
       agent_queue.erase(old_priority);