When handling master request with slaves, the mds could crash
after receiving all slaves' commit acknowledgement, but before
journalling the ECommitted. Current MDS recovery code does not
handle this case correctly, the request will be left in
LogSegment's uncommitted_masters after recovery is finished.
It prevents LogSegment from being trimmed. The fix is find and
clean up request of this kind when recovery enters rejoin stage.
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Signed-off-by: Sage Weil <sage@inktank.com>
}
+/*
+ * The mds could crash after receiving all slaves' commit acknowledgement,
+ * but before journalling the ECommitted.
+ */
+void MDCache::finish_committed_masters()
+{
+ map<metareqid_t, umaster>::iterator p = uncommitted_masters.begin();
+ while (p != uncommitted_masters.end()) {
+ if (p->second.slaves.empty()) {
+ metareqid_t reqid = p->first;
+ dout(10) << "finish_committed_masters " << reqid << dendl;
+ ++p;
+ log_master_commit(reqid);
+ } else {
+ ++p;
+ }
+ }
+}
/*
* at end of resolve... we must journal a commit|abort for all slave
void log_master_commit(metareqid_t reqid);
void _logged_master_commit(metareqid_t reqid, LogSegment *ls, list<Context*> &waiters);
void committed_master_slave(metareqid_t r, int from);
+ void finish_committed_masters();
void _logged_slave_commit(int from, metareqid_t reqid);
void MDS::rejoin_joint_start()
{
dout(1) << "rejoin_joint_start" << dendl;
+ mdcache->finish_committed_masters();
mdcache->rejoin_send_rejoins();
}
void MDS::rejoin_done()