Skip to content

Commit

Permalink
mon: add an "osd crush tree" command
Browse files Browse the repository at this point in the history
* to print crush buckets/items in a tree

Fixes: #11833
Signed-off-by: Kefu Chai <kchai@redhat.com>
(cherry picked from commit 5436c29)

Conflicts:
	src/test/mon/osd-crush.sh:
		do not start mon as run() takes care of it already
  • Loading branch information
tchaikov committed Jul 15, 2015
1 parent 9a79e8e commit 89aa8ff
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 1 deletion.
6 changes: 6 additions & 0 deletions doc/man/8/ceph.rst
Expand Up @@ -669,6 +669,12 @@ Usage::

ceph osd crush show-tunables

Subcommand ``tree`` shows the crush buckets and items in a tree view.

Usage::

ceph osd crush tree

Subcommand ``tunables`` sets crush tunables values to <profile>.

Usage::
Expand Down
50 changes: 50 additions & 0 deletions src/crush/CrushWrapper.cc
Expand Up @@ -1409,6 +1409,56 @@ void CrushWrapper::dump(Formatter *f) const
f->close_section();
}

namespace {
// depth first walker
class TreeDumper {
typedef CrushTreeDumper::Item Item;
const CrushWrapper *crush;
public:
TreeDumper(const CrushWrapper *crush)
: crush(crush) {}

void dump(Formatter *f) {
set<int> roots;
crush->find_roots(roots);
for (set<int>::iterator root = roots.begin(); root != roots.end(); ++root) {
dump_item(Item(*root, 0, crush->get_bucket_weightf(*root)), f);
}
}

private:
void dump_item(const Item& qi, Formatter* f) {
if (qi.is_bucket()) {
f->open_object_section("bucket");
CrushTreeDumper::dump_item_fields(crush, qi, f);
dump_bucket_children(qi, f);
f->close_section();
} else {
f->open_object_section("device");
CrushTreeDumper::dump_item_fields(crush, qi, f);
f->close_section();
}
}

void dump_bucket_children(const Item& parent, Formatter* f) {
f->open_array_section("items");
const int max_pos = crush->get_bucket_size(parent.id);
for (int pos = 0; pos < max_pos; pos++) {
int id = crush->get_bucket_item(parent.id, pos);
float weight = crush->get_bucket_item_weightf(parent.id, pos);
dump_item(Item(id, parent.depth + 1, weight), f);
}
f->close_section();
}
};
}

void CrushWrapper::dump_tree(Formatter *f) const
{
assert(f);
TreeDumper(this).dump(f);
}

void CrushWrapper::dump_tunables(Formatter *f) const
{
f->dump_int("choose_local_tries", get_choose_local_tries());
Expand Down
1 change: 1 addition & 0 deletions src/crush/CrushWrapper.h
Expand Up @@ -1054,6 +1054,7 @@ class CrushWrapper {
void dump_tunables(Formatter *f) const;
void list_rules(Formatter *f) const;
void dump_tree(ostream *out, Formatter *f) const;
void dump_tree(Formatter *f) const;
static void generate_test_instances(list<CrushWrapper*>& o);

int get_osd_pool_default_crush_replicated_ruleset(CephContext *cct);
Expand Down
3 changes: 3 additions & 0 deletions src/mon/MonCommands.h
Expand Up @@ -521,6 +521,9 @@ COMMAND("osd crush rule create-erasure " \
COMMAND("osd crush rule rm " \
"name=name,type=CephString,goodchars=[A-Za-z0-9-_.] ", \
"remove crush rule <name>", "osd", "rw", "cli,rest")
COMMAND("osd crush tree",
"dump crush buckets and items in a tree view",
"osd", "r", "cli,rest")
COMMAND("osd setmaxosd " \
"name=newmax,type=CephInt,range=0", \
"set new maximum osd value", "osd", "rw", "cli,rest")
Expand Down
6 changes: 6 additions & 0 deletions src/mon/OSDMonitor.cc
Expand Up @@ -3367,6 +3367,12 @@ bool OSDMonitor::preprocess_command(MMonCommand *m)
f->flush(rs);
rs << "\n";
rdata.append(rs.str());
} else if (prefix == "osd crush tree") {
boost::scoped_ptr<Formatter> f(Formatter::create(format, "json-pretty", "json-pretty"));
f->open_array_section("crush_map_roots");
osdmap.crush->dump_tree(f.get());
f->close_section();
f->flush(rdata);
} else if (prefix == "osd erasure-code-profile ls") {
const map<string,map<string,string> > &profiles =
osdmap.get_erasure_code_profiles();
Expand Down
62 changes: 62 additions & 0 deletions src/test/mon/osd-crush-tree.rng
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<ref name="crush_map_roots"/>
</start>
<define name="item">
<choice>
<ref name="bucket"/>
<ref name="device"/>
</choice>
</define>
<define name="device">
<element name="device">
<element name="id">
<text/>
</element>
<element name="name">
<text/>
</element>
<element name="type">
<text/>
</element>
<element name="type_id">
<text/>
</element>
<element name="crush_weight">
<text/>
</element>
<element name="depth">
<text/>
</element>
</element>
</define>
<define name="bucket">
<element name="bucket">
<element name="id">
<text/>
</element>
<element name="name">
<text/>
</element>
<element name="type">
<text/>
</element>
<element name="type_id">
<text/>
</element>
<element name="items">
<zeroOrMore>
<ref name="item"/>
</zeroOrMore>
</element>
</element>
</define>
<define name="crush_map_roots">
<element name="crush_map_roots">
<oneOrMore>
<ref name="bucket"/>
</oneOrMore>
</element>
</define>
</grammar>
7 changes: 6 additions & 1 deletion src/test/mon/osd-crush.sh
Expand Up @@ -200,7 +200,12 @@ function TEST_crush_reject_empty() {
./ceph osd setcrushmap -i $empty_map.map || return 1
}

main osd-crush
function TEST_crush_tree() {
./ceph osd crush tree --format=xml | \
$XMLSTARLET val -e -r test/mon/osd-crush-tree.rng - || return 1
}

main osd-crush

# Local Variables:
# compile-command: "cd ../.. ; make -j4 && test/mon/osd-crush.sh"
Expand Down

0 comments on commit 89aa8ff

Please sign in to comment.