From: Samuel Just Date: Fri, 29 Mar 2019 21:55:36 +0000 (-0700) Subject: osd/: move needs_recover/backfill, all_unfound_are_queried_or_lost X-Git-Tag: v15.1.0~2774^2~55 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4f8fbd1dca70eead924e010c2ba14c0ed1f6617e;p=ceph.git osd/: move needs_recover/backfill, all_unfound_are_queried_or_lost Signed-off-by: Samuel Just --- diff --git a/src/osd/PG.cc b/src/osd/PG.cc index ac2f84d0d00..52661e59300 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -519,92 +519,6 @@ void PG::discover_all_missing(map > &query_map) } /******* PG ***********/ -bool PG::needs_recovery() const -{ - ceph_assert(is_primary()); - - auto &missing = pg_log.get_missing(); - - if (missing.num_missing()) { - dout(10) << __func__ << " primary has " << missing.num_missing() - << " missing" << dendl; - return true; - } - - ceph_assert(!acting_recovery_backfill.empty()); - set::const_iterator end = acting_recovery_backfill.end(); - set::const_iterator a = acting_recovery_backfill.begin(); - for (; a != end; ++a) { - if (*a == get_primary()) continue; - pg_shard_t peer = *a; - map::const_iterator pm = peer_missing.find(peer); - if (pm == peer_missing.end()) { - dout(10) << __func__ << " osd." << peer << " doesn't have missing set" - << dendl; - continue; - } - if (pm->second.num_missing()) { - dout(10) << __func__ << " osd." << peer << " has " - << pm->second.num_missing() << " missing" << dendl; - return true; - } - } - - dout(10) << __func__ << " is recovered" << dendl; - return false; -} - -bool PG::needs_backfill() const -{ - ceph_assert(is_primary()); - - // We can assume that only possible osds that need backfill - // are on the backfill_targets vector nodes. - set::const_iterator end = backfill_targets.end(); - set::const_iterator a = backfill_targets.begin(); - for (; a != end; ++a) { - pg_shard_t peer = *a; - map::const_iterator pi = peer_info.find(peer); - if (!pi->second.last_backfill.is_max()) { - dout(10) << __func__ << " osd." << peer << " has last_backfill " << pi->second.last_backfill << dendl; - return true; - } - } - - dout(10) << __func__ << " does not need backfill" << dendl; - return false; -} - -/* - * Returns true unless there is a non-lost OSD in might_have_unfound. - */ -bool PG::all_unfound_are_queried_or_lost(const OSDMapRef osdmap) const -{ - ceph_assert(is_primary()); - - set::const_iterator peer = might_have_unfound.begin(); - set::const_iterator mend = might_have_unfound.end(); - for (; peer != mend; ++peer) { - if (peer_missing.count(*peer)) - continue; - map::const_iterator iter = peer_info.find(*peer); - if (iter != peer_info.end() && - (iter->second.is_empty() || iter->second.dne())) - continue; - if (!osdmap->exists(peer->osd)) - continue; - const osd_info_t &osd_info(osdmap->get_info(peer->osd)); - if (osd_info.lost_at <= osd_info.up_from) { - // If there is even one OSD in might_have_unfound that isn't lost, we - // still might retrieve our unfound. - return false; - } - } - dout(10) << "all_unfound_are_queried_or_lost all of might_have_unfound " << might_have_unfound - << " have been queried or are marked lost" << dendl; - return true; -} - void PG::clear_primary_state() { last_update_ondisk = eversion_t(); diff --git a/src/osd/PG.h b/src/osd/PG.h index 4306f0b84b6..76188e151c5 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -964,11 +964,15 @@ protected: friend class TestOpsSocketHook; void publish_stats_to_osd() override; - bool needs_recovery() const; - bool needs_backfill() const; - void try_mark_clean(); ///< mark an active pg clean + bool needs_recovery() const { + return recovery_state.needs_recovery(); + } + bool needs_backfill() const { + return recovery_state.needs_backfill(); + } + bool all_unfound_are_queried_or_lost(const OSDMapRef osdmap) const; virtual void dump_recovery_info(Formatter *f) const = 0; @@ -1115,16 +1119,6 @@ protected: uint64_t get_num_unfound() const { return missing_loc.num_unfound(); } - bool all_missing_unfound() const { - const auto& missing = pg_log.get_missing(); - if (!missing.have_missing()) - return false; - for (auto& m : missing.get_items()) { - if (!missing_loc.is_unfound(m.first)) - return false; - } - return true; - } virtual void check_local() = 0; diff --git a/src/osd/PeeringState.cc b/src/osd/PeeringState.cc index a61060ceb3f..4829edd7143 100644 --- a/src/osd/PeeringState.cc +++ b/src/osd/PeeringState.cc @@ -1025,6 +1025,95 @@ PastIntervals::PriorSet PeeringState::build_prior() return prior; } +bool PeeringState::needs_recovery() const +{ + ceph_assert(is_primary()); + + auto &missing = pg_log.get_missing(); + + if (missing.num_missing()) { + dout(10) << __func__ << " primary has " << missing.num_missing() + << " missing" << dendl; + return true; + } + + ceph_assert(!acting_recovery_backfill.empty()); + set::const_iterator end = acting_recovery_backfill.end(); + set::const_iterator a = acting_recovery_backfill.begin(); + for (; a != end; ++a) { + if (*a == get_primary()) continue; + pg_shard_t peer = *a; + map::const_iterator pm = peer_missing.find(peer); + if (pm == peer_missing.end()) { + psdout(10) << __func__ << " osd." << peer << " doesn't have missing set" + << dendl; + continue; + } + if (pm->second.num_missing()) { + psdout(10) << __func__ << " osd." << peer << " has " + << pm->second.num_missing() << " missing" << dendl; + return true; + } + } + + psdout(10) << __func__ << " is recovered" << dendl; + return false; +} + +bool PeeringState::needs_backfill() const +{ + ceph_assert(is_primary()); + + // We can assume that only possible osds that need backfill + // are on the backfill_targets vector nodes. + set::const_iterator end = backfill_targets.end(); + set::const_iterator a = backfill_targets.begin(); + for (; a != end; ++a) { + pg_shard_t peer = *a; + map::const_iterator pi = peer_info.find(peer); + if (!pi->second.last_backfill.is_max()) { + psdout(10) << __func__ << " osd." << peer + << " has last_backfill " << pi->second.last_backfill << dendl; + return true; + } + } + + dout(10) << __func__ << " does not need backfill" << dendl; + return false; +} + +/* + * Returns true unless there is a non-lost OSD in might_have_unfound. + */ +bool PeeringState::all_unfound_are_queried_or_lost( + const OSDMapRef osdmap) const +{ + ceph_assert(is_primary()); + + set::const_iterator peer = might_have_unfound.begin(); + set::const_iterator mend = might_have_unfound.end(); + for (; peer != mend; ++peer) { + if (peer_missing.count(*peer)) + continue; + map::const_iterator iter = peer_info.find(*peer); + if (iter != peer_info.end() && + (iter->second.is_empty() || iter->second.dne())) + continue; + if (!osdmap->exists(peer->osd)) + continue; + const osd_info_t &osd_info(osdmap->get_info(peer->osd)); + if (osd_info.lost_at <= osd_info.up_from) { + // If there is even one OSD in might_have_unfound that isn't lost, we + // still might retrieve our unfound. + return false; + } + } + psdout(10) << "all_unfound_are_queried_or_lost all of might_have_unfound " + << might_have_unfound + << " have been queried or are marked lost" << dendl; + return true; +} + /*------------ Peering State Machine----------------*/ #undef dout_prefix @@ -1556,7 +1645,7 @@ PeeringState::Backfilling::react(const RemoteReservationRevoked &) DECLARE_LOCALS ps->state_set(PG_STATE_BACKFILL_WAIT); cancel_backfill(); - if (pg->needs_backfill()) { + if (ps->needs_backfill()) { return transit(); } else { // raced with MOSDPGBackfill::OP_BACKFILL_FINISH, ignore @@ -2302,7 +2391,7 @@ PeeringState::Recovered::Recovered(my_context ctx) DECLARE_LOCALS - ceph_assert(!pg->needs_recovery()); + ceph_assert(!ps->needs_recovery()); // if we finished backfill, all acting are active; recheck if // DEGRADED | UNDERSIZED is appropriate. @@ -2497,7 +2586,7 @@ boost::statechart::result PeeringState::Active::react(const ActMap&) uint64_t unfound = ps->missing_loc.num_unfound(); if (unfound > 0 && - pg->all_unfound_are_queried_or_lost(ps->get_osdmap())) { + ps->all_unfound_are_queried_or_lost(ps->get_osdmap())) { if (ps->cct->_conf->osd_auto_mark_unfound_lost) { pl->get_clog().error() << context< PeeringMachine >().spgid.pgid << " has " << unfound << " objects unfound and apparently lost, would automatically " diff --git a/src/osd/PeeringState.h b/src/osd/PeeringState.h index ae06a29396f..b89f1f6780a 100644 --- a/src/osd/PeeringState.h +++ b/src/osd/PeeringState.h @@ -1453,6 +1453,20 @@ public: return info; } + bool needs_recovery() const; + bool needs_backfill() const; + bool all_unfound_are_queried_or_lost(const OSDMapRef osdmap) const; + bool all_missing_unfound() const { + const auto& missing = pg_log.get_missing(); + if (!missing.have_missing()) + return false; + for (auto& m : missing.get_items()) { + if (!missing_loc.is_unfound(m.first)) + return false; + } + return true; + } + // Flush control interface private: void start_flush(ObjectStore::Transaction *t) { diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index 9f46fa3c1ff..09f6845e6c9 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -1091,7 +1091,7 @@ int PrimaryLogPG::do_command( return 0; // make command idempotent } - if (!all_unfound_are_queried_or_lost(get_osdmap())) { + if (!recovery_state.all_unfound_are_queried_or_lost(get_osdmap())) { ss << "pg has " << unfound << " unfound objects but we haven't probed all sources, not marking lost"; return -EINVAL; @@ -12431,7 +12431,8 @@ bool PrimaryLogPG::start_recovery_ops( } if (!missing.have_missing() || // Primary does not have missing - all_missing_unfound()) { // or all of the missing objects are unfound. + // or all of the missing objects are unfound. + recovery_state.all_missing_unfound()) { // Recover the replicas. started = recover_replicas(max, handle, &recovery_started); }