From d2335fab5b69242acf3867b8f717db6cdd4aa67f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 21 Feb 2012 14:37:50 -0800 Subject: [PATCH] crush: write CrushWrapper:dump() Signed-off-by: Sage Weil --- src/crush/CrushWrapper.cc | 130 ++++++++++++++++++++++++++++++++++++++ src/crush/CrushWrapper.h | 39 +++++++----- src/test/encoding/types.h | 3 + 3 files changed, 156 insertions(+), 16 deletions(-) diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 60e78e512391d..7aacac1b48705 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -1,5 +1,6 @@ #include "common/debug.h" +#include "common/Formatter.h" #include "CrushWrapper.h" @@ -385,4 +386,133 @@ void CrushWrapper::decode_crush_bucket(crush_bucket** bptr, bufferlist::iterator } +void CrushWrapper::dump(Formatter *f) const +{ + f->open_array_section("devices"); + for (int i=0; iopen_object_section("device"); + f->dump_int("id", i); + const char *n = get_item_name(i); + if (n) { + f->dump_string("name", n); + } else { + char name[20]; + sprintf(name, "device%d", i); + f->dump_string("name", name); + } + f->close_section(); + } + f->close_section(); + + f->open_array_section("types"); + int n = get_num_type_names(); + for (int i=0; n; i++) { + const char *name = get_type_name(i); + if (!name) { + if (i == 0) { + f->open_object_section("type"); + f->dump_int("type_id", 0); + f->dump_string("name", "device"); + f->close_section(); + } + continue; + } + n--; + f->open_object_section("type"); + f->dump_int("type_id", i); + f->dump_string("name", name); + f->close_section(); + } + f->close_section(); + f->open_array_section("buckets"); + for (int bucket = -1; bucket > -1-get_max_buckets(); --bucket) { + if (!bucket_exists(bucket)) + continue; + f->open_object_section("bucket"); + f->dump_int("id", bucket); + if (get_item_name(bucket)) + f->dump_string("name", get_item_name(bucket)); + f->dump_int("type_id", get_bucket_type(bucket)); + if (get_type_name(get_bucket_type(bucket))) + f->dump_string("type_name", get_type_name(get_bucket_type(bucket))); + f->dump_int("weight", get_bucket_weight(bucket)); + f->dump_string("alg", crush_bucket_alg_name(get_bucket_alg(bucket))); + f->dump_string("hash", crush_hash_name(get_bucket_hash(bucket))); + f->open_array_section("items"); + for (int j=0; jopen_object_section("item"); + f->dump_int("id", get_bucket_item(bucket, j)); + f->dump_int("weight", get_bucket_item_weight(bucket, j)); + f->dump_int("pos", j); + f->close_section(); + } + f->close_section(); + f->close_section(); + } + f->close_section(); + + f->open_array_section("rules"); + for (int i=0; iopen_object_section("rule"); + f->dump_int("rule_id", i); + if (get_rule_name(i)) + f->dump_string("rule_name", get_rule_name(i)); + f->dump_int("ruleset", get_rule_mask_ruleset(i)); + f->dump_int("type", get_rule_mask_type(i)); + f->dump_int("min_size", get_rule_mask_min_size(i)); + f->dump_int("max_size", get_rule_mask_max_size(i)); + f->open_array_section("steps"); + for (int j=0; jopen_object_section("step"); + switch (get_rule_op(i, j)) { + case CRUSH_RULE_NOOP: + f->dump_string("op", "noop"); + break; + case CRUSH_RULE_TAKE: + f->dump_string("op", "take"); + f->dump_int("item", get_rule_arg1(i, j)); + break; + case CRUSH_RULE_EMIT: + f->dump_string("op", "emit"); + break; + case CRUSH_RULE_CHOOSE_FIRSTN: + f->dump_string("op", "choose_firstn"); + f->dump_int("num", get_rule_arg1(i, j)); + f->dump_string("type", get_type_name(get_rule_arg2(i, j))); + break; + case CRUSH_RULE_CHOOSE_INDEP: + f->dump_string("op", "choose_indep"); + f->dump_int("num", get_rule_arg1(i, j)); + f->dump_string("type", get_type_name(get_rule_arg2(i, j))); + break; + case CRUSH_RULE_CHOOSE_LEAF_FIRSTN: + f->dump_string("op", "chooseleaf_firstn"); + f->dump_int("num", get_rule_arg1(i, j)); + f->dump_string("type", get_type_name(get_rule_arg2(i, j))); + break; + case CRUSH_RULE_CHOOSE_LEAF_INDEP: + f->dump_string("op", "chooseleaf_indep"); + f->dump_int("num", get_rule_arg1(i, j)); + f->dump_string("type", get_type_name(get_rule_arg2(i, j))); + break; + default: + f->dump_int("opcode", get_rule_op(i, j)); + f->dump_int("arg1", get_rule_arg1(i, j)); + f->dump_int("arg2", get_rule_arg2(i, j)); + } + f->close_section(); + } + f->close_section(); + f->close_section(); + } + f->close_section(); +} + +void CrushWrapper::generate_test_instances(list& o) +{ + o.push_back(new CrushWrapper); + // fixme +} diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index e495815dca2e7..5376a78ffc9ad 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -24,6 +24,10 @@ extern "C" { #include //for testing, remove +namespace ceph { + class Formatter; +} + WRITE_RAW_ENCODER(crush_rule_mask) // it's all u8's inline static void encode(const crush_rule_step &s, bufferlist &bl) @@ -85,7 +89,7 @@ public: } // bucket types - int get_num_type_names() { + int get_num_type_names() const { return type_map.size(); } int get_type_id(const char *s) { @@ -145,9 +149,10 @@ public: return rule_name_rmap[name]; return 0; /* hrm */ } - const char *get_rule_name(int t) { - if (rule_name_map.count(t)) - return rule_name_map[t].c_str(); + const char *get_rule_name(int t) const { + std::map::const_iterator p = rule_name_map.find(t); + if (p != rule_name_map.end()) + return p->second.c_str(); return 0; } void set_rule_name(int i, const char *n) { @@ -177,13 +182,13 @@ public: /*** rules ***/ private: - crush_rule *get_rule(unsigned ruleno) { + crush_rule *get_rule(unsigned ruleno) const { if (!crush) return (crush_rule *)(-ENOENT); if (ruleno >= crush->max_rules) return 0; return crush->rules[ruleno]; } - crush_rule_step *get_rule_step(unsigned ruleno, unsigned step) { + crush_rule_step *get_rule_step(unsigned ruleno, unsigned step) const { crush_rule *n = get_rule(ruleno); if (!n) return (crush_rule_step *)(-EINVAL); if (step >= n->len) return (crush_rule_step *)(-EINVAL); @@ -192,53 +197,53 @@ private: public: /* accessors */ - int get_max_rules() { + int get_max_rules() const { if (!crush) return 0; return crush->max_rules; } - bool rule_exists(unsigned ruleno) { + bool rule_exists(unsigned ruleno) const { if (!crush) return false; if (ruleno < crush->max_rules && crush->rules[ruleno] != NULL) return true; return false; } - int get_rule_len(unsigned ruleno) { + int get_rule_len(unsigned ruleno) const { crush_rule *r = get_rule(ruleno); if (IS_ERR(r)) return PTR_ERR(r); return r->len; } - int get_rule_mask_ruleset(unsigned ruleno) { + int get_rule_mask_ruleset(unsigned ruleno) const { crush_rule *r = get_rule(ruleno); if (IS_ERR(r)) return -1; return r->mask.ruleset; } - int get_rule_mask_type(unsigned ruleno) { + int get_rule_mask_type(unsigned ruleno) const { crush_rule *r = get_rule(ruleno); if (IS_ERR(r)) return -1; return r->mask.type; } - int get_rule_mask_min_size(unsigned ruleno) { + int get_rule_mask_min_size(unsigned ruleno) const { crush_rule *r = get_rule(ruleno); if (IS_ERR(r)) return -1; return r->mask.min_size; } - int get_rule_mask_max_size(unsigned ruleno) { + int get_rule_mask_max_size(unsigned ruleno) const { crush_rule *r = get_rule(ruleno); if (IS_ERR(r)) return -1; return r->mask.max_size; } - int get_rule_op(unsigned ruleno, unsigned step) { + int get_rule_op(unsigned ruleno, unsigned step) const { crush_rule_step *s = get_rule_step(ruleno, step); if (IS_ERR(s)) return PTR_ERR(s); return s->op; } - int get_rule_arg1(unsigned ruleno, unsigned step) { + int get_rule_arg1(unsigned ruleno, unsigned step) const { crush_rule_step *s = get_rule_step(ruleno, step); if (IS_ERR(s)) return PTR_ERR(s); return s->arg1; } - int get_rule_arg2(unsigned ruleno, unsigned step) { + int get_rule_arg2(unsigned ruleno, unsigned step) const { crush_rule_step *s = get_rule_step(ruleno, step); if (IS_ERR(s)) return PTR_ERR(s); return s->arg2; @@ -414,6 +419,8 @@ public: void encode(bufferlist &bl, bool lean=false) const; void decode(bufferlist::iterator &blp); void decode_crush_bucket(crush_bucket** bptr, bufferlist::iterator &blp); + void dump(Formatter *f) const; + static void generate_test_instances(list& o); }; WRITE_CLASS_ENCODER(CrushWrapper) diff --git a/src/test/encoding/types.h b/src/test/encoding/types.h index 9970f76dec3b8..1d5587f0a4ab4 100644 --- a/src/test/encoding/types.h +++ b/src/test/encoding/types.h @@ -21,6 +21,9 @@ TYPE(entity_addr_t) TYPE(osd_info_t) TYPE(OSDMap) +#include "crush/CrushWrapper.h" +TYPE(CrushWrapper) + #include "osd/PG.h" TYPE(PG::Interval) TYPE(PG::OndiskLog) -- 2.39.5