}
bool is_boot(mds_rank_t m) const { return get_state(m) == STATE_BOOT; }
+ bool is_bootstrapping(mds_rank_t m) const {
+ return is_creating(m) || is_starting(m) || is_replay(m);
+ }
bool is_creating(mds_rank_t m) const { return get_state(m) == STATE_CREATING; }
bool is_starting(mds_rank_t m) const { return get_state(m) == STATE_STARTING; }
bool is_replay(mds_rank_t m) const { return get_state(m) == STATE_REPLAY; }
c->send_message2(m);
}
+class C_MDS_RetrySendMessageMDS : public MDSInternalContext {
+public:
+ C_MDS_RetrySendMessageMDS(MDSRank* mds, mds_rank_t who, ref_t<Message> m)
+ : MDSInternalContext(mds), who(who), m(std::move(m)) {}
+ void finish(int r) override {
+ mds->send_message_mds(m, who);
+ }
+private:
+ mds_rank_t who;
+ ref_t<Message> m;
+};
+
void MDSRank::send_message_mds(const ref_t<Message>& m, mds_rank_t mds)
{
if (!mdsmap->is_up(mds)) {
dout(10) << "send_message_mds mds." << mds << " not up, dropping " << *m << dendl;
return;
+ } else if (mdsmap->is_bootstrapping(mds)) {
+ dout(5) << __func__ << "mds." << mds << " is bootstrapping, deferring " << *m << dendl;
+ wait_for_bootstrapped_peer(mds, new C_MDS_RetrySendMessageMDS(this, mds, m));
+ return;
}
// send mdsmap first?
}
}
+ // did someone leave a "bootstrapping" state? We can't connect until then to
+ // allow messenger "myname" updates.
+ {
+ std::vector<mds_rank_t> erase;
+ for (auto& [rank, queue] : waiting_for_bootstrapping_peer) {
+ auto state = mdsmap->get_state(rank);
+ if (state > MDSMap::STATE_REPLAY) {
+ queue_waiters(queue);
+ erase.push_back(rank);
+ }
+ }
+ for (const auto& rank : erase) {
+ waiting_for_bootstrapping_peer.erase(rank);
+ }
+ }
// for testing...
if (unlikely(g_conf().get_val<bool>("mds_connect_bootstrapping"))) {
std::set<mds_rank_t> bootstrapping;
void send_message_client(const ref_t<Message>& m, Session* session);
void send_message(const ref_t<Message>& m, const ConnectionRef& c);
+ void wait_for_bootstrapped_peer(mds_rank_t who, MDSContext *c) {
+ waiting_for_bootstrapping_peer[who].push_back(c);
+ }
void wait_for_active_peer(mds_rank_t who, MDSContext *c) {
waiting_for_active_peer[who].push_back(c);
}
bool replaying_requests_done = false;
map<mds_rank_t, MDSContext::vec> waiting_for_active_peer;
+ map<mds_rank_t, MDSContext::vec> waiting_for_bootstrapping_peer;
map<epoch_t, MDSContext::vec> waiting_for_mdsmap;
epoch_t osd_epoch_barrier = 0;