]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/PeeringState: fix history.same_interval_since of merge target again 35558/head
authorxie xingguo <xie.xingguo@zte.com.cn>
Sat, 13 Jun 2020 07:28:31 +0000 (15:28 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Wed, 17 Jun 2020 01:14:21 +0000 (09:14 +0800)
The symptom looks much like we see in
https://tracker.ceph.com/issues/37654.

The root cause is that both merge source and target could be
fabricated PGs (aka placeholders), hence merge target's
same_interval_since could remain 0 after merge.

Fix by adjusting history.same_interval_since to last_epoch_clean
reported by these PGs were found to be ready for merge.
This peer is going to be ignored/purged by primary anyway later
when peering is done.

Fixes: https://tracker.ceph.com/issues/45991
Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
src/osd/PeeringState.cc

index ac42d9c281851ddeeb2ee8ca1bfe8dc35252bede..7a684983a6f6a8cbfafa29cb6489b2945eacee63 100644 (file)
@@ -3086,6 +3086,20 @@ void PeeringState::merge_from(
               << sources.begin()->second->info.history
               << dendl;
 
+    // above we have pulled down source's history and we need to check
+    // history.epoch_created again to confirm that source is not a placeholder
+    // too. (peering requires a sane history.same_interval_since value for any
+    // non-newly created pg and below here we know we are basically iterating
+    // back a series of past maps to fake a merge process, hence we need to
+    // fix history.same_interval_since first so that start_peering_interval()
+    // will not complain)
+    if (info.history.epoch_created == 0) {
+      dout(10) << __func__ << " both merge target and source are placeholders,"
+               << " set sis to lec " << info.history.last_epoch_clean
+               << dendl;
+      info.history.same_interval_since = info.history.last_epoch_clean;
+    }
+
     // if the past_intervals start is later than last_epoch_clean, it
     // implies the source repeered again but the target didn't, or
     // that the source became clean in a later epoch than the target.