crush: fix potential weight overflow

E.g.:
./bin/ceph osd crush reweight osd.0 32768

ID WEIGHT      TYPE NAME                                            UP/DOWN REWEIGHT PRIMARY-AFFINITY
-4 32770.00000 root default~hdd
-3           -     host gitbuilder-ceph-rpm-centos7-amd64-basic~hdd
 0           -         osd.0                                             up  1.00000          1.00000
 1     1.00000         osd.1                                             up  1.00000          1.00000
 2     1.00000         osd.2                                             up  1.00000          1.00000
-1 32770.00000 root default
-2           -     host gitbuilder-ceph-rpm-centos7-amd64-basic
 0           -         osd.0                                             up  1.00000          1.00000
 1     1.00000         osd.1                                             up  1.00000          1.00000
 2     1.00000         osd.2                                             up  1.00000          1.00000

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
This commit is contained in:
xie xingguo 2017-07-08 11:47:42 +08:00
parent b08b485ce8
commit 7d07356383
3 changed files with 31 additions and 0 deletions

View File

@ -104,6 +104,7 @@ o3=`ceph osd create`
ceph osd crush add $o3 123 root=default ceph osd crush add $o3 123 root=default
ceph osd tree | grep osd.$o3 | grep 123 ceph osd tree | grep osd.$o3 | grep 123
ceph osd crush reweight osd.$o3 113 ceph osd crush reweight osd.$o3 113
expect_false ceph osd crush reweight osd.$o3 123456
ceph osd tree | grep osd.$o3 | grep 113 ceph osd tree | grep osd.$o3 | grep 113
ceph osd crush rm osd.$o3 ceph osd crush rm osd.$o3
ceph osd rm osd.$o3 ceph osd rm osd.$o3
@ -116,6 +117,7 @@ ceph osd crush add $o5 123 root=default host=foobaz
ceph osd tree | grep osd.$o4 | grep 123 ceph osd tree | grep osd.$o4 | grep 123
ceph osd tree | grep osd.$o5 | grep 123 ceph osd tree | grep osd.$o5 | grep 123
ceph osd crush reweight-subtree foobaz 155 ceph osd crush reweight-subtree foobaz 155
expect_false ceph osd crush reweight-subtree foobaz 123456
ceph osd tree | grep osd.$o4 | grep 155 ceph osd tree | grep osd.$o4 | grep 155
ceph osd tree | grep osd.$o5 | grep 155 ceph osd tree | grep osd.$o5 | grep 155
ceph osd crush rm osd.$o4 ceph osd crush rm osd.$o4

View File

@ -807,6 +807,11 @@ int CrushWrapper::insert_item(CephContext *cct, int item, float weight, string n
if (!is_valid_crush_loc(cct, loc)) if (!is_valid_crush_loc(cct, loc))
return -EINVAL; return -EINVAL;
int r = validate_weightf(weight);
if (r < 0) {
return r;
}
if (name_exists(name)) { if (name_exists(name)) {
if (get_item_id(name) != item) { if (get_item_id(name) != item) {
ldout(cct, 10) << "device name '" << name << "' already exists as id " ldout(cct, 10) << "device name '" << name << "' already exists as id "
@ -1021,6 +1026,11 @@ int CrushWrapper::update_item(CephContext *cct, int item, float weight, string n
if (!is_valid_crush_loc(cct, loc)) if (!is_valid_crush_loc(cct, loc))
return -EINVAL; return -EINVAL;
ret = validate_weightf(weight);
if (ret < 0) {
return ret;
}
// compare quantized (fixed-point integer) weights! // compare quantized (fixed-point integer) weights!
int iweight = (int)(weight * (float)0x10000); int iweight = (int)(weight * (float)0x10000);
int old_iweight; int old_iweight;

View File

@ -849,18 +849,37 @@ public:
return (float)get_item_weight_in_loc(id, loc) / (float)0x10000; return (float)get_item_weight_in_loc(id, loc) / (float)0x10000;
} }
int validate_weightf(float weight) {
uint64_t iweight = weight * 0x10000;
if (iweight > std::numeric_limits<int>::max()) {
return -EOVERFLOW;
}
return 0;
}
int adjust_item_weight(CephContext *cct, int id, int weight); int adjust_item_weight(CephContext *cct, int id, int weight);
int adjust_item_weightf(CephContext *cct, int id, float weight) { int adjust_item_weightf(CephContext *cct, int id, float weight) {
int r = validate_weightf(weight);
if (r < 0) {
return r;
}
return adjust_item_weight(cct, id, (int)(weight * (float)0x10000)); return adjust_item_weight(cct, id, (int)(weight * (float)0x10000));
} }
int adjust_item_weight_in_loc(CephContext *cct, int id, int weight, const map<string,string>& loc); int adjust_item_weight_in_loc(CephContext *cct, int id, int weight, const map<string,string>& loc);
int adjust_item_weightf_in_loc(CephContext *cct, int id, float weight, const map<string,string>& loc) { int adjust_item_weightf_in_loc(CephContext *cct, int id, float weight, const map<string,string>& loc) {
int r = validate_weightf(weight);
if (r < 0) {
return r;
}
return adjust_item_weight_in_loc(cct, id, (int)(weight * (float)0x10000), loc); return adjust_item_weight_in_loc(cct, id, (int)(weight * (float)0x10000), loc);
} }
void reweight(CephContext *cct); void reweight(CephContext *cct);
int adjust_subtree_weight(CephContext *cct, int id, int weight); int adjust_subtree_weight(CephContext *cct, int id, int weight);
int adjust_subtree_weightf(CephContext *cct, int id, float weight) { int adjust_subtree_weightf(CephContext *cct, int id, float weight) {
int r = validate_weightf(weight);
if (r < 0) {
return r;
}
return adjust_subtree_weight(cct, id, (int)(weight * (float)0x10000)); return adjust_subtree_weight(cct, id, (int)(weight * (float)0x10000));
} }