Problem:
When multiple monitors are removed from the monmap in a single update,
the iterative rank adjustment in notify_rank_removed() fails to maintain
the invariant that our local rank matches the monmap's new_rank until
all iterations complete.
Problem:
The old code decremented rank for each removed rank:
```
for (auto i = monmap->removed_ranks.rbegin(); ...) {
int remove_rank = *i;
int new_rank = monmap->get_rank(messenger->get_myaddrs());
// Old logic (in ConnectionTracker):
if (remove_rank < rank) {
--rank;
}
// This assert would fail on first iteration when removed_ranks.size() > 1
ceph_assert(rank == new_rank);
}
```
When removed_ranks = {0, 1} and we are mon.d (originally rank 3):
- new_rank from monmap = 1 (final correct value after removing 0 and 1)
The invariant is violated during intermediate iterations because each
--rank adjustment only accounts for ONE removed rank, but new_rank
from monmap already accounts for ALL removed ranks.
Solution:
Trust the caller's new_rank from monmap instead of trying to compute it
iteratively. The monmap has already recalculated ranks correctly by
removing all monitors atomically, so we should just use that value.
Changed:
```
if (rank_removed < rank) {
--rank;
}
```
To:
// Trust the caller's new_rank from the monmap rather than trying to compute it.
// This handles cases where multiple ranks are removed simultaneously.
rank = new_rank;
Now the invariant holds on every iteration regardless of how many ranks
are removed.