From 2a7bb175f64f34ee4e3d697fb58168f9267a1dee Mon Sep 17 00:00:00 2001 From: xie xingguo Date: Mon, 24 Apr 2017 11:36:50 +0800 Subject: [PATCH] tools/crushtool: replicated-rule API support This patch adds two interfaces to operate replicated crush rules, namely "--create-simple-rule" and "--remove-rule". Signed-off-by: xie xingguo --- src/test/cli/crushtool/add-item.t | 129 ++++++++++++++++++++++++++++++ src/test/cli/crushtool/help.t | 7 ++ src/tools/crushtool.cc | 82 ++++++++++++++++++- 3 files changed, 217 insertions(+), 1 deletion(-) diff --git a/src/test/cli/crushtool/add-item.t b/src/test/cli/crushtool/add-item.t index 0dd43c8bb7c..261715ca6ca 100644 --- a/src/test/cli/crushtool/add-item.t +++ b/src/test/cli/crushtool/add-item.t @@ -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 diff --git a/src/test/cli/crushtool/help.t b/src/test/cli/crushtool/help.t index 65323c33482..27dc33e3c1f 100755 --- a/src/test/cli/crushtool/help.t +++ b/src/test/cli/crushtool/help.t @@ -58,6 +58,12 @@ 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 to start from , + replicate across buckets of type , using + a choose mode of + -i mapfn --remove-rule name + remove the specified crush rule Options for the display/test stage @@ -100,6 +106,7 @@ [--outfn|-o outfile] specify output for modified crush map + $ crushtool --help-output data output from testing routine ... absolute_weights diff --git a/src/tools/crushtool.cc b/src/tools/crushtool.cc index 12eff342fdd..ca314099a71 100644 --- a/src/tools/crushtool.cc +++ b/src/tools/crushtool.cc @@ -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 to start from ,\n" + << " replicate across buckets of type , using\n" + << " a choose mode of \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 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; -- 2.47.3