There was a silent bug in the activate 'acks' that go from the replica back
to the primary. Prior to
86aa07d7a91ac23074e76551c3a6db3a5736cffa, we
were passing same_interval_since to the callback, which mean that
sometimes _activate_committed() would ignore it and we wouldn't update
last_epoch_started. This was mosty invisible; the next peering event would
just, in some cases, look at more past intervals than it needed to.
In
86aa07d7a91ac23074e76551c3a6db3a5736cffa we fixed this so that the check
is correct. (We noticed because now we aren't setting the pg CLEAN flag
until after last_epoch_started is updated.) That, in turn, revealed a
similar bug that we're fixing here: the replica's last_peering_reset could
be lower than the primary's, such that the activate 'ack' info is ignored.
To fix this, simply set last_peering_reset to the current epoch when the
replica activates; this will always be greater than the primary's.
Signed-off-by: Sage Weil <sage@inktank.com>
dout(10) << "In ReplicaActive, about to call activate" << dendl;
PG *pg = context< RecoveryMachine >().pg;
map< int, map< pg_t, pg_query_t> > query_map;
+
+ // we are replica; use current epoch as last_peering_reset to ensure
+ // that our info is not ignored by the primary later. otherwise,
+ // our last_peering_reset may be earlier than the primary's, and
+ // they will ignore our message.
+ pg->last_peering_reset = pg->get_osdmap()->get_epoch();
+
pg->activate(*context< RecoveryMachine >().get_cur_transaction(),
*context< RecoveryMachine >().get_context_list(),
query_map, NULL);