mgr/DaemonServer.cc: prevent integer underflow that is triggered by large increases to pg_num/pgp_num

This fixes a scenario where mgrs continually crash while attempting to apply large increases to pg_num/pgp_num. The max step size (estmax) for each incremental update to the pgp_num is calculated as a percentage of the pg_num, which permits the possibility for the max step size (estmax) to be greater than the current pgp_num when the increase is large; this causes an integer underflow when the max step size is subtracted from the pgp_num in order to calculate the next step size with std::clamp. The integer underflow causes hi < lo in args passed to std::clamp, which causes a failed assertion, SIGABRT, and ultimately crashing mgr.

Fixes: https://tracker.ceph.com/issues/47738
Signed-off-by: Cory Snyder <csnyder@iland.com>
This commit is contained in:
Cory Snyder 2021-05-28 15:08:49 -04:00
parent 0331281e8a
commit b4316d257e

View File

@ -2831,8 +2831,12 @@ void DaemonServer::adjust_pgs()
max_misplaced / 2.0);
unsigned estmax = std::max<unsigned>(
(double)p.get_pg_num() * room, 1u);
unsigned next_min = 0;
if (p.get_pgp_num() > estmax) {
next_min = p.get_pgp_num() - estmax;
}
next = std::clamp(target,
p.get_pgp_num() - estmax,
next_min,
p.get_pgp_num() + estmax);
dout(20) << " room " << room << " estmax " << estmax
<< " delta " << (target-p.get_pgp_num())