]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/OSDMonitor: kill pending upmap changes too if pool is gone 20829/head
authorxie xingguo <xie.xingguo@zte.com.cn>
Mon, 5 Mar 2018 01:30:45 +0000 (09:30 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Sat, 10 Mar 2018 03:41:52 +0000 (11:41 +0800)
There are quite a lot mgr/balancer related tests that I can observe
the following logged errors:
```
2018-03-03 08:14:00.359946 7fdda18cc700 -1 maybe_remove_pg_upmaps unable to load crush-rule of pg 5.b
```
which turns out to be a *pool-deletion* vs *balancer-auto-injected-upmap-changes*
race issue.
The root cause is that we don't clean up those *pending*
pg_upmap/pg_upmap_items injected by the mgr/balancer properly simultaneously
when the corresponding pool is gone, and hence the above problem can be fixed by:
1. clean up any pending upmap changes too if the corresponding pool is gone
2. re-check pending pool removal queue before we can safely apply any new upmap changes

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
(cherry picked from commit bd828fc033222e60e9b6671ccb826cec29ec5f36)

src/mon/OSDMonitor.cc

index 90ddeac7985f15bb93ff1df5201930d41ed9b8c8..651cd4bf28776cefade71a52bccedd369f38fbb7 100644 (file)
@@ -9883,6 +9883,14 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
       err = -ENOENT;
       goto reply;
     }
+    if (pending_inc.old_pools.count(pgid.pool())) {
+      ss << "pool of " << pgid << " is pending removal";
+      err = -ENOENT;
+      getline(ss, rs);
+      wait_for_finished_proposal(op,
+        new Monitor::C_Command(mon, op, err, rs, get_last_committed() + 1));
+      return true;
+    }
 
     enum {
       OP_PG_UPMAP,
@@ -11889,6 +11897,20 @@ int OSDMonitor::_prepare_remove_pool(
       pending_inc.old_pg_upmap.insert(p.first);
     }
   }
+  // remove any pending pg_upmap mappings for this pool
+  {
+    auto it = pending_inc.new_pg_upmap.begin();
+    while (it != pending_inc.new_pg_upmap.end()) {
+      if (it->first.pool() == (uint64_t)pool) {
+        dout(10) << __func__ << " " << pool
+                 << " removing pending pg_upmap "
+                 << it->first << dendl;
+        it = pending_inc.new_pg_upmap.erase(it);
+      } else {
+        it++;
+      }
+    }
+  }
   // remove any pg_upmap_items mappings for this pool
   for (auto& p : osdmap.pg_upmap_items) {
     if (p.first.pool() == (uint64_t)pool) {
@@ -11898,6 +11920,20 @@ int OSDMonitor::_prepare_remove_pool(
       pending_inc.old_pg_upmap_items.insert(p.first);
     }
   }
+  // remove any pending pg_upmap mappings for this pool
+  {
+    auto it = pending_inc.new_pg_upmap_items.begin();
+    while (it != pending_inc.new_pg_upmap_items.end()) {
+      if (it->first.pool() == (uint64_t)pool) {
+        dout(10) << __func__ << " " << pool
+                 << " removing pending pg_upmap_items "
+                 << it->first << dendl;
+        it = pending_inc.new_pg_upmap_items.erase(it);
+      } else {
+        it++;
+      }
+    }
+  }
 
   // remove any choose_args for this pool
   CrushWrapper newcrush;