From: Tongliang Deng Date: Fri, 31 Dec 2021 06:02:25 +0000 (+0800) Subject: mon/OSDMonitor: fix integer underflow of check_pg_num X-Git-Tag: v17.2.6~16^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=30a24170a70279f172a869ab8fd0f7799d25a5c9;p=ceph.git mon/OSDMonitor: fix integer underflow of check_pg_num Underflow of the `uint64_t projected` variable occurs when the sum of current acting pg num and new pg num we specified is less than the pg num calculated from pg info. Signed-off-by: Tongliang Deng Note: This commit is cherry-picked as a dependency for later commits in this backport. (cherry picked from commit bd9813f5e1a3addca1a57360d58b50b120e0e5f3) --- diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 5d76862e0a83..b64da5fb6c98 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -7932,13 +7932,12 @@ int OSDMonitor::check_pg_num(int64_t pool, int pg_num, int size, int crush_rule, } osd_num += osd_ids.size() - out_osd; } - if (pool >= 0) { - // update an existing pool's pg num - const auto& pg_info = osdmap.get_pools().at(pool); - // already counted the pgs of this `pool` by iterating crush map, so + if (pool >= 0) { + // update an existing pool's pg num. + // already counted the pgs of this `pool` by iterating crush map, so // remove them using adding the specified pg num projected += pg_num * size; - projected -= pg_info.get_pg_num_target() * pg_info.get_size(); + projected -= mapping.get_num_acting_pgs(pool); } num_osds = std::max(osd_num, 3u); // assume min cluster size 3 } else { diff --git a/src/osd/OSDMapMapping.h b/src/osd/OSDMapMapping.h index 8f779c41e669..eeeb7a8bc7f3 100644 --- a/src/osd/OSDMapMapping.h +++ b/src/osd/OSDMapMapping.h @@ -247,6 +247,16 @@ private: row[4 + size + i] = up[i]; } } + + uint64_t get_num_acting_pgs() const { + uint64_t num_acting_pgs = 0; + const size_t row_size = this->row_size(); + for (size_t ps = 0; ps < pg_num; ++ps) { + const int32_t *row = &table[row_size * ps]; + num_acting_pgs += row[2]; + } + return num_acting_pgs; + } }; mempool::osdmap_mapping::map pools; @@ -330,6 +340,12 @@ public: return acting_rmap[osd]; } + uint64_t get_num_acting_pgs(int64_t pool) const { + auto p = pools.find(pool); + ceph_assert(p != pools.end()); + return p->second.get_num_acting_pgs(); + } + void update(const OSDMap& map, pg_t pgid); std::unique_ptr start_update(