mirror of
https://github.com/ceph/ceph
synced 2025-03-11 02:39:05 +00:00
Merge pull request #4840 from tchaikov/wip-11833-crush-dump-tree
mon: add an "osd crush dump tree" command Reviewed-by: Min Chen <minchen@ubuntukylin.com> Reviewed-by: Haomai Wang <haomaiwang@gmail.com>
This commit is contained in:
commit
b097e70732
doc/man/8
src
@ -699,6 +699,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::
|
||||
|
@ -1456,6 +1456,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());
|
||||
|
@ -1060,6 +1060,7 @@ public:
|
||||
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,
|
||||
|
@ -531,6 +531,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")
|
||||
|
@ -3718,6 +3718,12 @@ stats_out:
|
||||
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();
|
||||
|
62
src/test/mon/osd-crush-tree.rng
Normal file
62
src/test/mon/osd-crush-tree.rng
Normal file
@ -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>
|
@ -218,6 +218,14 @@ function TEST_crush_reject_empty() {
|
||||
./ceph osd setcrushmap -i $empty_map.map || return 1
|
||||
}
|
||||
|
||||
function TEST_crush_tree() {
|
||||
local dir=$1
|
||||
run_mon $dir a || return 1
|
||||
|
||||
./ceph osd crush tree --format=xml | \
|
||||
$XMLSTARLET val -e -r test/mon/osd-crush-tree.rng - || return 1
|
||||
}
|
||||
|
||||
main osd-crush "$@"
|
||||
|
||||
# Local Variables:
|
||||
|
Loading…
Reference in New Issue
Block a user