out << "tunable choose_local_fallback_tries " << crush.get_choose_local_fallback_tries() << "\n";
if (crush.get_choose_total_tries() != 19)
out << "tunable choose_total_tries " << crush.get_choose_total_tries() << "\n";
+ if (crush.get_chooseleaf_descend_once() != 0)
+ out << "tunable chooseleaf_descend_once " << crush.get_chooseleaf_descend_once() << "\n";
out << "\n# devices\n";
for (int i=0; i<crush.get_max_devices(); i++) {
crush.set_choose_local_fallback_tries(val);
else if (name == "choose_total_tries")
crush.set_choose_total_tries(val);
+ else if (name == "chooseleaf_descend_once")
+ crush.set_chooseleaf_descend_once(val);
else {
err << "tunable " << name << " not recognized" << std::endl;
return -1;
::encode(crush->choose_local_tries, bl);
::encode(crush->choose_local_fallback_tries, bl);
::encode(crush->choose_total_tries, bl);
+ ::encode(crush->chooseleaf_descend_once, bl);
}
static void decode_32_or_64_string_map(map<int32_t,string>& m, bufferlist::iterator& blp)
::decode(crush->choose_local_fallback_tries, blp);
::decode(crush->choose_total_tries, blp);
}
+ if (!blp.end()) {
+ ::decode(crush->chooseleaf_descend_once, blp);
+ }
finalize();
}
catch (...) {
crush->choose_total_tries = n;
}
+ int get_chooseleaf_descend_once() {
+ return crush->chooseleaf_descend_once;
+ }
+ void set_chooseleaf_descend_once(int n) {
+ crush->chooseleaf_descend_once = !!n;
+ }
+
bool has_nondefault_tunables() const {
return
(crush->choose_local_tries != 2 ||
m->choose_local_tries = 2;
m->choose_local_fallback_tries = 5;
m->choose_total_tries = 19;
+ m->chooseleaf_descend_once = 0;
return m;
}
__u32 choose_local_fallback_tries;
/* choose attempts before giving up */
__u32 choose_total_tries;
+ /* attempt chooseleaf inner descent once; on failure retry outer descent */
+ __u32 chooseleaf_descend_once;
__u32 *choose_tries;
};
* @param out pointer to output vector
* @param outpos our position in that vector
* @param firstn true if choosing "first n" items, false if choosing "indep"
- * @param recurseto_leaf: true if we want one device under each item of given type
+ * @param recurse_to_leaf: true if we want one device under each item of given type
+ * @descend_once: true if we should only try one descent before giving up
* @param out2 second output vector for leaf items (if @a recurse_to_leaf)
*/
static int crush_choose(const struct crush_map *map,
int x, int numrep, int type,
int *out, int outpos,
int firstn, int recurse_to_leaf,
- int *out2)
+ int descend_once, int *out2)
{
int rep;
unsigned int ftotal, flocal;
x, outpos+1, 0,
out2, outpos,
firstn, 0,
+ map->chooseleaf_descend_once,
NULL) <= outpos)
/* didn't get leaf */
reject = 1;
ftotal++;
flocal++;
- if (collide && flocal <= map->choose_local_tries)
+ if (reject && descend_once)
+ /* let outer call try again */
+ skip_rep = 1;
+ else if (collide && flocal <= map->choose_local_tries)
/* retry locally a few times */
retry_bucket = 1;
else if (map->choose_local_fallback_tries > 0 &&
int i, j;
int numrep;
int firstn;
+ const int descend_once = 0;
if ((__u32)ruleno >= map->max_rules) {
dprintk(" bad ruleno %d\n", ruleno);
curstep->arg2,
o+osize, j,
firstn,
- recurse_to_leaf, c+osize);
+ recurse_to_leaf,
+ descend_once, c+osize);
}
if (recurse_to_leaf)
int choose_local_tries = -1;
int choose_local_fallback_tries = -1;
int choose_total_tries = -1;
+ int chooseleaf_descend_once = -1;
CrushWrapper crush;
} else if (ceph_argparse_withint(args, i, &choose_total_tries, &err,
"--set_choose_total_tries", (char*)NULL)) {
adjust = true;
+ } else if (ceph_argparse_withint(args, i, &chooseleaf_descend_once, &err,
+ "--set_chooseleaf_descend_once", (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_choose_total_tries(choose_total_tries);
modified = true;
}
+ if (chooseleaf_descend_once >= 0) {
+ if (!unsafe_tunables) {
+ cerr << scary_tunables_message << std::endl;
+ return -1;
+ }
+ crush.set_chooseleaf_descend_once(chooseleaf_descend_once);
+ modified = true;
+ }
if (modified) {
crush.finalize();