]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/OSDMonitor: handle 'osd tier add ...' race/corner case
authorSage Weil <sage@inktank.com>
Mon, 3 Mar 2014 19:32:48 +0000 (11:32 -0800)
committerSage Weil <sage@inktank.com>
Tue, 4 Mar 2014 05:16:24 +0000 (21:16 -0800)
If you have two racing requests to add two different pools as a tier, the
committed checks will pass but they proposals will conflict.  Recheck the
pending pools for the same conditions and wait for a commit if they
occur.

Reported-by: Loic Dachary <loic@dachary.org>
Signed-off-by: Sage Weil <sage@inktank.com>
src/mon/OSDMonitor.cc

index 14c0b48b41b3925b0e635f99df320836032dea84..5f61b4cf6e74c193591d0e1519f049f954d5c318 100644 (file)
@@ -4506,8 +4506,14 @@ done:
       goto reply;
     }
     // go
-    pending_inc.get_new_pool(pool_id, p)->tiers.insert(tierpool_id);
-    pending_inc.get_new_pool(tierpool_id, tp)->tier_of = pool_id;
+    pg_pool_t *np = pending_inc.get_new_pool(pool_id, p);
+    pg_pool_t *ntp = pending_inc.get_new_pool(tierpool_id, tp);
+    if (np->tiers.count(tierpool_id) || ntp->is_tier()) {
+      wait_for_finished_proposal(new C_RetryMessage(this, m));
+      return true;
+    }
+    np->tiers.insert(tierpool_id);
+    ntp->tier_of = pool_id;
     ss << "pool '" << tierpoolstr << "' is now (or already was) a tier of '" << poolstr << "'";
     wait_for_finished_proposal(new Monitor::C_Command(mon, m, 0, ss.str(),
                                              get_last_committed() + 1));