]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: fix potential weight overflow
authorxie xingguo <xie.xingguo@zte.com.cn>
Sat, 8 Jul 2017 03:47:42 +0000 (11:47 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Mon, 10 Jul 2017 03:23:36 +0000 (11:23 +0800)
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>
qa/workunits/mon/crush_ops.sh
src/crush/CrushWrapper.cc
src/crush/CrushWrapper.h

index c1aa54b08ae449f2a02e1f348af9d1ef8ad9487b..a3f189e8a27ea2f87f8eabb42541c678f437e0ac 100755 (executable)
@@ -104,6 +104,7 @@ o3=`ceph osd create`
 ceph osd crush add $o3 123 root=default
 ceph osd tree | grep osd.$o3 | grep 123
 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 crush 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.$o5 | grep 123
 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.$o5 | grep 155
 ceph osd crush rm osd.$o4
index 6a0017df96d7cc3b7150a29a6ca38b2fbee4fdf8..425ec311f7f9a5fc8c75a70ade0e049af5944c36 100644 (file)
@@ -807,6 +807,11 @@ int CrushWrapper::insert_item(CephContext *cct, int item, float weight, string n
   if (!is_valid_crush_loc(cct, loc))
     return -EINVAL;
 
+  int r = validate_weightf(weight);
+  if (r < 0) {
+    return r;
+  }
+
   if (name_exists(name)) {
     if (get_item_id(name) != item) {
       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))
     return -EINVAL;
 
+  ret = validate_weightf(weight);
+  if (ret < 0) {
+    return ret;
+  }
+
   // compare quantized (fixed-point integer) weights!  
   int iweight = (int)(weight * (float)0x10000);
   int old_iweight;
index b5bfebb765780f44c2b002ff5a246047f2e7d37c..3f181e2eeb725210c1a00e22abbb8c5c834bbb6f 100644 (file)
@@ -849,18 +849,37 @@ public:
     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_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));
   }
   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 r = validate_weightf(weight);
+    if (r < 0) {
+      return r;
+    }
     return adjust_item_weight_in_loc(cct, id, (int)(weight * (float)0x10000), loc);
   }
   void reweight(CephContext *cct);
 
   int adjust_subtree_weight(CephContext *cct, int id, int 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));
   }