]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
tools/crushtool: replicated-rule API support 15011/head
authorxie xingguo <xie.xingguo@zte.com.cn>
Mon, 24 Apr 2017 03:36:50 +0000 (11:36 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Sat, 20 May 2017 03:21:41 +0000 (11:21 +0800)
This patch adds two interfaces to operate replicated crush rules,
namely "--create-simple-rule" and "--remove-rule".

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
src/test/cli/crushtool/add-item.t
src/test/cli/crushtool/help.t
src/tools/crushtool.cc

index 0dd43c8bb7c556ab7c807189af28ee249a84a11b..261715ca6cafb43b1700ebbefff365a03e0c4578 100644 (file)
@@ -1,5 +1,134 @@
   $ crushtool -i "$TESTDIR/simple.template" --add-item 0 1.0 device0 --loc host host0 --loc cluster cluster0 -o one > /dev/null
   $ crushtool -i one --add-item 1 1.0 device1 --loc host host0 --loc cluster cluster0 -o two > /dev/null
+  $ crushtool -i two --create-simple-rule simple-rule cluster0 host firstn -o two > /dev/null
+  $ crushtool -d two
+  # begin crush map
+  
+  # devices
+  device 0 device0
+  device 1 device1
+  
+  # types
+  type 0 device
+  type 1 host
+  type 2 cluster
+  
+  # buckets
+  host host0 {
+  \tid -2\t\t# do not change unnecessarily (esc)
+  \t# weight 2.000 (esc)
+  \talg straw (esc)
+  \thash 0\t# rjenkins1 (esc)
+  \titem device0 weight 1.000 (esc)
+  \titem device1 weight 1.000 (esc)
+  }
+  cluster cluster0 {
+  \tid -1\t\t# do not change unnecessarily (esc)
+  \t# weight 2.000 (esc)
+  \talg straw (esc)
+  \thash 0\t# rjenkins1 (esc)
+  \titem host0 weight 2.000 (esc)
+  }
+  
+  # rules
+  rule data {
+  \truleset 0 (esc)
+  \ttype replicated (esc)
+  \tmin_size 1 (esc)
+  \tmax_size 10 (esc)
+  \tstep take cluster0 (esc)
+  \tstep chooseleaf firstn 0 type host (esc)
+  \tstep emit (esc)
+  }
+  rule metadata {
+  \truleset 1 (esc)
+  \ttype replicated (esc)
+  \tmin_size 1 (esc)
+  \tmax_size 10 (esc)
+  \tstep take cluster0 (esc)
+  \tstep chooseleaf firstn 0 type host (esc)
+  \tstep emit (esc)
+  }
+  rule rbd {
+  \truleset 2 (esc)
+  \ttype replicated (esc)
+  \tmin_size 1 (esc)
+  \tmax_size 10 (esc)
+  \tstep take cluster0 (esc)
+  \tstep chooseleaf firstn 0 type host (esc)
+  \tstep emit (esc)
+  }
+  rule simple-rule {
+  \truleset 3 (esc)
+  \ttype replicated (esc)
+  \tmin_size 1 (esc)
+  \tmax_size 10 (esc)
+  \tstep take cluster0 (esc)
+  \tstep chooseleaf firstn 0 type host (esc)
+  \tstep emit (esc)
+  }
+  
+  # end crush map
+  $ crushtool -i two --remove-rule simple-rule -o two > /dev/null
+  $ crushtool -d two
+  # begin crush map
+  
+  # devices
+  device 0 device0
+  device 1 device1
+  
+  # types
+  type 0 device
+  type 1 host
+  type 2 cluster
+  
+  # buckets
+  host host0 {
+  \tid -2\t\t# do not change unnecessarily (esc)
+  \t# weight 2.000 (esc)
+  \talg straw (esc)
+  \thash 0\t# rjenkins1 (esc)
+  \titem device0 weight 1.000 (esc)
+  \titem device1 weight 1.000 (esc)
+  }
+  cluster cluster0 {
+  \tid -1\t\t# do not change unnecessarily (esc)
+  \t# weight 2.000 (esc)
+  \talg straw (esc)
+  \thash 0\t# rjenkins1 (esc)
+  \titem host0 weight 2.000 (esc)
+  }
+  
+  # rules
+  rule data {
+  \truleset 0 (esc)
+  \ttype replicated (esc)
+  \tmin_size 1 (esc)
+  \tmax_size 10 (esc)
+  \tstep take cluster0 (esc)
+  \tstep chooseleaf firstn 0 type host (esc)
+  \tstep emit (esc)
+  }
+  rule metadata {
+  \truleset 1 (esc)
+  \ttype replicated (esc)
+  \tmin_size 1 (esc)
+  \tmax_size 10 (esc)
+  \tstep take cluster0 (esc)
+  \tstep chooseleaf firstn 0 type host (esc)
+  \tstep emit (esc)
+  }
+  rule rbd {
+  \truleset 2 (esc)
+  \ttype replicated (esc)
+  \tmin_size 1 (esc)
+  \tmax_size 10 (esc)
+  \tstep take cluster0 (esc)
+  \tstep chooseleaf firstn 0 type host (esc)
+  \tstep emit (esc)
+  }
+  
+  # end crush map
   $ crushtool -d two -o final
   $ cmp final "$TESTDIR/simple.template.two"
   $ crushtool -i two --add-item 1 1.0 device1 --loc host host0 --loc cluster cluster0 -o three 2>/dev/null >/dev/null || echo FAIL
index 65323c33482304a0d4005724486b02ca2c7d706f..27dc33e3c1f0035ef0800fbc7aae04b474d63fa8 100755 (executable)
                            reweight a given item (and adjust ancestor
                            weights as needed)
      -i mapfn --reweight   recalculate all bucket weights
+     -i mapfn --create-simple-rule name root type mode
+                           create crush rule <name> to start from <root>,
+                           replicate across buckets of type <type>, using
+                           a choose mode of <firstn|indep>
+     -i mapfn --remove-rule name
+                           remove the specified crush rule
   
   Options for the display/test stage
   
      [--outfn|-o outfile]
                            specify output for modified crush map
   
   $ crushtool --help-output
   data output from testing routine ...
              absolute_weights
index 12eff342fdd9e278ce7673175f4705709afd3584..ca314099a7143e1bedf10a7943cc44786ba38519 100644 (file)
@@ -166,6 +166,12 @@ void usage()
   cout << "                         reweight a given item (and adjust ancestor\n"
        << "                         weights as needed)\n";
   cout << "   -i mapfn --reweight   recalculate all bucket weights\n";
+  cout << "   -i mapfn --create-simple-rule name root type mode\n"
+       << "                         create crush rule <name> to start from <root>,\n"
+       << "                         replicate across buckets of type <type>, using\n"
+       << "                         a choose mode of <firstn|indep>\n";
+  cout << "   -i mapfn --remove-rule name\n"
+       << "                         remove the specified crush rule\n";
   cout << "\n";
   cout << "Options for the display/test stage\n";
   cout << "\n";
@@ -252,6 +258,9 @@ int main(int argc, const char **argv)
   bool reweight = false;
   int add_item = -1;
   bool update_item = false;
+  bool add_rule = false;
+  std::string rule_name, rule_root, rule_type, rule_mode;
+  bool del_rule = false;
   float add_weight = 0;
   map<string,string> add_loc;
   float reweight_weight = 0;
@@ -406,6 +415,48 @@ int main(int argc, const char **argv)
       }
       add_name.assign(*i);
       i = args.erase(i);
