From: xie xingguo Date: Tue, 25 Jul 2017 07:18:44 +0000 (+0800) Subject: crush: guard set-device-class X-Git-Tag: v12.1.2~68^2~13 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=32fb548797df16dbe09252c6ceadee21a2bc8552;p=ceph.git crush: guard set-device-class If a device has already been bounded to a class, do not allow to change its class silently. Require user call rm-device-class first. Signed-off-by: xie xingguo --- diff --git a/qa/standalone/crush/crush-classes.sh b/qa/standalone/crush/crush-classes.sh index c81a4550dc8e6..c2eccc38bd720 100755 --- a/qa/standalone/crush/crush-classes.sh +++ b/qa/standalone/crush/crush-classes.sh @@ -186,6 +186,10 @@ function TEST_mon_classes() { expect_failure $dir EBUSY ceph osd crush class rm abc || return 1 # still referenced by foo-rule ceph osd crush rule rm foo-rule || return 1 ceph osd crush class rm abc || return 1 + + # test set-device-class implicitly change class + ceph osd crush set-device-class hdd osd.0 || return 1 + expect_failure $dir EBUSY ceph osd crush set-device-class nvme osd.0 || return 1 } main crush-classes "$@" diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 2fc492e7f3720..11659ccf44089 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -1803,12 +1803,21 @@ int CrushWrapper::update_device_class(int id, const string& name, ostream *ss) { + assert(item_exists(id)); + auto old_class_name = get_item_class(id); + if (old_class_name && old_class_name != class_name) { + *ss << "osd." << id << " has already bound to class '" << old_class_name + << "', can not reset class to '" << class_name << "'; " + << "use 'ceph osd crush rm-device-class ' to " + << "remove old class first"; + return -EBUSY; + } + int class_id = get_or_create_class_id(class_name); if (id < 0) { *ss << name << " id " << id << " is negative"; return -EINVAL; } - assert(item_exists(id)); if (class_map.count(id) != 0 && class_map[id] == class_id) { *ss << name << " already set to class " << class_name;