From: Loic Dachary Date: Sun, 2 Feb 2014 09:05:59 +0000 (+0100) Subject: mon: compute the ruleset of erasure-coded pools X-Git-Tag: v0.78~226^2~14 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1acc73bb09e2c5630b30acf1af55ec8753119781;p=ceph.git mon: compute the ruleset of erasure-coded pools The default ruleset of an erasure coded pool may depend on the parameters used to configure it. In the case of a pyramidal / hierarchical plugin, the desired ruleset will, for instance, chose from datacenters and then from racks and disperse local coding chunks among them. For this reason the default ruleset cannot be hardcoded in config_opts as it is for replicated pools. Instead, the "crush_ruleset" property is interpreted to be the name of an existing crush ruleset to be used. If the corresponding ruleset is found in a pending crushmap, the prepare_pool_crush_ruleset will return EAGAIN. The "osd pool create" caller is modified to handle the EAGAIN error and reschedules the message. Reviewed-By: Christophe Courtaut Signed-off-by: Loic Dachary --- diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 60262ad0c87a..597f9f6cecc2 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -2827,6 +2827,34 @@ int OSDMonitor::prepare_pool_crush_ruleset(const unsigned pool_type, *crush_ruleset = CrushWrapper::get_osd_pool_default_crush_replicated_ruleset(g_ceph_context); 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; + } + } + } + break; default: ss << "prepare_pool_crush_ruleset: " << pool_type << " is not a known pool type"; @@ -4112,11 +4140,18 @@ done: pg_num, pgp_num, properties, pool_type, ss); - if (err < 0 && err != -EEXIST) { - goto reply; - } - if (err == -EEXIST) { - ss << "pool '" << poolstr << "' already exists"; + if (err < 0) { + switch(err) { + case -EEXIST: + ss << "pool '" << poolstr << "' already exists"; + break; + case -EAGAIN: + wait_for_finished_proposal(new C_RetryMessage(this, m)); + return true; + default: + goto reply; + break; + } } else { ss << "pool '" << poolstr << "' created"; }