]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: make use of pg history and past_intervals in pg_create2 messages 27696/head
authorSage Weil <sage@redhat.com>
Fri, 19 Apr 2019 21:41:04 +0000 (16:41 -0500)
committerSage Weil <sage@redhat.com>
Tue, 23 Apr 2019 12:03:47 +0000 (07:03 -0500)
If we get a mismatched epoch and past_intervals, error out early, or else
we'll end up asserting later in the PastIntervals code.

Signed-off-by: Sage Weil <sage@redhat.com>
src/osd/OSD.cc

index cfd123c0418a3a102f4ff8439816edfa3e1b1a11..6cd4eb966758c81ae14cb348acfd630fecc21b68 100644 (file)
@@ -9000,6 +9000,9 @@ void OSD::split_pgs(
  */
 void OSD::handle_pg_create(OpRequestRef op)
 {
+  // NOTE: this can be removed in P release (mimic is the last version to
+  // send MOSDPGCreate messages).
+
   const MOSDPGCreate *m = static_cast<const MOSDPGCreate*>(op->get_req());
   ceph_assert(m->get_type() == MSG_OSD_PG_CREATE);
 
@@ -9263,23 +9266,55 @@ void OSD::handle_fast_pg_create(MOSDPGCreate2 *m)
     spg_t pgid = p.first;
     epoch_t created = p.second.first;
     utime_t created_stamp = p.second.second;
-    dout(20) << __func__ << " " << pgid << " e" << created
-            << "@" << created_stamp << dendl;
-    enqueue_peering_evt(
-      pgid,
-      PGPeeringEventRef(
-       std::make_shared<PGPeeringEvent>(
-         m->epoch,
-         m->epoch,
-         NullEvt(),
-         true,
-         new PGCreateInfo(
-           pgid,
-           created,
-           pg_history_t(created, created_stamp),
-           PastIntervals(),
-           true)
-         )));
+    auto q = m->pg_extra.find(pgid);
+    if (q == m->pg_extra.end()) {
+      dout(20) << __func__ << " " << pgid << " e" << created
+              << "@" << created_stamp
+              << " (no history or past_intervals)" << dendl;
+      // pre-octopus ... no pg history.  this can be removed in Q release.
+      enqueue_peering_evt(
+       pgid,
+       PGPeeringEventRef(
+         std::make_shared<PGPeeringEvent>(
+           m->epoch,
+           m->epoch,
+           NullEvt(),
+           true,
+           new PGCreateInfo(
+             pgid,
+             created,
+             pg_history_t(created, created_stamp),
+             PastIntervals(),
+             true)
+           )));
+    } else {
+      dout(20) << __func__ << " " << pgid << " e" << created
+              << "@" << created_stamp
+              << " history " << q->second.first
+              << " pi " << q->second.second << dendl;
+      if (!q->second.second.empty() &&
+         m->epoch < q->second.second.get_bounds().second) {
+       clog->error() << "got pg_create on " << pgid << " epoch " << m->epoch
+                     << " and unmatched past_intervals " << q->second.second
+                     << " (history " << q->second.first << ")";
+      } else {
+       enqueue_peering_evt(
+         pgid,
+         PGPeeringEventRef(
+           std::make_shared<PGPeeringEvent>(
+             m->epoch,
+             m->epoch,
+             NullEvt(),
+             true,
+             new PGCreateInfo(
+               pgid,
+               m->epoch,
+               q->second.first,
+               q->second.second,
+               true)
+             )));
+      }
+    }
   }
 
   {