From b7db487a64e878d5f7aaaba68bbe2a8adc074fff Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Mon, 3 Mar 2014 15:25:21 +0100 Subject: [PATCH] mon: pool create erasure implicit ruleset creation If the crush_ruleset parameter is missing, set it to the pool name. If the crush_ruleset parameter is set to a name that does not match any of the existing rulesets, create one using the pool creation parameters. If the ruleset exists and is in the pending map or if the ruleset was just created (meaning it exists in the pending map), the prepare_pool_crush_ruleset method returns EAGAIN so that the pool creation message is retried after the pending map is proposed. If the ruleset exists, it is used to initialize the newly created pool, as before. http://tracker.ceph.com/issues/7571 fixes #7571 Signed-off-by: Loic Dachary --- src/mon/OSDMonitor.cc | 49 ++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index e4f527bdc1303..dab7fb6d765c8 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -3002,30 +3002,31 @@ int OSDMonitor::prepare_pool_crush_ruleset(const string &poolstr, break; case pg_pool_t::TYPE_ERASURE: { - map::const_iterator ruleset = - properties.find("crush_ruleset"); - if (ruleset == properties.end()) { - ss << "prepare_pool_crush_ruleset: crush_ruleset is missing from " - << properties; - return -EINVAL; - } - - *crush_ruleset = osdmap.crush->get_rule_id(ruleset->second); - if (*crush_ruleset < 0) { - CrushWrapper newcrush; - _get_pending_crush(newcrush); - - int rule = newcrush.get_rule_id(ruleset->second); - if (rule < 0) { - ss << "prepare_pool_crush_ruleset: ruleset " << ruleset->second - << " does not exist"; - return -EINVAL; - } else { - dout(20) << "prepare_pool_crush_ruleset: ruleset " - << ruleset->second << " try again" << dendl; - return -EAGAIN; - } - } + string ruleset; + map::const_iterator i = properties.find("crush_ruleset"); + if (i == properties.end()) { + dout(1) << "prepare_pool_crush_ruleset: implicitly use ruleset " + << "named after the pool: " << poolstr << dendl; + ruleset = poolstr; + } else { + ruleset = i->second; + } + + int err = crush_ruleset_create_erasure(ruleset, properties, + crush_ruleset, ss); + switch (err) { + case -EALREADY: + dout(20) << "prepare_pool_crush_ruleset: ruleset " + << ruleset << " try again" << dendl; + case 0: + // need to wait for the crush rule to be proposed before proceeding + err = -EAGAIN; + break; + case -EEXIST: + err = 0; + break; + } + return err; } break; default: -- 2.39.5