]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: pool create erasure implicit ruleset creation
authorLoic Dachary <loic@dachary.org>
Mon, 3 Mar 2014 14:25:21 +0000 (15:25 +0100)
committerLoic Dachary <loic@dachary.org>
Mon, 17 Mar 2014 08:48:02 +0000 (09:48 +0100)
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 <loic@dachary.org>
src/mon/OSDMonitor.cc

index e4f527bdc1303964246fbe184aa4736bc94bfae4..dab7fb6d765c8741c305a1389cfb63a341c12f50 100644 (file)
@@ -3002,30 +3002,31 @@ int OSDMonitor::prepare_pool_crush_ruleset(const string &poolstr,
       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;
-         }
-       }
+       string ruleset;
+       map<string,string>::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: