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 <xie.xingguo@zte.com.cn>
This commit is contained in:
xie xingguo 2017-07-25 15:18:44 +08:00
parent e4e83a0dd7
commit 32fb548797
2 changed files with 14 additions and 1 deletions

View File

@ -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 "$@"

View File

@ -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 <osd>' 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;