From: Sage Weil Date: Mon, 3 Mar 2014 19:32:48 +0000 (-0800) Subject: mon/OSDMonitor: handle 'osd tier add ...' race/corner case X-Git-Tag: v0.78~94^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=62e0eb7f2e9cbeaa46f8304b0be93e95f5c5c73e;p=ceph.git mon/OSDMonitor: handle 'osd tier add ...' race/corner case 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 Signed-off-by: Sage Weil --- diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 14c0b48b41b3..5f61b4cf6e74 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -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));