From 3f8efee390a221ff88eaf46d3eb6515275d05ccc Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Mon, 3 Apr 2017 17:50:03 +0200 Subject: [PATCH] mon: implement osd crush class create/rm/ls Signed-off-by: Loic Dachary --- src/mon/MonCommands.h | 11 +++++ src/mon/OSDMonitor.cc | 73 +++++++++++++++++++++++++++++++++ src/test/crush/crush-classes.sh | 11 +++++ 3 files changed, 95 insertions(+) diff --git a/src/mon/MonCommands.h b/src/mon/MonCommands.h index 2561fce117f1..2ede8fb5b5ea 100644 --- a/src/mon/MonCommands.h +++ b/src/mon/MonCommands.h @@ -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 ", \ + "osd", "rw", "cli,rest") +COMMAND("osd crush class rm " \ + "name=class,type=CephString,goodchars=[A-Za-z0-9-_]", \ + "remove crush device 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") diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index a9339f0c7441..93883f5f3b10 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -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 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 > &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")) { // is 'osd.' or '', passed as int64_t id diff --git a/src/test/crush/crush-classes.sh b/src/test/crush/crush-classes.sh index bf06f33d3446..fce7a84147ad 100755 --- a/src/test/crush/crush-classes.sh +++ b/src/test/crush/crush-classes.sh @@ -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: -- 2.47.3