From: xie xingguo Date: Tue, 18 Jul 2017 03:05:27 +0000 (+0800) Subject: crush: allow "crush class rm" to automatically recycle shadow tree(s) X-Git-Tag: v12.1.2~68^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=edd89303466adc8e573610c4d8e37b029f324eac;p=ceph.git crush: allow "crush class rm" to automatically recycle shadow tree(s) Signed-off-by: xie xingguo --- diff --git a/qa/standalone/crush/crush-classes.sh b/qa/standalone/crush/crush-classes.sh index 0e091fcdac38..dfc3d036ff55 100755 --- a/qa/standalone/crush/crush-classes.sh +++ b/qa/standalone/crush/crush-classes.sh @@ -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}'` diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 2125fa15f2ed..26a602bcc9a1 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -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 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();