::encode(crush->chooseleaf_descend_once, bl);
::encode(crush->chooseleaf_vary_r, bl);
::encode(crush->straw_calc_version, bl);
+ ::encode(crush->allowed_bucket_algs, bl);
}
static void decode_32_or_64_string_map(map<int32_t,string>& m, bufferlist::iterator& blp)
if (!blp.end()) {
::decode(crush->straw_calc_version, blp);
}
+ if (!blp.end()) {
+ ::decode(crush->allowed_bucket_algs, blp);
+ }
finalize();
}
catch (...) {
f->dump_int("chooseleaf_descend_once", get_chooseleaf_descend_once());
f->dump_int("chooseleaf_vary_r", get_chooseleaf_vary_r());
f->dump_int("straw_calc_version", get_straw_calc_version());
+ f->dump_int("allowed_bucket_algs", get_allowed_bucket_algs());
// be helpful about it
if (has_firefly_tunables())
crush->choose_total_tries = 19;
crush->chooseleaf_descend_once = 0;
crush->chooseleaf_vary_r = 0;
+ crush->allowed_bucket_algs = CRUSH_LEGACY_ALLOWED_BUCKET_ALGS;
}
void set_tunables_bobtail() {
crush->choose_local_tries = 0;
crush->choose_total_tries = 50;
crush->chooseleaf_descend_once = 1;
crush->chooseleaf_vary_r = 0;
+ crush->allowed_bucket_algs = CRUSH_LEGACY_ALLOWED_BUCKET_ALGS;
}
void set_tunables_firefly() {
crush->choose_local_tries = 0;
crush->choose_total_tries = 50;
crush->chooseleaf_descend_once = 1;
crush->chooseleaf_vary_r = 1;
+ crush->allowed_bucket_algs = CRUSH_LEGACY_ALLOWED_BUCKET_ALGS;
}
void set_tunables_hammer() {
crush->choose_local_tries = 0;
crush->choose_total_tries = 50;
crush->chooseleaf_descend_once = 1;
crush->chooseleaf_vary_r = 1;
+ crush->allowed_bucket_algs =
+ (1 << CRUSH_BUCKET_UNIFORM) |
+ (1 << CRUSH_BUCKET_LIST) |
+ (1 << CRUSH_BUCKET_STRAW) |
+ (1 << CRUSH_BUCKET_STRAW2);
}
void set_tunables_legacy() {
crush->straw_calc_version = n;
}
+ unsigned get_allowed_bucket_algs() const {
+ return crush->allowed_bucket_algs;
+ }
+ void set_allowed_bucket_algs(unsigned n) {
+ crush->allowed_bucket_algs = n;
+ }
+
bool has_argonaut_tunables() const {
return
crush->choose_local_tries == 2 &&
crush->choose_total_tries == 19 &&
crush->chooseleaf_descend_once == 0 &&
crush->chooseleaf_vary_r == 0 &&
- crush->straw_calc_version == 0;
+ crush->straw_calc_version == 0 &&
+ crush->allowed_bucket_algs == CRUSH_LEGACY_ALLOWED_BUCKET_ALGS;
}
bool has_bobtail_tunables() const {
return
crush->choose_total_tries == 50 &&
crush->chooseleaf_descend_once == 1 &&
crush->chooseleaf_vary_r == 0 &&
- crush->straw_calc_version == 0;
+ crush->straw_calc_version == 0 &&
+ crush->allowed_bucket_algs == CRUSH_LEGACY_ALLOWED_BUCKET_ALGS;
}
bool has_firefly_tunables() const {
return
crush->choose_total_tries == 50 &&
crush->chooseleaf_descend_once == 1 &&
crush->chooseleaf_vary_r == 1 &&
- crush->straw_calc_version == 0;
+ crush->straw_calc_version == 0 &&
+ crush->allowed_bucket_algs == CRUSH_LEGACY_ALLOWED_BUCKET_ALGS;
}
bool has_hammer_tunables() const {
return
crush->choose_total_tries == 50 &&
crush->chooseleaf_descend_once == 1 &&
crush->chooseleaf_vary_r == 1 &&
- crush->straw_calc_version == 1;
- }
+ crush->straw_calc_version == 1 &&
+ crush->allowed_bucket_algs == ((1 << CRUSH_BUCKET_UNIFORM) |
+ (1 << CRUSH_BUCKET_LIST) |
+ (1 << CRUSH_BUCKET_STRAW) |
+ (1 << CRUSH_BUCKET_STRAW2));
+}
bool has_optimal_tunables() const {
return has_firefly_tunables();
// default bucket types
unsigned get_default_bucket_alg() const {
- return CRUSH_BUCKET_STRAW;
+ // in order of preference
+ if (crush->allowed_bucket_algs & (1 << CRUSH_BUCKET_STRAW2))
+ return CRUSH_BUCKET_STRAW2;
+ if (crush->allowed_bucket_algs & (1 << CRUSH_BUCKET_STRAW))
+ return CRUSH_BUCKET_STRAW;
+ if (crush->allowed_bucket_algs & (1 << CRUSH_BUCKET_TREE))
+ return CRUSH_BUCKET_TREE;
+ if (crush->allowed_bucket_algs & (1 << CRUSH_BUCKET_LIST))
+ return CRUSH_BUCKET_LIST;
+ if (crush->allowed_bucket_algs & (1 << CRUSH_BUCKET_UNIFORM))
+ return CRUSH_BUCKET_UNIFORM;
+ return 0;
}
// bucket types
};
extern const char *crush_bucket_alg_name(int alg);
+/*
+ * although tree was a legacy algorithm, it has been buggy, so
+ * exclude it.
+ */
+#define CRUSH_LEGACY_ALLOWED_BUCKET_ALGS ( \
+ (1 << CRUSH_BUCKET_UNIFORM) | \
+ (1 << CRUSH_BUCKET_LIST) | \
+ (1 << CRUSH_BUCKET_STRAW))
+
struct crush_bucket {
__s32 id; /* this'll be negative */
__u16 type; /* non-zero; type=0 is reserved for devices */
*/
__u8 straw_calc_version;
+ /*
+ * allowed bucket algs is a bitmask, here the bit positions
+ * are CRUSH_BUCKET_*. note that these are *bits* and
+ * CRUSH_BUCKET_* values are not, so we need to or together (1
+ * << CRUSH_BUCKET_WHATEVER). The 0th bit is not used to
+ * minimize confusion (bucket type values start at 1).
+ */
+ __u32 allowed_bucket_algs;
+
__u32 *choose_tries;
};
int chooseleaf_descend_once = -1;
int chooseleaf_vary_r = -1;
int straw_calc_version = -1;
+ int allowed_bucket_algs = -1;
CrushWrapper crush;
} else if (ceph_argparse_withint(args, i, &straw_calc_version, &err,
"--set_straw_calc_version", (char*)NULL)) {
adjust = true;
+ } else if (ceph_argparse_withint(args, i, &allowed_bucket_algs, &err,
+ "--set_allowed_bucket_algs", (char*)NULL)) {
+ adjust = true;
} else if (ceph_argparse_flag(args, i, "--reweight", (char*)NULL)) {
reweight = true;
} else if (ceph_argparse_withint(args, i, &add_item, &err, "--add_item", (char*)NULL)) {
crush.set_straw_calc_version(straw_calc_version);
modified = true;
}
+ if (allowed_bucket_algs >= 0) {
+ crush.set_allowed_bucket_algs(allowed_bucket_algs);
+ modified = true;
+ }
if (modified) {
crush.finalize();