]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: implement osd crush class create/rm/ls 14039/head
authorLoic Dachary <ldachary@redhat.com>
Mon, 3 Apr 2017 15:50:03 +0000 (17:50 +0200)
committerLoic Dachary <ldachary@redhat.com>
Wed, 5 Apr 2017 07:22:24 +0000 (09:22 +0200)
Signed-off-by: Loic Dachary <loic@dachary.org>
src/mon/MonCommands.h
src/mon/OSDMonitor.cc
src/test/crush/crush-classes.sh

index 2561fce117f1f58d1f4d23530732559fbe673408..2ede8fb5b5eaa5a656f80db7b006efda735af3ca 100644 (file)
@@ -581,6 +581,17 @@ COMMAND("osd crush rule rm " \
 COMMAND("osd crush tree",
        "dump crush buckets and items in a tree view",
        "osd", "r", "cli,rest")
+COMMAND("osd crush class create " \
+       "name=class,type=CephString,goodchars=[A-Za-z0-9-_]", \
+       "create crush device class <class>", \
+       "osd", "rw", "cli,rest")
+COMMAND("osd crush class rm " \
+       "name=class,type=CephString,goodchars=[A-Za-z0-9-_]", \
+       "remove crush device class <class>", \
+       "osd", "rw", "cli,rest")
+COMMAND("osd crush class ls", \
+       "list all crush device classes", \
+       "osd", "r", "cli,rest")
 COMMAND("osd setmaxosd " \
        "name=newmax,type=CephInt,range=0", \
        "set new maximum osd value", "osd", "rw", "cli,rest")
index a9339f0c74415bdbe02ccb7d1ddafac7eb34fd76..93883f5f3b10d0329883a9d41c37503919fcfcc1 100644 (file)
@@ -4831,6 +4831,13 @@ stats_out:
     osdmap.crush->dump_tree(f.get());
     f->close_section();
     f->flush(rdata);
+  } else if (prefix == "osd crush class ls") {
+    boost::scoped_ptr<Formatter> f(Formatter::create(format, "json-pretty", "json-pretty"));
+    f->open_array_section("crush_classes");
+    for (auto i : osdmap.crush->class_name)
+      f->dump_string("class", i.second);
+    f->close_section();
+    f->flush(rdata);
   } else if (prefix == "osd erasure-code-profile ls") {
     const map<string,map<string,string> > &profiles =
       osdmap.get_erasure_code_profiles();
@@ -6393,6 +6400,72 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
       goto reply;
     else
       goto update;
+  } else if (prefix == "osd crush class create") {
+    string device_class;
+    if (!cmd_getval(g_ceph_context, cmdmap, "class", device_class)) {
+      err = -EINVAL; // no value!
+      goto reply;
+    }
+
+    if (!_have_pending_crush() &&
+       _get_stable_crush().class_exists(device_class)) {
+      ss << "class '" << device_class << "' already exists";
+      goto reply;
+    }
+
+    CrushWrapper newcrush;
+    _get_pending_crush(newcrush);
+
+    if (newcrush.class_exists(name)) {
+      ss << "class '" << device_class << "' already exists";
+      goto update;
+    }
+
+    int class_id = newcrush.get_or_create_class_id(device_class);
+
+    pending_inc.crush.clear();
+    newcrush.encode(pending_inc.crush, mon->get_quorum_con_features());
+    ss << "created class " << device_class << " with id " << class_id
+       << " to crush map";
+    goto update;
+    
+  } else if (prefix == "osd crush class rm") {
+    string device_class;
+    if (!cmd_getval(g_ceph_context, cmdmap, "class", device_class)) {
+      err = -EINVAL; // no value!
+      goto reply;
+    }
+
+    CrushWrapper newcrush;
+    _get_pending_crush(newcrush);
+
+    if (!newcrush.class_exists(device_class)) {
+      err = -ENOENT;
+      ss << "class '" << device_class << "' does not exist";
+      goto reply;
+    }
+
+    int class_id = newcrush.get_class_id(device_class);
+
+    if (newcrush.class_is_in_use(class_id)) {
+      err = -EBUSY;
+      ss << "class '" << device_class << "' is in use";
+      goto reply;
+    }
+
+    err = newcrush.remove_class_name(device_class);
+    if (err < 0) {
+      ss << "class '" << device_class << "' cannot be removed '"
+        << cpp_strerror(err) << "'";
+      goto reply;
+    }
+
+    pending_inc.crush.clear();
+    newcrush.encode(pending_inc.crush, mon->get_quorum_con_features());
+    ss << "removed class " << device_class << " with id " << class_id
+       << " from crush map";
+    goto update;
+    
   } else if (osdid_present &&
             (prefix == "osd crush set" || prefix == "osd crush add")) {
     // <OsdName> is 'osd.<id>' or '<id>', passed as int64_t id
index bf06f33d34465cf2e67df3da434f82d6311a7973..fce7a84147add879550079328f0e84169080e082 100755 (executable)
@@ -128,6 +128,17 @@ function TEST_set_device_class() {
     $ok || return 1
 }
 
+function TEST_mon_classes() {
+    local dir=$1
+
+    run_mon $dir a || return 1
+    ceph osd crush class create CLASS || return 1
+    ceph osd crush class create CLASS || return 1 # idempotent
+    ceph osd crush class ls | grep CLASS  || return 1
+    ceph osd crush class rm CLASS || return 1
+    expect_failure $dir ENOENT ceph osd crush class rm CLASS || return 1
+}
+
 main crush-classes "$@"
 
 # Local Variables: