From 09fab2f3bda6ae1d2b295af36348cd5905cbf3ce Mon Sep 17 00:00:00 2001 From: xie xingguo Date: Tue, 15 Aug 2017 16:46:15 +0800 Subject: [PATCH] mon: "ceph osd crush rule rename" support User may specify a rule with the same name of the pool that it serves. Since a pool can be renamed, so does the rule. Signed-off-by: xie xingguo (cherry picked from commit a5075ed253940471b347ba0773f66ea6e61398d0) --- qa/workunits/mon/crush_ops.sh | 10 ++++++++++ src/crush/CrushWrapper.cc | 27 +++++++++++++++++++++++++++ src/crush/CrushWrapper.h | 3 +++ src/mon/MonCommands.h | 5 +++++ src/mon/OSDMonitor.cc | 30 ++++++++++++++++++++++++++++++ 5 files changed, 75 insertions(+) diff --git a/qa/workunits/mon/crush_ops.sh b/qa/workunits/mon/crush_ops.sh index 1ef6e5cc1eddd..41e7d10882f52 100755 --- a/qa/workunits/mon/crush_ops.sh +++ b/qa/workunits/mon/crush_ops.sh @@ -33,6 +33,16 @@ ceph osd pool rm ec-foo ec-foo --yes-i-really-really-mean-it ceph osd crush rule ls | grep foo +ceph osd crush rule rename foo foo-asdf +ceph osd crush rule rename bar bar-asdf +ceph osd crush rule ls | grep 'foo-asdf' +ceph osd crush rule ls | grep 'bar-asdf' +ceph osd crush rule rm foo 2>&1 | grep 'does not exist' +ceph osd crush rule rm bar 2>&1 | grep 'does not exist' +ceph osd crush rule rename foo-asdf foo +ceph osd crush rule rename bar-asdf bar +ceph osd crush rule ls | expect_false grep 'foo-asdf' +ceph osd crush rule ls | expect_false grep 'bar-asdf' ceph osd crush rule rm foo ceph osd crush rule rm foo # idempotent ceph osd crush rule rm bar diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index fd21110925283..1c72454b64738 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -291,6 +291,33 @@ int CrushWrapper::rename_bucket(const string& srcname, return set_item_name(oldid, dstname); } +int CrushWrapper::rename_rule(const string& srcname, + const string& dstname, + ostream *ss) +{ + if (!rule_exists(srcname)) { + if (ss) { + *ss << "source rule name '" << srcname << "' does not exist"; + } + return -ENOENT; + } + if (rule_exists(dstname)) { + if (ss) { + *ss << "destination rule name '" << dstname << "' already exists"; + } + return -EEXIST; + } + int rule_id = get_rule_id(srcname); + auto it = rule_name_map.find(rule_id); + assert(it != rule_name_map.end()); + it->second = dstname; + if (have_rmaps) { + rule_name_rmap.erase(srcname); + rule_name_rmap[dstname] = rule_id; + } + return 0; +} + void CrushWrapper::find_takes(set& roots) const { for (unsigned i=0; imax_rules; i++) { diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index 9ef12f9b66269..5271e14411231 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -539,6 +539,9 @@ public: ostream *ss); // rule names + int rename_rule(const string& srcname, + const string& dstname, + ostream *ss); bool rule_exists(string name) const { build_rmaps(); return rule_name_rmap.count(name); diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index 57845ab3d27f1..5756f967769ad 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -646,6 +646,11 @@ COMMAND("osd crush rule create-erasure " \ COMMAND("osd crush rule rm " \ "name=name,type=CephString,goodchars=[A-Za-z0-9-_.] ", \ "remove crush rule ", "osd", "rw", "cli,rest") +COMMAND("osd crush rule rename " \ + "name=srcname,type=CephString,goodchars=[A-Za-z0-9-_.] " \ + "name=dstname,type=CephString,goodchars=[A-Za-z0-9-_.]", \ + "rename crush rule to ", + "osd", "rw", "cli,rest") COMMAND("osd crush tree " "name=shadow,type=CephChoices,strings=--show-shadow,req=false", \ "dump crush buckets and items in a tree view", diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index b6f5aca365cd4..b97e3dc009628 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -8487,6 +8487,36 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, get_last_committed() + 1)); return true; + } else if (prefix == "osd crush rule rename") { + string srcname; + string dstname; + cmd_getval(g_ceph_context, cmdmap, "srcname", srcname); + cmd_getval(g_ceph_context, cmdmap, "dstname", dstname); + if (srcname.empty() || dstname.empty()) { + ss << "must specify both source rule name and destination rule name"; + err = -EINVAL; + goto reply; + } + if (srcname == dstname) { + ss << "destination rule name is equal to source rule name"; + err = 0; + goto reply; + } + + CrushWrapper newcrush; + _get_pending_crush(newcrush); + err = newcrush.rename_rule(srcname, dstname, &ss); + if (err < 0) { + // ss has reason for failure + goto reply; + } + pending_inc.crush.clear(); + newcrush.encode(pending_inc.crush, mon->get_quorum_con_features()); + getline(ss, rs); + wait_for_finished_proposal(op, new Monitor::C_Command(mon, op, 0, rs, + get_last_committed() + 1)); + return true; + } else if (prefix == "osd setmaxosd") { int64_t newmax; if (!cmd_getval(g_ceph_context, cmdmap, "newmax", newmax)) { -- 2.39.5