From: DesmondS Date: Tue, 30 Aug 2016 03:40:00 +0000 (+0800) Subject: mon: OSDMonitor: fix the check error of pg creating X-Git-Tag: v11.1.0~693^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=179d3d165955e91fb8bd88613af9424f20782d01;p=ceph.git mon: OSDMonitor: fix the check error of pg creating 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 Fixes: http://tracker.ceph.com/issues/17169 --- diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index d97a929ad23..6206cb42d8f 100755 --- a/qa/workunits/cephtool/test.sh +++ b/qa/workunits/cephtool/test.sh @@ -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 diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index bfdaf1ef68e..9448ff2c0db 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -5093,10 +5093,9 @@ int OSDMonitor::prepare_command_pool_set(map &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