PG: best_info must have a last_epoch_started as high as any other info

We disregard incomplete infos during find_best_info, but we can't an
info with a last_epoch_started less that of the incomplete info.

This should avoid cases like #2462.  In that case, it appears that
a peer with empty info/log was chosen as authoritative even though
there was a non-empty incomplete peer.

Signed-off-by: Samuel Just <sam.just@inktank.com>
This commit is contained in:
Samuel Just 2012-06-15 17:09:42 -07:00
parent 2dd179883e
commit 07f853db39

View File

@ -928,6 +928,7 @@ void PG::clear_primary_state()
*/
map<int, pg_info_t>::const_iterator PG::find_best_info(const map<int, pg_info_t> &infos) const
{
epoch_t last_epoch_started = 0;
map<int, pg_info_t>::const_iterator best = infos.end();
// find osd with newest last_update. if there are multiples, prefer
// - a longer tail, if it brings another peer into log contiguity
@ -935,6 +936,15 @@ map<int, pg_info_t>::const_iterator PG::find_best_info(const map<int, pg_info_t>
for (map<int, pg_info_t>::const_iterator p = infos.begin();
p != infos.end();
++p) {
// Only consider peers with the most recent last_epoch_started found
if (p->second.history.last_epoch_started > last_epoch_started) {
last_epoch_started = p->second.history.last_epoch_started;
if (best != infos.end() &&
last_epoch_started > best->second.history.last_epoch_started)
best = infos.end();
} else if (p->second.history.last_epoch_started < last_epoch_started) {
continue;
}
// Disquality anyone who is incomplete (not fully backfilled)
if (p->second.is_incomplete())
continue;