]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: allow "crush class rm" to automatically recycle shadow tree(s)
authorxie xingguo <xie.xingguo@zte.com.cn>
Tue, 18 Jul 2017 03:05:27 +0000 (11:05 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Wed, 26 Jul 2017 14:39:41 +0000 (22:39 +0800)
Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
qa/standalone/crush/crush-classes.sh
src/mon/OSDMonitor.cc

index 0e091fcdac38f751d9486d809f28d6cbcb0c5b16..dfc3d036ff555ee4df5e78c3c82c35605d17c9da 100755 (executable)
@@ -193,6 +193,18 @@ function TEST_mon_classes() {
     ceph osd crush dump | grep -q '~asdf' && return 1
     ceph osd crush tree --show-shadow | grep -q '~asdf' && return 1
 
+    # test 'class rm' automatically recycles shadow trees
+    ceph osd crush set-device-class asdf 0 1 2 || return 1
+    ceph osd tree | grep -q 'asdf' || return 1
+    ceph osd crush dump | grep -q '~asdf' || return 1
+    ceph osd crush tree --show-shadow | grep -q '~asdf' || return 1
+    ceph osd crush class ls | grep -q 'asdf' || return 1
+    ceph osd crush class rm asdf || return 1
+    ceph osd tree | grep -q 'asdf' && return 1
+    ceph osd crush dump | grep -q '~asdf' && return 1
+    ceph osd crush tree --show-shadow | grep -q '~asdf' && return 1
+    ceph osd crush class ls | grep -q 'asdf' && return 1
+
     ceph osd crush set-device-class abc osd.2 || return 1
     ceph osd crush move osd.2 root=foo rack=foo-rack host=foo-host || return 1
     out=`ceph osd tree |awk '$1 == 2 && $2 == "abc" {print $0}'`
index 2125fa15f2ed73386552f1c79e05f0e4f46c7a2d..26a602bcc9a11b2aca83668822b9aa8414d626a9 100644 (file)
@@ -7680,11 +7680,24 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
       goto reply;
     }
 
-    err = newcrush.remove_class_name(device_class);
-    if (err < 0) {
-      ss << "class '" << device_class << "' cannot be removed '"
-        << cpp_strerror(err) << "'";
-      goto reply;
+    set<int> osds;
+    newcrush.get_devices_by_class(device_class, &osds);
+    for (auto& p: osds) {
+      err = newcrush.remove_device_class(g_ceph_context, p, &ss);
+      if (err < 0) {
+        // ss has reason for failure
+        goto reply;
+      }
+    }
+
+    if (osds.empty()) {
+      // empty class, remove directly
+      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();