diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index 90c03da4f57..a2e5d4b7ba4 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -400,6 +400,11 @@ COMMAND("osd crush add-bucket " \ "name=type,type=CephString", \ "add no-parent (probably root) crush bucket of type ", \ "osd", "rw", "cli,rest") +COMMAND("osd crush rename-bucket " \ + "name=srcname,type=CephString,goodchars=[A-Za-z0-9-_.] " \ + "name=dstname,type=CephString,goodchars=[A-Za-z0-9-_.]", \ + "rename bucket to ", \ + "osd", "rw", "cli,rest") COMMAND("osd crush set " \ "name=id,type=CephOsdName " \ "name=weight,type=CephFloat,range=0.0 " \ diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 3c4f51ed6c4..f34a7e903a6 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -3195,6 +3195,38 @@ int OSDMonitor::prepare_new_pool(MPoolOp *m) pg_pool_t::TYPE_REPLICATED, 0, ss); } +int OSDMonitor::crush_rename_bucket(const string& srcname, + const string& dstname, + ostream *ss) +{ + int ret; + // + // Avoid creating a pending crush if it does not already exists and + // the rename would fail. + // + if (!_have_pending_crush()) { + ret = _get_stable_crush().can_rename_bucket(srcname, + dstname, + ss); + if (ret) + return ret; + } + + CrushWrapper newcrush; + _get_pending_crush(newcrush); + + ret = newcrush.rename_bucket(srcname, + dstname, + ss); + if (ret) + return ret; + + pending_inc.crush.clear(); + newcrush.encode(pending_inc.crush); + *ss << "renamed bucket " << srcname << " into " << dstname; + return 0; +} + int OSDMonitor::crush_ruleset_create_erasure(const string &name, const string &profile, int *ruleset, @@ -4091,6 +4123,18 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m, ss << "added bucket " << name << " type " << typestr << " to crush map"; goto update; + } else if (prefix == "osd crush rename-bucket") { + string srcname, dstname; + cmd_getval(g_ceph_context, cmdmap, "srcname", srcname); + cmd_getval(g_ceph_context, cmdmap, "dstname", dstname); + + err = crush_rename_bucket(srcname, dstname, &ss); + if (err == -EALREADY) // equivalent to success for idempotency + err = 0; + if (err) + goto reply; + else + goto update; } else if (osdid_present && (prefix == "osd crush set" || prefix == "osd crush add")) { // is 'osd.' or '', passed as int64_t id diff --git a/src/mon/OSDMonitor.h b/src/mon/OSDMonitor.h index 27a4eddf692..411650dcddc 100644 --- a/src/mon/OSDMonitor.h +++ b/src/mon/OSDMonitor.h @@ -261,6 +261,9 @@ private: bool prepare_pool_op (MPoolOp *m); bool prepare_pool_op_create (MPoolOp *m); bool prepare_pool_op_delete(MPoolOp *m); + int crush_rename_bucket(const string& srcname, + const string& dstname, + ostream *ss); int crush_ruleset_create_erasure(const string &name, const string &profile, int *ruleset,