Skip to content

Commit

Permalink
crush, mon: "ceph osd crush rule ls-by-class" support
Browse files Browse the repository at this point in the history
This command returns all crush rules that are currently
referencing a device class specified by user.

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
  • Loading branch information
xiexingguo committed Aug 17, 2017
1 parent a5075ed commit 83fa035
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 0 deletions.
4 changes: 4 additions & 0 deletions qa/workunits/mon/crush_ops.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ ceph osd crush set-device-class ssd osd.0
ceph osd crush set-device-class hdd osd.1
ceph osd crush rule create-replicated foo-ssd default host ssd
ceph osd crush rule create-replicated foo-hdd default host hdd
ceph osd crush rule ls-by-class ssd | grep 'foo-ssd'
ceph osd crush rule ls-by-class ssd | expect_false grep 'foo-hdd'
ceph osd crush rule ls-by-class hdd | grep 'foo-hdd'
ceph osd crush rule ls-by-class hdd | expect_false grep 'foo-ssd'

ceph osd erasure-code-profile set ec-foo-ssd crush-device-class=ssd m=2 k=2
ceph osd pool create ec-foo 2 erasure ec-foo-ssd
Expand Down
31 changes: 31 additions & 0 deletions src/crush/CrushWrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2017,6 +2017,37 @@ int CrushWrapper::device_class_clone(
return 0;
}

int CrushWrapper::get_rules_by_class(const string &class_name, set<int> *rules)
{
assert(rules);
rules->clear();
if (!class_exists(class_name)) {
return -ENOENT;
}
int class_id = get_class_id(class_name);
for (unsigned i = 0; i < crush->max_rules; ++i) {
crush_rule *r = crush->rules[i];
if (!r)
continue;
for (unsigned j = 0; j < r->len; ++j) {
if (r->steps[j].op == CRUSH_RULE_TAKE) {
int step_item = r->steps[j].arg1;
int original_item;
int c;
int res = split_id_class(step_item, &original_item, &c);
if (res < 0) {
return res;
}
if (c != -1 && c == class_id) {
rules->insert(i);
break;
}
}
}
}
return 0;
}

bool CrushWrapper::_class_is_dead(int class_id)
{
for (auto &p: class_map) {
Expand Down
1 change: 1 addition & 0 deletions src/crush/CrushWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,7 @@ class CrushWrapper {
int rename_class(const string& srcname, const string& dstname);
int populate_classes(
const std::map<int32_t, map<int32_t, int32_t>>& old_class_bucket);
int get_rules_by_class(const string &class_name, set<int> *rules);
bool _class_is_dead(int class_id);
void cleanup_dead_classes();
int rebuild_roots_with_classes();
Expand Down
4 changes: 4 additions & 0 deletions src/mon/MonCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,10 @@ COMMAND("osd lspools " \
COMMAND_WITH_FLAG("osd crush rule list", "list crush rules", "osd", "r", "cli,rest",
FLAG(DEPRECATED))
COMMAND("osd crush rule ls", "list crush rules", "osd", "r", "cli,rest")
COMMAND("osd crush rule ls-by-class " \
"name=class,type=CephString,goodchars=[A-Za-z0-9-_.],req=false", \
"list all crush rules that reference the same <class>", \
"osd", "r", "cli,rest")
COMMAND("osd crush rule dump " \
"name=name,type=CephString,goodchars=[A-Za-z0-9-_.],req=false", \
"dump crush rule <name> (default all)", \
Expand Down
28 changes: 28 additions & 0 deletions src/mon/OSDMonitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4923,6 +4923,34 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op)
osdmap.crush->list_rules(&ss);
rdata.append(ss.str());
}
} else if (prefix == "osd crush rule ls-by-class") {
string class_name;
cmd_getval(g_ceph_context, cmdmap, "class", class_name);
if (class_name.empty()) {
ss << "no class specified";
r = -EINVAL;
goto reply;
}
set<int> rules;
r = osdmap.crush->get_rules_by_class(class_name, &rules);
if (r < 0) {
ss << "failed to get rules by class '" << class_name << "'";
goto reply;
}
if (f) {
f->open_array_section("rules");
for (auto &rule: rules) {
f->dump_string("name", osdmap.crush->get_rule_name(rule));
}
f->close_section();
f->flush(rdata);
} else {
ostringstream rs;
for (auto &rule: rules) {
rs << osdmap.crush->get_rule_name(rule) << "\n";
}
rdata.append(rs.str());
}
} else if (prefix == "osd crush rule dump") {
string name;
cmd_getval(g_ceph_context, cmdmap, "name", name);
Expand Down

0 comments on commit 83fa035

Please sign in to comment.