]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crush, mon: "ceph osd crush rule ls-by-class" support 17260/head
authorxie xingguo <xie.xingguo@zte.com.cn>
Thu, 17 Aug 2017 02:34:26 +0000 (10:34 +0800)
committerSage Weil <sage@redhat.com>
Fri, 25 Aug 2017 15:22:19 +0000 (11:22 -0400)
This command returns all crush rules that are currently
referencing the device class specified by user.

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
(cherry picked from commit 7c67f95201316a240c7cdf1d8619b7642ff8fc33)

qa/workunits/mon/crush_ops.sh
src/crush/CrushWrapper.cc
src/crush/CrushWrapper.h
src/mon/MonCommands.h
src/mon/OSDMonitor.cc

index 41e7d10882f525b07e18b805823d3ad8704c0c7a..44bc70f4e923b983d1ba19362d0f65ae77f55e6b 100755 (executable)
@@ -26,6 +26,10 @@ ceph osd crush set-device-class ssd osd.0
 ceph osd crush set-device-class hdd osd.1
 ceph osd crush rule create-replicated foo-ssd default host ssd
 ceph osd crush rule create-replicated foo-hdd default host hdd
+ceph osd crush rule ls-by-class ssd | grep 'foo-ssd'
+ceph osd crush rule ls-by-class ssd | expect_false grep 'foo-hdd'
+ceph osd crush rule ls-by-class hdd | grep 'foo-hdd'
+ceph osd crush rule ls-by-class hdd | expect_false grep 'foo-ssd'
 
 ceph osd erasure-code-profile set ec-foo-ssd crush-device-class=ssd m=2 k=2
 ceph osd pool create ec-foo 2 erasure ec-foo-ssd
index 1c72454b64738ae1ddeb5ae5b584a29dbd0ccb14..bf6f3cf5ab8d69aa7bea8ad4562d0a1093102b9b 100644 (file)
@@ -2023,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) {
index 5271e1441123115c182e42fa2ddee150eb7777ae..3737d57300230404dd6b086861a2d10fd28c5941 100644 (file)
@@ -1220,6 +1220,7 @@ public:
   int rename_class(const string& srcname, const string& dstname);
   int populate_classes(
     const std::map<int32_t, map<int32_t, int32_t>>& old_class_bucket);
+  int get_rules_by_class(const string &class_name, set<int> *rules);
   bool _class_is_dead(int class_id);
   void cleanup_dead_classes();
   int rebuild_roots_with_classes();
index 5756f967769ad0d9d377e1880640a68bb1ba4ea7..e463986bc87028667358585814b181bc932f9d08 100644 (file)
@@ -509,6 +509,10 @@ COMMAND("osd lspools " \
 COMMAND_WITH_FLAG("osd crush rule list", "list crush rules", "osd", "r", "cli,rest",
                  FLAG(DEPRECATED))
 COMMAND("osd crush rule ls", "list crush rules", "osd", "r", "cli,rest")
+COMMAND("osd crush rule ls-by-class " \
+        "name=class,type=CephString,goodchars=[A-Za-z0-9-_.],req=false", \
+        "list all crush rules that reference the same <class>", \
+        "osd", "r", "cli,rest")
 COMMAND("osd crush rule dump " \
        "name=name,type=CephString,goodchars=[A-Za-z0-9-_.],req=false", \
        "dump crush rule <name> (default all)", \
index b97e3dc009628d545d544dd4dc9b3d62b824fbc4..995c0a561d94adedcbfd7d55c04d0a5700f7f899 100644 (file)
@@ -4930,6 +4930,34 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op)
       osdmap.crush->list_rules(&ss);
       rdata.append(ss.str());
     }
+  } else if (prefix == "osd crush rule ls-by-class") {
+    string class_name;
+    cmd_getval(g_ceph_context, cmdmap, "class", class_name);
+    if (class_name.empty()) {
+      ss << "no class specified";
+      r = -EINVAL;
+      goto reply;
+    }
+    set<int> rules;
+    r = osdmap.crush->get_rules_by_class(class_name, &rules);
+    if (r < 0) {
+      ss << "failed to get rules by class '" << class_name << "'";
+      goto reply;
+    }
+    if (f) {
+      f->open_array_section("rules");
+      for (auto &rule: rules) {
+        f->dump_string("name", osdmap.crush->get_rule_name(rule));
+      }
+      f->close_section();
+      f->flush(rdata);
+    } else {
+      ostringstream rs;
+      for (auto &rule: rules) {
+        rs << osdmap.crush->get_rule_name(rule) << "\n";
+      }
+      rdata.append(rs.str());
+    }
   } else if (prefix == "osd crush rule dump") {
     string name;
     cmd_getval(g_ceph_context, cmdmap, "name", name);