Merge pull request #15875 from xiexingguo/wip-osdmon-20170623

mon/OSDMonitor: "osd crush class rename" support

Reviewed-by: Sage Weil <sage@redhat.com>
This commit is contained in:
Sage Weil 2017-06-24 23:21:02 -05:00 committed by GitHub
commit 4e9fd2ae8d
5 changed files with 82 additions and 7 deletions

View File

@ -1537,21 +1537,24 @@ int CrushWrapper::bucket_remove_item(crush_bucket *bucket, int item)
return crush_bucket_remove_item(crush, bucket, item);
}
int CrushWrapper::update_device_class(CephContext *cct, int id, const string& class_name, const string& name)
int CrushWrapper::update_device_class(int id,
const string& class_name,
const string& name,
ostream *ss)
{
int class_id = get_class_id(class_name);
if (class_id < 0) {
ldout(cct, 0) << "update_device_class class " << class_name << " does not exist " << dendl;
*ss << "class " << class_name << " does not exist";
return -ENOENT;
}
if (id < 0) {
ldout(cct, 0) << "update_device_class " << name << " id " << id << " is negative " << dendl;
*ss << name << " id " << id << " is negative";
return -EINVAL;
}
assert(item_exists(id));
if (class_map.count(id) != 0 && class_map[id] == class_id) {
ldout(cct, 5) << "update_device_class " << name << " already set to class " << class_name << dendl;
*ss << name << " already set to class " << class_name;
return 0;
}

View File

@ -466,6 +466,22 @@ public:
class_name.erase(class_id);
return 0;
}
int rename_class(const string& srcname, const string& dstname) {
auto p = class_rname.find(srcname);
if (p == class_rname.end())
return -ENOENT;
int class_id = p->second;
auto q = class_name.find(class_id);
if (q == class_name.end())
return -ENOENT;
class_rname.erase(srcname);
class_name.erase(class_id);
class_rname[dstname] = class_id;
class_name[class_id] = dstname;
return 0;
}
int get_or_create_class_id(const string& name) {
int c = get_class_id(name);
if (c < 0) {
@ -1175,7 +1191,7 @@ public:
have_uniform_rules = !has_legacy_rulesets();
}
int update_device_class(CephContext *cct, int id, const string& class_name, const string& name);
int update_device_class(int id, const string& class_name, const string& name, ostream *ss);
int device_class_clone(int original, int device_class, int *clone);
bool class_is_in_use(int class_id);
int populate_classes();

View File

@ -616,6 +616,11 @@ COMMAND("osd crush class rm " \
"name=class,type=CephString,goodchars=[A-Za-z0-9-_]", \
"remove crush device class <class>", \
"osd", "rw", "cli,rest")
COMMAND("osd crush class rename " \
"name=srcname,type=CephString,goodchars=[A-Za-z0-9-_] " \
"name=dstname,type=CephString,goodchars=[A-Za-z0-9-_]", \
"rename crush device class <srcname> to <dstname>", \
"osd", "rw", "cli,rest")
COMMAND("osd crush class ls", \
"list all crush device classes", \
"osd", "r", "cli,rest")

View File

@ -7070,8 +7070,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
dout(5) << action << " crush item id " << osdid << " name '"
<< name << "' device_class " << device_class << dendl;
err = newcrush.update_device_class(g_ceph_context, osdid, device_class, name);
err = newcrush.update_device_class(osdid, device_class, name, &ss);
if (err < 0)
goto reply;
@ -7216,6 +7215,53 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
ss << "removed class " << device_class << " with id " << class_id
<< " from crush map";
goto update;
} else if (prefix == "osd crush class rename") {
string srcname, dstname;
if (!cmd_getval(g_ceph_context, cmdmap, "srcname", srcname)) {
err = -EINVAL;
goto reply;
}
if (!cmd_getval(g_ceph_context, cmdmap, "dstname", dstname)) {
err = -EINVAL;
goto reply;
}
CrushWrapper newcrush;
_get_pending_crush(newcrush);
if (!newcrush.class_exists(srcname)) {
err = -ENOENT;
ss << "class '" << srcname << "' does not exist";
goto reply;
}
if (newcrush.class_exists(dstname)) {
err = -EEXIST;
ss << "class '" << dstname << "' already exists";
goto reply;
}
int class_id = newcrush.get_class_id(srcname);
if (newcrush.class_is_in_use(class_id)) {
err = -EBUSY;
ss << "class '" << srcname << "' is in use";
goto reply;
}
err = newcrush.rename_class(srcname, dstname);
if (err < 0) {
ss << "fail to rename '" << srcname << "' to '" << dstname << "':"
<< cpp_strerror(err);
goto reply;
}
pending_inc.crush.clear();
newcrush.encode(pending_inc.crush, mon->get_quorum_con_features());
ss << "rename class '" << srcname << "' to '" << dstname << "'";
goto update;
} else if (osdid_present &&
(prefix == "osd crush set" || prefix == "osd crush add")) {
@ -7414,6 +7460,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
int r = newcrush.swap_bucket(g_ceph_context, sid, did);
if (r < 0) {
ss << "failed to swap bucket contents: " << cpp_strerror(r);
err = r;
goto reply;
}
ss << "swapped bucket of " << source << " to " << dest;

View File

@ -135,6 +135,10 @@ function TEST_mon_classes() {
ceph osd crush class create CLASS || return 1
ceph osd crush class create CLASS || return 1 # idempotent
ceph osd crush class ls | grep CLASS || return 1
ceph osd crush class rename CLASS TEMP || return 1
ceph osd crush class ls | grep TEMP || return 1
ceph osd crush class rename TEMP CLASS || return 1
ceph osd crush class ls | grep CLASS || return 1
ceph osd crush class rm CLASS || return 1
expect_failure $dir ENOENT ceph osd crush class rm CLASS || return 1
}