]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: OSDMonitor: fix the check error of pg creating 10916/head
authorDesmondS <jordanjimmy41177@gmail.com>
Tue, 30 Aug 2016 03:40:00 +0000 (11:40 +0800)
committerDesmondS <jordanjimmy41177@gmail.com>
Mon, 19 Sep 2016 09:59:01 +0000 (17:59 +0800)
The variable 'pgs_per_osd' set value from 'new_pgs' divided by 'expected_osds',
and its type is integer. So it would remove the decimal point and get smaller value.
This would have problem in some situations, for exmaple:

The limitation of pg creating for one OSD is '32'.
There have 3 OSDs and I want to increase pgs for a pool.
It should be the limitation for creating new pgs up to '96(32 * 3)' at once.
Now, I create '98' pgs for a pool.

In original code, '98' would be divided by 'expected_osds' and get the floating value '32....'
Because of the type which is integer, the 'pgs_per_osd' would be set to 32.
Then the value won't bigger than the limitation and get the wrong result.

Signed-off-by: DesmondS <desmond.s@inwinstack.com>
Fixes: http://tracker.ceph.com/issues/17169
qa/workunits/cephtool/test.sh
src/mon/OSDMonitor.cc

index d97a929ad2307ec1483104945c82678864f1f839..6206cb42d8f612abf6bb228b83f2423962feb13f 100755 (executable)
@@ -1514,6 +1514,15 @@ function test_mon_osd_pool_set()
   wait_for_clean
   ceph osd pool set $TEST_POOL_GETSET pgp_num 10
 
+  old_pgs=$(ceph osd pool get $TEST_POOL_GETSET pg_num | sed -e 's/pg_num: //')
+  new_pgs=$(($old_pgs+$(ceph osd stat | grep osdmap | awk '{print $3}')*32))
+  ceph osd pool set $TEST_POOL_GETSET pg_num $new_pgs
+  ceph osd pool set $TEST_POOL_GETSET pgp_num $new_pgs
+  wait_for_clean
+  old_pgs=$(ceph osd pool get $TEST_POOL_GETSET pg_num | sed -e 's/pg_num: //')
+  new_pgs=$(($old_pgs+$(ceph osd stat | grep osdmap | awk '{print $3}')*32+1))
+  expect_false ceph osd pool set $TEST_POOL_GETSET pg_num $new_pgs
+
   ceph osd pool set $TEST_POOL_GETSET nosizechange 1
   expect_false ceph osd pool set $TEST_POOL_GETSET size 2
   expect_false ceph osd pool set $TEST_POOL_GETSET min_size 2
index bfdaf1ef68ec2d1116e2b0e1efbfff58be6ef155..9448ff2c0db753bebdfd41ec4665ecc1210e066f 100644 (file)
@@ -5093,10 +5093,9 @@ int OSDMonitor::prepare_command_pool_set(map<string,cmd_vartype> &cmdmap,
       ss << "splits in cache pools must be followed by scrubs and leave sufficient free space to avoid overfilling.  use --yes-i-really-mean-it to force.";
       return -EPERM;
     }
-    int expected_osds = MAX(1, MIN(p.get_pg_num(), osdmap.get_num_osds()));
+    int expected_osds = MIN(p.get_pg_num(), osdmap.get_num_osds());
     int64_t new_pgs = n - p.get_pg_num();
-    int64_t pgs_per_osd = new_pgs / expected_osds;
-    if (pgs_per_osd > g_conf->mon_osd_max_split_count) {
+    if (new_pgs > g_conf->mon_osd_max_split_count * expected_osds) {
       ss << "specified pg_num " << n << " is too large (creating "
         << new_pgs << " new PGs on ~" << expected_osds
         << " OSDs exceeds per-OSD max of " << g_conf->mon_osd_max_split_count