}
}
}
-
+
// did a significant osd's up_thru change?
for (map<int,epoch_t>::const_iterator p = prior.up_thru.begin();
p != prior.up_thru.end();
return false;
}
+bool PG::adjust_need_up_thru(PgPriorSet &prior, const OSDMap *osdmap)
+{
+ epoch_t up_thru = osd->osdmap->get_up_thru(osd->whoami);
+ if (need_up_thru &&
+ up_thru >= info.history.same_acting_since) {
+ dout(10) << "adjust_need_up_thru now " << up_thru << ", need_up_thru now false" << dendl;
+ need_up_thru = false;
+ return true;
+ }
+ return false;
+}
+
/*
* Returns true unless there is a non-lost OSD in might_have_unfound.
*/
}
if (prior.some_down) {
- need_up_thru = true;
for (vector<Interval>::iterator i = prior.inter_up_thru.begin();
i != prior.inter_up_thru.end();
++i) {
prior.up_thru[i->acting[0]] = lastmap->get_up_thru(i->acting[0]);
}
}
+
+ // NOTE: we can skip the up_thru check if this is a new PG and there
+ // were no prior intervals.
+ if (info.history.epoch_created < info.history.same_acting_since &&
+ osd->osdmap->get_up_thru(osd->whoami) < info.history.same_acting_since) {
+ dout(10) << "up_thru " << osd->osdmap->get_up_thru(osd->whoami)
+ << " < same_since " << info.history.same_acting_since
+ << ", must notify monitor" << dendl;
+ need_up_thru = true;
+ } else {
+ dout(10) << "up_thru " << osd->osdmap->get_up_thru(osd->whoami)
+ << " >= same_since " << info.history.same_acting_since
+ << ", all is well" << dendl;
+ }
}
void PG::clear_primary_state()
pg->state_set(PG_STATE_PEERING);
}
-boost::statechart::result
-PG::RecoveryState::Peering::react(const AdvMap& advmap) {
+boost::statechart::result PG::RecoveryState::Peering::react(const AdvMap& advmap)
+{
PG *pg = context< RecoveryMachine >().pg;
dout(10) << "Peering advmap" << dendl;
if (pg->prior_set_affected(*prior_set.get(), &advmap.osdmap)) {
post_event(advmap);
return transit< Reset >();
}
+
+ pg->adjust_need_up_thru(*prior_set.get(), &advmap.osdmap);
+
return forward_event();
}
}
/*--------GetInfo---------*/
-PG::RecoveryState::GetInfo::GetInfo(my_context ctx) : my_base(ctx) {
+PG::RecoveryState::GetInfo::GetInfo(my_context ctx) : my_base(ctx)
+{
state_name = "Started/Primary/Peering/GetInfo";
context< RecoveryMachine >().log_enter(state_name);
if (!prior_set.get())
pg->build_prior(prior_set);
- if (pg->need_up_thru) {
- post_event(NeedNewMap());
- } else {
- get_infos();
- }
+ if (pg->need_up_thru)
+ pg->osd->queue_want_up_thru(pg->info.history.same_acting_since);
+
+ get_infos();
}
-void PG::RecoveryState::GetInfo::get_infos() {
+void PG::RecoveryState::GetInfo::get_infos()
+{
PG *pg = context< RecoveryMachine >().pg;
auto_ptr<PgPriorSet> &prior_set = context< Peering >().prior_set;
}
}
-boost::statechart::result
-PG::RecoveryState::GetInfo::react(const MNotifyRec& infoevt) {
+boost::statechart::result PG::RecoveryState::GetInfo::react(const MNotifyRec& infoevt)
+{
set<int>::iterator p = peer_info_requested.find(infoevt.from);
if (p != peer_info_requested.end())
peer_info_requested.erase(p);
// can infer the rest!
dout(10) << " osd" << *i << " has no missing, identical log" << dendl;
pg->peer_missing[*i];
- pg->search_for_missing(pg->peer_info[*i], &pg->peer_missing[*i], *i);
+ pg->search_for_missing(pi, &pg->peer_missing[*i], *i);
continue;
}
}
if (peer_missing_requested.empty()) {
+ if (pg->need_up_thru) {
+ dout(10) << " still need up_thru update before going active" << dendl;
+ post_event(NeedUpThru());
+ return;
+ }
+
+ // all good!
post_event(Activate());
}
}
context< RecoveryMachine >().log_exit(state_name, enter_time);
}
+/*------WaitUpThru--------*/
+PG::RecoveryState::WaitUpThru::WaitUpThru(my_context ctx) : my_base(ctx)
+{
+ state_name = "Started/Primary/Peering/WaitUpThru";
+ context< RecoveryMachine >().log_enter(state_name);
+}
+
+boost::statechart::result PG::RecoveryState::WaitUpThru::react(const ActMap& am) {
+ PG *pg = context< RecoveryMachine >().pg;
+ if (!pg->need_up_thru) {
+ post_event(Activate());
+ return discard_event();
+ }
+ return forward_event();
+}
+
+boost::statechart::result PG::RecoveryState::WaitUpThru::react(const MLogRec& logevt)
+{
+ dout(10) << "searching osd" << logevt.from
+ << " log for unfound items" << dendl;
+ PG *pg = context< RecoveryMachine >().pg;
+ bool got_missing = pg->search_for_missing(logevt.msg->info,
+ &pg->missing, logevt.from);
+
+ // hmm.. should we?
+ (void)got_missing;
+ //if (got_missing)
+ //pg->osd->queue_for_recovery(pg);
+
+ return discard_event();
+}
+
+void PG::RecoveryState::WaitUpThru::exit() {
+ context< RecoveryMachine >().log_exit(state_name, enter_time);
+}
/*----RecoveryState::RecoveryMachine Methods-----*/
#undef dout_prefix
struct Load : boost::statechart::event< Load > {
Load() : boost::statechart::event< Load >() {}
};
+ struct GotInfo : boost::statechart::event< GotInfo > {
+ GotInfo() : boost::statechart::event< GotInfo >() {}
+ };
+ struct NeedUpThru : boost::statechart::event< NeedUpThru > {
+ NeedUpThru() : boost::statechart::event< NeedUpThru >() {};
+ };
/* States */
};
struct GetLog;
- struct GotInfo : boost::statechart::event< GotInfo > {
- GotInfo() : boost::statechart::event< GotInfo >() {}
- };
struct GetInfo : boost::statechart::state< GetInfo, Peering >, NamedState {
set<int> peer_info_requested;
boost::statechart::result react(const BacklogComplete&);
};
+ struct WaitUpThru;
+
struct GetMissing : boost::statechart::state< GetMissing, Peering >, NamedState {
set<int> peer_missing_requested;
void exit();
typedef boost::mpl::list <
- boost::statechart::custom_reaction< MLogRec >
+ boost::statechart::custom_reaction< MLogRec >,
+ boost::statechart::transition< NeedUpThru, WaitUpThru >
> reactions;
boost::statechart::result react(const MLogRec& logevt);
};
+ struct WaitUpThru : boost::statechart::state< WaitUpThru, Peering >, NamedState {
+ WaitUpThru(my_context ctx);
+ void exit();
+
+ typedef boost::mpl::list <
+ boost::statechart::custom_reaction< ActMap >,
+ boost::statechart::custom_reaction< MLogRec >
+ > reactions;
+ boost::statechart::result react(const ActMap& am);
+ boost::statechart::result react(const MLogRec& logrec);
+ };
+
+
RecoveryMachine machine;
PG *pg;
RecoveryCtx *rctx;
void clear_prior();
bool prior_set_affected(PgPriorSet &prior, const OSDMap *osdmap) const;
+ bool adjust_need_up_thru(PgPriorSet &prior, const OSDMap *osdmap);
+
bool all_unfound_are_lost(const OSDMap* osdmap) const;
void mark_obj_as_lost(ObjectStore::Transaction& t,
const sobject_t &lost_soid);