mon: add the osd crush rename-bucket command

The synopsis is:

 osd crush rename-bucket name1 name2

It is made idempotent by interpreting -EALREADY as returned by
CrushWrapper::rename_bucket return as success.

The crush_rename_bucket method first checks for errors with
CrushWrapper::can_rename_bucket if there is no pending crush so that it
can return early and avoid the creation of a pending crush map.

If renaming is possible, CrushWrapper::rename_bucket is called on the
pending crush map (and creates it indirectly if it does not already
exists).

http://tracker.ceph.com/issues/9526 Fixes: #9526

Signed-off-by: Loic Dachary <loic-201408@dachary.org>
This commit is contained in:
Loic Dachary 2014-10-15 17:14:53 -07:00
parent 29d13d41c5
commit aa675604c9
3 changed files with 52 additions and 0 deletions

View File

@ -400,6 +400,11 @@ COMMAND("osd crush add-bucket " \
"name=type,type=CephString", \
"add no-parent (probably root) crush bucket <name> of type <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 <srcname> to <dstname>", \
"osd", "rw", "cli,rest")
COMMAND("osd crush set " \
"name=id,type=CephOsdName " \
"name=weight,type=CephFloat,range=0.0 " \

View File

@ -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")) {
// <OsdName> is 'osd.<id>' or '<id>', passed as int64_t id

View File

@ -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,