]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
osd: send pg creations through normal pg queue
authorSage Weil <sage@redhat.com>
Tue, 2 Jan 2018 22:51:41 +0000 (16:51 -0600)
committerSage Weil <sage@redhat.com>
Wed, 4 Apr 2018 13:26:48 +0000 (08:26 -0500)
Queue a null event tagged with create_info, elimiating the special
legacy path.

These are still not fast dispatch because we need an spg (not pg) to queue
and event, and we need a current osdmap in order to calculate that.  That
isn't possible/a good idea in fast dispatch.  In a subsequent patch we'll
create a new pg create message that includes the correct information and
can be fast dispatched, allowing this path to die off post-nautilus.

Also, improve things so that we ack the pg creation only after the PG has
gone active, meaning it is fully replicated (by at least min_size PGs).

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

index f924728c872f58cbf79069e590c38ae624c3366b..7721b586c71af040251fa7b2d3caccd6d286df88 100644 (file)
@@ -4101,94 +4101,6 @@ PGRef OSD::handle_pg_create_info(OSDMapRef osdmap, const PGCreateInfo *info)
   return pg;
 }
 
-/*
- * look up a pg.  if we have it, great.  if not, consider creating it IF the pg mapping
- * hasn't changed since the given epoch and we are the primary.
- */
-int OSD::handle_pg_peering_evt(
-  spg_t pgid,
-  const pg_history_t& orig_history,
-  const PastIntervals& pi,
-  epoch_t epoch,
-  PGPeeringEventRef evt)
-{
-  if (service.splitting(pgid)) {
-    peering_wait_for_split[pgid].push_back(evt);
-    return -EEXIST;
-  }
-
-  PG *pg = _lookup_lock_pg(pgid);
-  if (!pg) {
-    // same primary?
-    if (!osdmap->have_pg_pool(pgid.pool()))
-      return -EINVAL;
-    int up_primary, acting_primary;
-    vector<int> up, acting;
-    osdmap->pg_to_up_acting_osds(
-      pgid.pgid, &up, &up_primary, &acting, &acting_primary);
-
-    pg_history_t history = orig_history;
-    bool valid_history = project_pg_history(
-      pgid, history, epoch, up, up_primary, acting, acting_primary);
-
-    if (!valid_history || epoch < history.same_interval_since) {
-      dout(10) << __func__ << pgid << " acting changed in "
-              << history.same_interval_since << " (msg from " << epoch << ")"
-              << dendl;
-      return -EINVAL;
-    }
-
-    if (service.splitting(pgid)) {
-      ceph_abort();
-    }
-
-    const bool is_mon_create =
-      evt->get_event().dynamic_type() == NullEvt::static_type();
-    if (maybe_wait_for_max_pg(osdmap, pgid, is_mon_create)) {
-      return -EAGAIN;
-    }
-
-    PG::RecoveryCtx rctx = create_context();
-
-    const pg_pool_t* pp = osdmap->get_pg_pool(pgid.pool());
-    if (pp->has_flag(pg_pool_t::FLAG_EC_OVERWRITES) &&
-       store->get_type() != "bluestore") {
-      clog->warn() << "pg " << pgid
-                  << " is at risk of silent data corruption: "
-                  << "the pool allows ec overwrites but is not stored in "
-                  << "bluestore, so deep scrubbing will not detect bitrot";
-    }
-    PG::_create(*rctx.transaction, pgid, pgid.get_split_bits(pp->get_pg_num()));
-    PG::_init(*rctx.transaction, pgid, pp);
-
-    int role = osdmap->calc_pg_role(whoami, acting, acting.size());
-    if (!pp->is_replicated() && role != pgid.shard)
-      role = -1;
-
-    pg = _create_lock_pg(
-      get_map(epoch),
-      pgid, false, false,
-      role,
-      up, up_primary,
-      acting, acting_primary,
-      history, pi,
-      *rctx.transaction);
-    pg->handle_create(&rctx);
-    dispatch_context(rctx, pg, osdmap);
-
-    dout(10) << *pg << " is new" << dendl;
-    enqueue_peering_evt(pg->get_pgid(), evt);
-    wake_pg_waiters(pg);
-    pg->unlock();
-    return 0;
-  } else {
-    // already had it
-    enqueue_peering_evt(pg->get_pgid(), evt);
-    pg->unlock();
-    return -EEXIST;
-  }
-}
-
 bool OSD::maybe_wait_for_max_pg(OSDMapRef osdmap, spg_t pgid, bool is_mon_create)
 {
   const auto max_pgs_per_osd =
@@ -8347,11 +8259,9 @@ void OSD::handle_pg_create(OpRequestRef op)
     pg_history_t history;
     build_initial_pg_history(pgid, created, ci->second, &history, &pi);
 
-    // The mon won't resend unless the primary changed, so
-    // we ignore same_interval_since.  We'll pass this history
-    // to handle_pg_peering_evt with the current epoch as the
-    // event -- the project_pg_history check in
-    // handle_pg_peering_evt will be a noop.
+    // The mon won't resend unless the primary changed, so we ignore
+    // same_interval_since.  We'll pass this history with the current
+    // epoch as the event.
     if (history.same_primary_since > m->epoch) {
       dout(10) << __func__ << ": got obsolete pg create on pgid "
               << pgid << " from epoch " << m->epoch
@@ -8359,19 +8269,21 @@ void OSD::handle_pg_create(OpRequestRef op)
               << dendl;
       continue;
     }
-    if (handle_pg_peering_evt(
-          pgid,
-          history,
-          pi,
-          osdmap->get_epoch(),
-          PGPeeringEventRef(
-           std::make_shared<PGPeeringEvent>(
-             osdmap->get_epoch(),
-             osdmap->get_epoch(),
-             NullEvt()))
-          ) == -EEXIST) {
-      service.send_pg_created(pgid.pgid);
-    }
+    enqueue_peering_evt(
+      pgid,
+      PGPeeringEventRef(
+       std::make_shared<PGPeeringEvent>(
+         osdmap->get_epoch(),
+         osdmap->get_epoch(),
+         NullEvt(),
+         true,
+         new PGCreateInfo(
+           pgid,
+           created,
+           history,
+           pi,
+           true)
+         )));
   }
 
   with_unique_lock(pending_creates_lock, [=]() {
index 366ae17a93ef3b59b7855bd0ded303d6c11e8f8c..1a8ad48c6cb5bfb9aca27d7cb48609a921fb3efb 100644 (file)
@@ -1858,7 +1858,6 @@ protected:
   std::set<create_from_osd_t> pending_creates_from_osd;
   unsigned pending_creates_from_mon = 0;
 
-  map<spg_t, list<PGPeeringEventRef> > peering_wait_for_split;
   PGRecoveryStats pg_recovery_stats;
 
   PGRef _lookup_pg(spg_t pgid);
@@ -1898,12 +1897,6 @@ protected:
 
   PG* _make_pg(OSDMapRef createmap, spg_t pgid);
 
-  int handle_pg_peering_evt(
-    spg_t pgid,
-    const pg_history_t& orig_history,
-    const PastIntervals& pi,
-    epoch_t epoch,
-    PGPeeringEventRef evt);
   bool maybe_wait_for_max_pg(OSDMapRef osdmap, spg_t pgid, bool is_mon_create);
   void resume_creating_pg();
 
index a0f634075f580d0f31ccfbd1c90e365938c63479..3fc2e132dd523a05f43bf5324fbf7dcacd4a5d3d 100644 (file)
@@ -8143,6 +8143,9 @@ boost::statechart::result PG::RecoveryState::Active::react(const AllReplicasActi
   }
 
   // info.last_epoch_started is set during activate()
+  if (pg->info.history.last_epoch_started == 0) {
+    pg->osd->send_pg_created(pg->info.pgid.pgid);
+  }
   pg->info.history.last_epoch_started = pg->info.last_epoch_started;
   pg->info.history.last_interval_started = pg->info.last_interval_started;
   pg->dirty_info = true;