From 179d3d165955e91fb8bd88613af9424f20782d01 Mon Sep 17 00:00:00 2001 From: DesmondS Date: Tue, 30 Aug 2016 11:40:00 +0800 Subject: [PATCH] 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 --- qa/workunits/cephtool/test.sh | 9 +++++++++ src/mon/OSDMonitor.cc | 5 ++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/qa/workunits/cephtool/test.sh b/qa/workunits/cephtool/test.sh index d97a929ad230..6206cb42d8f6 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 bfdaf1ef68ec..9448ff2c0db7 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 -- 2.47.3