]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: compute the ruleset of erasure-coded pools
authorLoic Dachary <loic@dachary.org>
Sun, 2 Feb 2014 09:05:59 +0000 (10:05 +0100)
committerLoic Dachary <loic@dachary.org>
Tue, 4 Feb 2014 07:06:26 +0000 (08:06 +0100)
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 <christophe.courtaut@gmail.com>
Signed-off-by: Loic Dachary <loic@dachary.org>
src/mon/OSDMonitor.cc

index 60262ad0c87a70d5fdd373b495bc05ec26b186bd..597f9f6cecc20ba8a32812478c8ee43100e9490f 100644 (file)
@@ -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<string,string>::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";
     }