From cd0c8fb324c08814643c420427d93a539ee0e8b0 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 6 Dec 2011 16:00:48 -0800 Subject: [PATCH] osd: add incomplete, backfill states; simplify calculation Set/clear states in peering state machine state ctor/dtors where possible. Set degraded if the number of non-backfilling replicas is lower than the target replication factor. Signed-off-by: Sage Weil --- src/osd/PG.cc | 46 +++++++++++++++++++++++++++++--------------- src/osd/osd_types.cc | 4 ++++ src/osd/osd_types.h | 4 +++- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 0188d4a04c6c4..904c2b8f4fa0a 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -1142,12 +1142,6 @@ void PG::activate(ObjectStore::Transaction& t, list& tfin, state_set(PG_STATE_ACTIVE); state_clear(PG_STATE_STRAY); state_clear(PG_STATE_DOWN); - state_clear(PG_STATE_PEERING); - if (is_primary() && - get_osdmap()->get_pg_size(info.pgid) != acting.size()) - state_set(PG_STATE_DEGRADED); - else - state_clear(PG_STATE_DEGRADED); if (is_primary()) { // If necessary, create might_have_unfound to help us find our unfound objects. @@ -1224,6 +1218,10 @@ void PG::activate(ObjectStore::Transaction& t, list& tfin, // if primary.. if (is_primary()) { // start up replicas + + // count replicas that are not backfilling + int active = 1; + for (unsigned i=1; i& tfin, pi.log_tail = info.last_update; pi.last_backfill = hobject_t(); pi.history = info.history; + state_set(PG_STATE_BACKFILL); peer_missing[peer].clear(); @@ -1274,6 +1273,11 @@ void PG::activate(ObjectStore::Transaction& t, list& tfin, m->log.copy_after(log, pi.last_update); } + if (pi.last_backfill != hobject_t::get_max()) + state_set(PG_STATE_BACKFILL); + else + active++; + Missing& pm = peer_missing[peer]; // update local version of peer's missing list! @@ -1304,6 +1308,10 @@ void PG::activate(ObjectStore::Transaction& t, list& tfin, } } + // degraded? + if (get_osdmap()->get_pg_size(info.pgid) != active) + state_set(PG_STATE_DEGRADED); + // all clean? if (is_all_uptodate()) finish_recovery(t, tfin); @@ -3267,17 +3275,9 @@ void PG::start_peering_interval(const OSDMapRef lastmap, // deactivate. state_clear(PG_STATE_ACTIVE); state_clear(PG_STATE_DOWN); - state_clear(PG_STATE_PEERING); // we'll need to restart peering - state_clear(PG_STATE_DEGRADED); - state_clear(PG_STATE_REPLAY); peer_missing.clear(); - if (is_primary()) { - if (osdmap->get_pg_size(info.pgid) != acting.size()) - state_set(PG_STATE_DEGRADED); - } - // reset primary state? if (oldrole == 0 || get_role() == 0) clear_primary_state(); @@ -3779,7 +3779,6 @@ boost::statechart::result PG::RecoveryState::Peering::react(const AdvMap& advmap dout(10) << "Peering advmap" << dendl; if (prior_set.get()->affected_by_map(advmap.osdmap, pg)) { dout(1) << "Peering, affected_by_map, going to Reset" << dendl; - pg->state_clear(PG_STATE_PEERING); post_event(advmap); return transit< Reset >(); } @@ -3793,6 +3792,8 @@ void PG::RecoveryState::Peering::exit() { dout(10) << "Leaving Peering" << dendl; context< RecoveryMachine >().log_exit(state_name, enter_time); + PG *pg = context< RecoveryMachine >().pg; + pg->state_clear(PG_STATE_PEERING); } /*---------Active---------*/ @@ -3933,8 +3934,13 @@ boost::statechart::result PG::RecoveryState::Active::react(const BackfillComplet } void PG::RecoveryState::Active::exit() - { +{ context< RecoveryMachine >().log_exit(state_name, enter_time); + PG *pg = context< RecoveryMachine >().pg; + + pg->state_clear(PG_STATE_DEGRADED); + pg->state_clear(PG_STATE_BACKFILL); + pg->state_clear(PG_STATE_REPLAY); } /*------ReplicaActive-----*/ @@ -4267,10 +4273,18 @@ PG::RecoveryState::Incomplete::Incomplete(my_context ctx) { state_name = "Started/Primary/Peering/Incomplete"; context< RecoveryMachine >().log_enter(state_name); + PG *pg = context< RecoveryMachine >().pg; + + pg->state_clear(PG_STATE_PEERING); + pg->state_set(PG_STATE_INCOMPLETE); + pg->update_stats(); } void PG::RecoveryState::Incomplete::exit() { context< RecoveryMachine >().log_exit(state_name, enter_time); + PG *pg = context< RecoveryMachine >().pg; + + pg->state_clear(PG_STATE_INCOMPLETE); } /*------GetMissing--------*/ diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index c5a87ad26cdc6..43568cfa5232b 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -190,6 +190,10 @@ std::string pg_state_string(int state) oss << "peering+"; if (state & PG_STATE_REPAIR) oss << "repair+"; + if (state & PG_STATE_BACKFILL) + oss << "backfill+"; + if (state & PG_STATE_INCOMPLETE) + oss << "incomplete+"; string ret(oss.str()); if (ret.length() > 0) ret.resize(ret.length() - 1); diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index 61ef74645fe01..9e5cdfd1292e7 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -502,7 +502,9 @@ inline ostream& operator<<(ostream& out, const osd_stat_t& s) { #define PG_STATE_INCONSISTENT (1<<11) // pg replicas are inconsistent (but shouldn't be) #define PG_STATE_PEERING (1<<12) // pg is (re)peering #define PG_STATE_REPAIR (1<<13) // pg should repair on next scrub -//#define PG_STATE_SCANNING (1<<14) // scanning content to generate backlog +//PG_STATE_SCANNING (1<<14) .. deprecated. +#define PG_STATE_BACKFILL (1<<15) // [active] backfilling pg content +#define PG_STATE_INCOMPLETE (1<<16) // incomplete content, peering failed. std::string pg_state_string(int state); -- 2.39.5