MDCache::MDCache(MDS *m) :
logger(0),
filer(m->objecter, &m->finisher),
+ rejoin_done(NULL),
+ resolve_done(NULL),
recovery_queue(m),
stray_manager(m)
{
delete logger;
logger = 0;
}
+
+ delete rejoin_done;
+ delete resolve_done;
//delete renamer;
}
}
-void MDCache::resolve_start()
+void MDCache::resolve_start(MDSInternalContext *resolve_done_)
{
dout(10) << "resolve_start" << dendl;
+ resolve_done = resolve_done_;
if (mds->mdsmap->get_root() != mds->whoami) {
// if we don't have the root dir, adjust it to UNKNOWN. during
if (mds->is_resolve()) {
trim_unlinked_inodes();
recalc_auth_bits(false);
- mds->resolve_done();
+ resolve_done->complete(0);
+ resolve_done = NULL;
} else {
maybe_send_pending_rejoins();
}
* after recovery.
*/
-void MDCache::rejoin_start()
+void MDCache::rejoin_start(MDSInternalContext *rejoin_done_)
{
dout(10) << "rejoin_start" << dendl;
+ rejoin_done = rejoin_done_;
rejoin_gather = recovery_set;
// need finish opening cap inodes before sending cache rejoins
do_delayed_cap_imports();
start_files_to_recover(rejoin_recover_q, rejoin_check_q);
- mds->rejoin_done();
+ assert(rejoin_done);
+ rejoin_done->complete(0);
+ rejoin_done = NULL;
}
}
}
void cancel_ambiguous_import(CDir *);
void finish_ambiguous_import(dirfrag_t dirino);
- void resolve_start();
+ void resolve_start(MDSInternalContext *resolve_done_);
void send_resolves();
void send_slave_resolves();
void send_subtree_resolves();
if (rejoins_pending)
rejoin_send_rejoins();
}
+ MDSInternalContext *rejoin_done;
+ MDSInternalContext *resolve_done;
public:
- void rejoin_start();
+ void rejoin_start(MDSInternalContext *rejoin_done_);
void rejoin_gather_finish();
void rejoin_send_rejoins();
void rejoin_export_caps(inodeno_t ino, client_t client, ceph_mds_cap_reconnect& capinfo,
}
}
+/**
+ * Helper for simple callbacks that call a void fn with no args.
+ */
+class C_VoidFn : public MDSInternalContext
+{
+ typedef void (MDS::*fn_ptr)();
+ protected:
+ MDS *mds_daemon;
+ fn_ptr fn;
+ public:
+ C_VoidFn(MDS *mds_, fn_ptr fn_)
+ : MDSInternalContext(mds_), mds_daemon(mds_), fn(fn_)
+ {
+ assert(mds_);
+ assert(fn_);
+ }
+
+ void finish(int r)
+ {
+ (mds_daemon->*fn)();
+ }
+};
+
void MDS::reopen_log()
{
dout(1) << "reopen_log" << dendl;
reopen_log();
- mdcache->resolve_start();
+ mdcache->resolve_start(new C_VoidFn(this, &MDS::resolve_done));
finish_contexts(g_ceph_context, waiting_for_resolve);
}
void MDS::resolve_done()
if (last_state == MDSMap::STATE_REPLAY)
reopen_log();
- server->reconnect_clients();
+ server->reconnect_clients(new C_VoidFn(this, &MDS::reconnect_done));
finish_contexts(g_ceph_context, waiting_for_reconnect);
}
void MDS::reconnect_done()
void MDS::rejoin_start()
{
dout(1) << "rejoin_start" << dendl;
- mdcache->rejoin_start();
+ mdcache->rejoin_start(new C_VoidFn(this, &MDS::rejoin_done));
}
void MDS::rejoin_done()
{
void reopen_log();
+ protected:
void resolve_start();
void resolve_done();
void reconnect_start();
void active_start();
void stopping_start();
void stopping_done();
+ public:
void handle_mds_recovery(mds_rank_t who);
void handle_mds_failure(mds_rank_t who);
finish_flush_session(session, session->get_push_seq());
}
-void Server::reconnect_clients()
+void Server::reconnect_clients(MDSInternalContext *reconnect_done_)
{
+ reconnect_done = reconnect_done_;
mds->sessionmap.get_client_set(client_reconnect_gather);
if (client_reconnect_gather.empty()) {
void Server::reconnect_gather_finish()
{
dout(7) << "reconnect_gather_finish. failed on " << failed_reconnects << " clients" << dendl;
- mds->reconnect_done();
+ assert(reconnect_done);
+ reconnect_done->complete(0);
+ reconnect_done = NULL;
}
void Server::reconnect_tick()
// OSDMap full status, used to generate ENOSPC on some operations
bool is_full;
-public:
+ // State for while in reconnect
+ MDSInternalContext *reconnect_done;
int failed_reconnects;
+public:
bool terminating_sessions;
Server(MDS *m) :
messenger(mds->messenger),
logger(0),
is_full(false),
+ reconnect_done(NULL),
failed_reconnects(0),
terminating_sessions(false) {
}
~Server() {
g_ceph_context->get_perfcounters_collection()->remove(logger);
delete logger;
+ delete reconnect_done;
}
void create_logger();
void find_idle_sessions();
void kill_session(Session *session, Context *on_safe);
void journal_close_session(Session *session, int state, Context *on_safe);
- void reconnect_clients();
+ void reconnect_clients(MDSInternalContext *reconnect_done_);
void handle_client_reconnect(class MClientReconnect *m);
//void process_reconnect_cap(CInode *in, int from, ceph_mds_cap_reconnect& capinfo);
void reconnect_gather_finish();