+    } else if (ceph_argparse_witharg(args, i, &val, err, "--create-simple-rule", (char*)NULL)) {
+      rule_name.assign(val);
+      if (!err.str().empty()) {
+        cerr << err.str() << std::endl;
+        return EXIT_FAILURE;
+      }
+      if (i == args.end()) {
+        cerr << "expecting additional argument to --create-simple-rule" << std::endl;
+        return EXIT_FAILURE;
+      }
+
+      rule_root.assign(*i);
+      i = args.erase(i);
+      if (i == args.end()) {
+        cerr << "expecting additional argument to --create-simple-rule" << std::endl;
+        return EXIT_FAILURE;
+      }
+
+      rule_type.assign(*i);
+      i = args.erase(i);
+      if (i == args.end()) {
+        cerr << "expecting additional argument to --create-simple-rule" << std::endl;
+        return EXIT_FAILURE;
+      }
+
+      rule_mode.assign(*i);
+      i = args.erase(i);
+
+      cout << "--create-simple-rule:"
+           << " name=" << rule_name
+           << " root=" << rule_root
+           << " type=" << rule_type
+           << " mode=" << rule_mode
+           << std::endl;
+      add_rule = true;
+    } else if (ceph_argparse_witharg(args, i, &val, "--remove-rule", (char*)NULL)) {
+      rule_name.assign(val);
+      if (!err.str().empty()) {
+        cerr << err.str() << std::endl;
+        return EXIT_FAILURE;
+      }
+      del_rule = true;
     } else if (ceph_argparse_witharg(args, i, &val, "--loc", (char*)NULL)) {
       std::string type(val);
       if (i == args.end()) {
@@ -548,7 +599,7 @@ int main(int argc, const char **argv)
     return EXIT_FAILURE;
   }
   if (!check && !compile && !decompile && !build && !test && !reweight && !adjust && !tree && !dump &&
-      add_item < 0 && full_location < 0 &&
+      add_item < 0 && !add_rule && !del_rule && full_location < 0 &&
       remove_name.empty() && reweight_name.empty()) {
     cerr << "no action specified; -h for help" << std::endl;
     return EXIT_FAILURE;
@@ -840,6 +891,35 @@ int main(int argc, const char **argv)
     }
   }
 
+  if (add_rule) {
+    if (crush.rule_exists(rule_name)) {
+      cerr << "rule " << rule_name << " already exists" << std::endl;
+      return EXIT_FAILURE;
+    }
+    int r = crush.add_simple_ruleset(rule_name, rule_root, rule_type, rule_mode,
+      pg_pool_t::TYPE_REPLICATED, &err);
+    if (r < 0) {
+      cerr << err.str() << std::endl;
+      return EXIT_FAILURE;
+    }
+    modified = true;
+  }
+
+  if (del_rule) {
+    if (!crush.rule_exists(rule_name)) {
+      cerr << "rule " << rule_name << " does not exist" << std::endl;
+      return 0;
+    }
+    int ruleno = crush.get_rule_id(rule_name);
+    assert(ruleno >= 0);
+    int r = crush.remove_rule(ruleno);
+    if (r < 0) {
+      cerr << "fail to remove rule " << rule_name << std::endl;
+      return EXIT_FAILURE;
+    }
+    modified = true;
+  }
+
   if (reweight) {
     crush.reweight(g_ceph_context);
     modified = true;