Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

osd: 'osd tree in|out|up|down' to filter tree results #15294

Merged
merged 2 commits into from
May 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions qa/workunits/cephtool/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1312,6 +1312,19 @@ function test_mon_osd()
ceph osd unpause

ceph osd tree
ceph osd tree up
ceph osd tree down
ceph osd tree in
ceph osd tree out
ceph osd tree up in
ceph osd tree up out
ceph osd tree down in
ceph osd tree down out
ceph osd tree out down
expect_false ceph osd tree up down
expect_false ceph osd tree in out
expect_false ceph osd tree up foo

ceph osd perf
ceph osd blocked-by

Expand Down
31 changes: 28 additions & 3 deletions src/crush/CrushTreeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,31 @@ namespace CrushTreeDumper {
clear();
}

virtual bool should_dump_leaf(int i) const {
return true;
}
virtual bool should_dump_empty_bucket() const {
return true;
}

bool should_dump(int id) {
if (id >= 0)
return should_dump_leaf(id);
if (should_dump_empty_bucket())
return true;
int s = crush->get_bucket_size(id);
for (int k = s - 1; k >= 0; k--) {
int c = crush->get_bucket_item(id, k);
if (should_dump(c))
return true;
}
return false;
}

bool next(Item &qi) {
if (empty()) {
while (root != roots.end() && !should_dump(*root))
++root;
if (root == roots.end())
return false;
push_back(Item(*root, 0, crush->get_bucket_weightf(*root)));
Expand All @@ -93,9 +116,11 @@ namespace CrushTreeDumper {
int s = crush->get_bucket_size(qi.id);
for (int k = s - 1; k >= 0; k--) {
int id = crush->get_bucket_item(qi.id, k);
qi.children.push_back(id);
push_front(Item(id, qi.depth + 1,
crush->get_bucket_item_weightf(qi.id, k)));
if (should_dump(id)) {
qi.children.push_back(id);
push_front(Item(id, qi.depth + 1,
crush->get_bucket_item_weightf(qi.id, k)));
}
}
}
return true;
Expand Down
3 changes: 2 additions & 1 deletion src/mon/MonCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,8 @@ COMMAND("osd dump " \
"name=epoch,type=CephInt,range=0,req=false",
"print summary of OSD map", "osd", "r", "cli,rest")
COMMAND("osd tree " \
"name=epoch,type=CephInt,range=0,req=false", \
"name=epoch,type=CephInt,range=0,req=false " \
"name=states,type=CephChoices,strings=up|down|in|out,n=N,req=false", \
"print OSD tree", "osd", "r", "cli,rest")
COMMAND("osd ls " \
"name=epoch,type=CephInt,range=0,req=false", \
Expand Down
30 changes: 28 additions & 2 deletions src/mon/OSDMonitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4012,13 +4012,39 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op)
}
rdata.append(ds);
} else if (prefix == "osd tree") {
vector<string> states;
cmd_getval(g_ceph_context, cmdmap, "states", states);
unsigned filter = 0;
for (auto& s : states) {
if (s == "up") {
filter |= OSDMap::DUMP_UP;
} else if (s == "down") {
filter |= OSDMap::DUMP_DOWN;
} else if (s == "in") {
filter |= OSDMap::DUMP_IN;
} else if (s == "out") {
filter |= OSDMap::DUMP_OUT;
} else {
ss << "unrecognized state '" << s << "'";
r = -EINVAL;
goto reply;
}
}
if ((filter & (OSDMap::DUMP_IN|OSDMap::DUMP_OUT)) ==
(OSDMap::DUMP_IN|OSDMap::DUMP_OUT) ||
(filter & (OSDMap::DUMP_UP|OSDMap::DUMP_DOWN)) ==
(OSDMap::DUMP_UP|OSDMap::DUMP_DOWN)) {
ss << "cannot specify both up and down or both in and out";
r = -EINVAL;
goto reply;
}
if (f) {
f->open_object_section("tree");
p->print_tree(f.get(), NULL);
p->print_tree(f.get(), NULL, filter);
f->close_section();
f->flush(ds);
} else {
p->print_tree(NULL, &ds);
p->print_tree(NULL, &ds, filter);
}
rdata.append(ds);
} else if (prefix == "osd getmap") {
Expand Down
56 changes: 45 additions & 11 deletions src/osd/OSDMap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2849,8 +2849,24 @@ void OSDMap::print(ostream& out) const
class OSDTreePlainDumper : public CrushTreeDumper::Dumper<TextTable> {
public:
typedef CrushTreeDumper::Dumper<TextTable> Parent;
OSDTreePlainDumper(const CrushWrapper *crush, const OSDMap *osdmap_)
: Parent(crush), osdmap(osdmap_) {}

OSDTreePlainDumper(const CrushWrapper *crush, const OSDMap *osdmap_,
unsigned f)
: Parent(crush), osdmap(osdmap_), filter(f) { }

bool should_dump_leaf(int i) const override {
if (((filter & OSDMap::DUMP_UP) && !osdmap->is_up(i)) ||
((filter & OSDMap::DUMP_DOWN) && !osdmap->is_down(i)) ||
((filter & OSDMap::DUMP_IN) && !osdmap->is_in(i)) ||
((filter & OSDMap::DUMP_OUT) && !osdmap->is_out(i))) {
return false;
}
return true;
}

bool should_dump_empty_bucket() const override {
return !filter;
}

void dump(TextTable *tbl) {
tbl->define_column("ID", TextTable::LEFT, TextTable::RIGHT);
Expand All @@ -2863,8 +2879,9 @@ class OSDTreePlainDumper : public CrushTreeDumper::Dumper<TextTable> {
Parent::dump(tbl);

for (int i = 0; i < osdmap->get_max_osd(); i++) {
if (osdmap->exists(i) && !is_touched(i))
if (osdmap->exists(i) && !is_touched(i) && should_dump_leaf(i)) {
dump_item(CrushTreeDumper::Item(i, 0, 0), tbl);
}
}
}

Expand Down Expand Up @@ -2900,22 +2917,38 @@ class OSDTreePlainDumper : public CrushTreeDumper::Dumper<TextTable> {

private:
const OSDMap *osdmap;
const unsigned filter;
};

class OSDTreeFormattingDumper : public CrushTreeDumper::FormattingDumper {
public:
typedef CrushTreeDumper::FormattingDumper Parent;

OSDTreeFormattingDumper(const CrushWrapper *crush, const OSDMap *osdmap_)
: Parent(crush), osdmap(osdmap_) {}
OSDTreeFormattingDumper(const CrushWrapper *crush, const OSDMap *osdmap_,
unsigned f)
: Parent(crush), osdmap(osdmap_), filter(f) { }

bool should_dump_leaf(int i) const override {
if (((filter & OSDMap::DUMP_UP) && !osdmap->is_up(i)) ||
((filter & OSDMap::DUMP_DOWN) && !osdmap->is_down(i)) ||
((filter & OSDMap::DUMP_IN) && !osdmap->is_in(i)) ||
((filter & OSDMap::DUMP_OUT) && !osdmap->is_out(i))) {
return false;
}
return true;
}

bool should_dump_empty_bucket() const override {
return !filter;
}

void dump(Formatter *f) {
f->open_array_section("nodes");
Parent::dump(f);
f->close_section();
f->open_array_section("stray");
for (int i = 0; i < osdmap->get_max_osd(); i++) {
if (osdmap->exists(i) && !is_touched(i))
if (osdmap->exists(i) && !is_touched(i) && should_dump_leaf(i))
dump_item(CrushTreeDumper::Item(i, 0, 0), f);
}
f->close_section();
Expand All @@ -2935,16 +2968,17 @@ class OSDTreeFormattingDumper : public CrushTreeDumper::FormattingDumper {

private:
const OSDMap *osdmap;
const unsigned filter;
};

void OSDMap::print_tree(Formatter *f, ostream *out) const
void OSDMap::print_tree(Formatter *f, ostream *out, unsigned filter) const
{
if (f)
OSDTreeFormattingDumper(crush.get(), this).dump(f);
else {
if (f) {
OSDTreeFormattingDumper(crush.get(), this, filter).dump(f);
} else {
assert(out);
TextTable tbl;
OSDTreePlainDumper(crush.get(), this).dump(&tbl);
OSDTreePlainDumper(crush.get(), this, filter).dump(&tbl);
*out << tbl;
}
}
Expand Down
9 changes: 8 additions & 1 deletion src/osd/OSDMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,14 @@ class OSDMap {
void print_pools(ostream& out) const;
void print_summary(Formatter *f, ostream& out) const;
void print_oneline_summary(ostream& out) const;
void print_tree(Formatter *f, ostream *out) const;

enum {
DUMP_IN = 1, // only 'in' osds
DUMP_OUT = 2, // only 'out' osds
DUMP_UP = 4, // only 'up' osds
DUMP_DOWN = 8, // only 'down' osds
};
void print_tree(Formatter *f, ostream *out, unsigned dump_flags=0) const;

int summarize_mapping_stats(
OSDMap *newmap,
Expand Down
2 changes: 2 additions & 0 deletions src/test/mon/osd-crush.sh
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,10 @@ function TEST_crush_rename_bucket() {
run_mon $dir a || return 1

ceph osd crush add-bucket host1 host
ceph osd tree
! ceph osd tree | grep host2 || return 1
ceph osd crush rename-bucket host1 host2 || return 1
ceph osd tree
ceph osd tree | grep host2 || return 1
ceph osd crush rename-bucket host1 host2 || return 1 # idempotency
ceph osd crush rename-bucket nonexistent something 2>&1 | grep "Error ENOENT" || return 1
Expand Down