return set_item_name(oldid, dstname);
}
+int CrushWrapper::rename_rule(const string& srcname,
+ const string& dstname,
+ ostream *ss)
+{
+ if (!rule_exists(srcname)) {
+ if (ss) {
+ *ss << "source rule name '" << srcname << "' does not exist";
+ }
+ return -ENOENT;
+ }
+ if (rule_exists(dstname)) {
+ if (ss) {
+ *ss << "destination rule name '" << dstname << "' already exists";
+ }
+ return -EEXIST;
+ }
+ int rule_id = get_rule_id(srcname);
+ auto it = rule_name_map.find(rule_id);
+ assert(it != rule_name_map.end());
+ it->second = dstname;
+ if (have_rmaps) {
+ rule_name_rmap.erase(srcname);
+ rule_name_rmap[dstname] = rule_id;
+ }
+ return 0;
+}
+
void CrushWrapper::find_takes(set<int>& roots) const
{
for (unsigned i=0; i<crush->max_rules; i++) {
// swap names
swap_names(src, dst);
- return 0;
+ return rebuild_roots_with_classes();
}
int CrushWrapper::link_bucket(
crush->rules[ruleno] = NULL;
rule_name_map.erase(ruleno);
have_rmaps = false;
- return 0;
+ return rebuild_roots_with_classes();
}
int CrushWrapper::bucket_adjust_item_weight(CephContext *cct, crush_bucket *bucket, int item, int weight)
if (bucket->items[position] == item)
break;
assert(position != bucket->size);
- for (auto w : choose_args) {
- crush_choose_arg_map arg_map = w.second;
+ for (auto &w : choose_args) {
+ crush_choose_arg_map &arg_map = w.second;
crush_choose_arg *arg = &arg_map.args[-1-bucket->id];
for (__u32 j = 0; j < arg->weight_set_size; j++) {
crush_weight_set *weight_set = &arg->weight_set[j];
crush_bucket *b = crush_make_bucket(crush, alg, hash, type, size, items,
weights);
assert(b);
+ assert(idout);
int r = crush_add_bucket(crush, bucketno, b, idout);
+ int pos = -1 - *idout;
for (auto& p : choose_args) {
crush_choose_arg_map& cmap = p.second;
if (cmap.args) {
- if ((int)cmap.size <= *idout) {
+ if ((int)cmap.size <= pos) {
cmap.args = (crush_choose_arg*)realloc(
cmap.args,
- sizeof(crush_choose_arg) * (*idout + 1));
+ sizeof(crush_choose_arg) * (pos + 1));
+ assert(cmap.args);
memset(&cmap.args[cmap.size], 0,
- sizeof(crush_choose_arg) * (*idout + 1 - cmap.size));
- cmap.size = *idout + 1;
+ sizeof(crush_choose_arg) * (pos + 1 - cmap.size));
+ cmap.size = pos + 1;
}
} else {
cmap.args = (crush_choose_arg*)calloc(sizeof(crush_choose_arg),
- *idout + 1);
- cmap.size = *idout + 1;
+ pos + 1);
+ assert(cmap.args);
+ cmap.size = pos + 1;
}
if (size > 0) {
int positions = get_choose_args_positions(cmap);
- crush_choose_arg& carg = cmap.args[*idout];
+ crush_choose_arg& carg = cmap.args[pos];
carg.weight_set = (crush_weight_set*)calloc(sizeof(crush_weight_set),
size);
carg.weight_set_size = positions;
if (r < 0) {
return r;
}
- for (auto w : choose_args) {
- crush_choose_arg_map arg_map = w.second;
+ for (auto &w : choose_args) {
+ crush_choose_arg_map &arg_map = w.second;
crush_choose_arg *arg = &arg_map.args[-1-bucket->id];
for (__u32 j = 0; j < arg->weight_set_size; j++) {
crush_weight_set *weight_set = &arg->weight_set[j];
if (r < 0) {
return r;
}
- for (auto w : choose_args) {
- crush_choose_arg_map arg_map = w.second;
+ for (auto &w : choose_args) {
+ crush_choose_arg_map &arg_map = w.second;
crush_choose_arg *arg = &arg_map.args[-1-bucket->id];
for (__u32 j = 0; j < arg->weight_set_size; j++) {
crush_weight_set *weight_set = &arg->weight_set[j];
unsigned new_size = -1-bno + 1;
cmap.args = (crush_choose_arg*)realloc(cmap.args,
new_size * sizeof(cmap.args[0]));
+ assert(cmap.args);
memset(cmap.args + cmap.size, 0,
(new_size - cmap.size) * sizeof(cmap.args[0]));
+ cmap.size = new_size;
}
auto& o = cmap.args[-1-original_id];
auto& n = cmap.args[-1-bno];
return 0;
}
+int CrushWrapper::get_rules_by_class(const string &class_name, set<int> *rules)
+{
+ assert(rules);
+ rules->clear();
+ if (!class_exists(class_name)) {
+ return -ENOENT;
+ }
+ int class_id = get_class_id(class_name);
+ for (unsigned i = 0; i < crush->max_rules; ++i) {
+ crush_rule *r = crush->rules[i];
+ if (!r)
+ continue;
+ for (unsigned j = 0; j < r->len; ++j) {
+ if (r->steps[j].op == CRUSH_RULE_TAKE) {
+ int step_item = r->steps[j].arg1;
+ int original_item;
+ int c;
+ int res = split_id_class(step_item, &original_item, &c);
+ if (res < 0) {
+ return res;
+ }
+ if (c != -1 && c == class_id) {
+ rules->insert(i);
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
bool CrushWrapper::_class_is_dead(int class_id)
{
for (auto &p: class_map) {
__u32 choose_args_size;
::decode(choose_args_size, blp);
for (__u32 i = 0; i < choose_args_size; i++) {
- uint64_t choose_args_index;
+ typename decltype(choose_args)::key_type choose_args_index;
::decode(choose_args_index, blp);
crush_choose_arg_map arg_map;
arg_map.size = crush->max_buckets;