int oldacker = pg->get_acker();
vector<int> oldacting = pg->acting;
+ pg->clear_prior();
+
// update PG
pg->acting.swap(tacting);
pg->set_role(role);
// deactivate.
pg->state_clear(PG_STATE_ACTIVE);
pg->state_clear(PG_STATE_DOWN);
+ pg->state_clear(PG_STATE_PEERING); // we'll need to restart peering
if (pg->is_primary() &&
pg->info.pgid.size() != pg->acting.size())
if (!pg->info.dead_snaps.empty())
pg->queue_snap_trim();
}
- else if (pg->is_primary() && !pg->is_active()) {
+ else if (pg->is_primary() &&
+ !pg->is_active()) {
// i am (inactive) primary
- pg->build_prior();
- pg->peer(t, query_map, &info_map);
+ if (!pg->is_peering())
+ pg->peer(t, query_map, &info_map);
}
else if (pg->is_stray() &&
pg->get_primary() >= 0) {
pg->set_role(role);
pg->info.history = history;
pg->clear_primary_state(); // yep, notably, set hml=false
- pg->build_prior();
pg->write_info(t);
pg->write_log(t);
}
if (pg->is_all_uptodate())
pg->finish_recovery();
} else {
- pg->build_prior();
pg->peer(t, query_map, &info_map);
}
pg->update_stats();
return false;
}
+void PG::clear_prior()
+{
+ dout(10) << "clear_prior" << dendl;
+ prior_set.clear();
+ prior_set_down.clear();
+ prior_set_up_thru.clear();
+ must_notify_mon = false;
+}
+
+
void PG::build_prior()
{
if (1) {
* intervene in some as-yet-undetermined way. :)
*/
- // build prior set.
- prior_set.clear();
- prior_set_down.clear();
- prior_set_up_thru.clear();
+ clear_prior();
// current nodes, of course.
for (unsigned i=1; i<acting.size(); i++)
bool any_up_now = false;
bool some_down = false;
- must_notify_mon = false;
-
// generate past intervals, if we don't have them.
if (info.history.same_since > info.history.last_epoch_started &&
(past_intervals.empty() ||
map< int, map<pg_t,Query> >& query_map,
map<int, MOSDPGInfo*> *activator_map)
{
- dout(10) << "peer. acting is " << acting
- << ", prior_set is " << prior_set << dendl;
+ dout(10) << "peer acting is " << acting << dendl;
+
+ if (!is_active())
+ state_set(PG_STATE_PEERING);
+
+ if (prior_set.empty())
+ build_prior();
+ dout(10) << "peer prior_set is " << prior_set << dendl;
+
/** GET ALL PG::Info *********/
state_set(PG_STATE_ACTIVE);
state_clear(PG_STATE_STRAY);
state_clear(PG_STATE_DOWN);
+ state_clear(PG_STATE_PEERING);
if (is_crashed()) {
//assert(is_replay()); // HELP.. not on replica?
state_clear(PG_STATE_CRASHED);
state_set(PG_STATE_DEGRADED);
else
state_clear(PG_STATE_DEGRADED);
-
+
info.history.last_epoch_started = osd->osdmap->get_epoch();
trim_past_intervals();
}
stray_set.clear();
+
+ // clear _requested maps; we may have to peer() again if we discover
+ // (more) stray content
+ peer_info_requested.clear();
+ peer_log_requested.clear();
+ peer_summary_requested.clear();
}
void generate_past_intervals();
void trim_past_intervals();
void build_prior();
+ void clear_prior();
bool prior_set_affected(OSDMap *map);
bool adjust_peers_complete_thru() {
int get_state() const { return state; }
bool is_active() const { return state_test(PG_STATE_ACTIVE); }
+ bool is_peering() const { return state_test(PG_STATE_PEERING); }
bool is_crashed() const { return state_test(PG_STATE_CRASHED); }
bool is_down() const { return state_test(PG_STATE_DOWN); }
bool is_replay() const { return state_test(PG_STATE_REPLAY); }
#define PG_STATE_SCRUBBING 256 // scrubbing
#define PG_STATE_SCRUBQ 512 // queued for scrub
#define PG_STATE_DEGRADED 1024 // pg membership not complete
+#define PG_STATE_INCONSISTENT 2048 // pg replicas are inconsistent (but shouldn't be)
+#define PG_STATE_REPAIR 2048 // pg should repair on next scrub
+#define PG_STATE_PEERING 4096
static inline std::string pg_state_string(int state) {
std::string st;
if (state & PG_STATE_DEGRADED) st += "degraded+";
if (state & PG_STATE_SCRUBBING) st += "scrubbing+";
if (state & PG_STATE_SCRUBQ) st += "scrubq+";
+ if (state & PG_STATE_INCONSISTENT) st += "inconsistent+";
+ if (state & PG_STATE_REPAIR) st += "repair+";
+ if (state & PG_STATE_PEERING) st += "peering+";
if (!st.length())
st = "inactive";
else