]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/crush/CrushWrapper.cc
update sources to v12.2.0
[ceph.git] / ceph / src / crush / CrushWrapper.cc
index 76c6afe60a5ce32535af0c088f30f4d2a0d86998..bf6f3cf5ab8d69aa7bea8ad4562d0a1093102b9b 100644 (file)
@@ -291,6 +291,33 @@ int CrushWrapper::rename_bucket(const string& srcname,
   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++) {
@@ -1075,7 +1102,7 @@ int CrushWrapper::swap_bucket(CephContext *cct, int src, int dst)
 
   // swap names
   swap_names(src, dst);
-  return 0;
+  return rebuild_roots_with_classes();
 }
 
 int CrushWrapper::link_bucket(
@@ -1667,7 +1694,7 @@ int CrushWrapper::remove_rule(int ruleno)
   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)
@@ -1678,8 +1705,8 @@ int CrushWrapper::bucket_adjust_item_weight(CephContext *cct, crush_bucket *buck
       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];
@@ -1702,26 +1729,30 @@ int CrushWrapper::add_bucket(
   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;
@@ -1744,8 +1775,8 @@ int CrushWrapper::bucket_add_item(crush_bucket *bucket, int item, int weight)
   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];
@@ -1777,8 +1808,8 @@ int CrushWrapper::bucket_remove_item(crush_bucket *bucket, int item)
   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];
@@ -1960,8 +1991,10 @@ int CrushWrapper::device_class_clone(
       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];
@@ -1990,6 +2023,37 @@ int CrushWrapper::device_class_clone(
   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) {
@@ -2299,7 +2363,7 @@ void CrushWrapper::decode(bufferlist::iterator& blp)
       __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;