projected = version;
}
+void SessionMap::replay_open_sessions(version_t event_cmapv,
+ map<client_t,entity_inst_t>& client_map,
+ map<client_t,client_metadata_t>& client_metadata_map)
+{
+ unsigned already_saved;
+
+ if (version + client_map.size() < event_cmapv)
+ goto bad;
+
+ // Server::finish_force_open_sessions() marks sessions dirty one by one.
+ // Marking a session dirty may flush all existing dirty sessions. So it's
+ // possible that some sessions are already saved in sessionmap.
+ already_saved = client_map.size() - (event_cmapv - version);
+ for (const auto& p : client_map) {
+ Session *s = get_or_add_session(p.second);
+ auto q = client_metadata_map.find(p.first);
+ if (q != client_metadata_map.end())
+ s->info.client_metadata.merge(q->second);
+
+ if (already_saved > 0) {
+ if (s->is_closed())
+ goto bad;
+
+ --already_saved;
+ continue;
+ }
+
+ set_state(s, Session::STATE_OPEN);
+ replay_dirty_session(s);
+ }
+ return;
+
+bad:
+ mds->clog->error() << "error replaying open sessions(" << client_map.size()
+ << ") sessionmap v " << event_cmapv << " table " << version;
+ ceph_assert(g_conf()->mds_wipe_sessions);
+ mds->sessionmap.wipe();
+ mds->sessionmap.set_version(event_cmapv);
+}
+
version_t SessionMap::mark_projected(Session *s)
{
dout(20) << __func__ << " s=" << s << " name=" << s->info.inst.name
get_client_sessions(f);
}
- void replay_open_sessions(version_t event_cmapv,
- map<client_t,entity_inst_t>& client_map,
- map<client_t,client_metadata_t>& client_metadata_map) {
- // Server::finish_force_open_sessions() marks sessions dirty one by one.
- // Marking a session dirty may flush all existing dirty sessions. So it's
- // possible that some sessions are already saved in sessionmap.
- ceph_assert(version + client_map.size() >= event_cmapv);
- unsigned already_saved = client_map.size() - (event_cmapv - version);
- for (map<client_t,entity_inst_t>::iterator p = client_map.begin();
- p != client_map.end();
- ++p) {
- Session *s = get_or_add_session(p->second);
- auto q = client_metadata_map.find(p->first);
- if (q != client_metadata_map.end())
- s->info.client_metadata.merge(q->second);
-
- if (already_saved > 0) {
- ceph_assert(s->is_open());
- --already_saved;
- continue;
- }
-
- set_state(s, Session::STATE_OPEN);
- replay_dirty_session(s);
- }
- }
-
// helpers
entity_inst_t& get_inst(entity_name_t w) {
ceph_assert(session_map.count(w));
*/
void replay_advance_version();
+ /**
+ * During replay, open sessions, advance versions and
+ * mark these sessions as dirty.
+ */
+ void replay_open_sessions(version_t event_cmapv,
+ map<client_t,entity_inst_t>& client_map,
+ map<client_t,client_metadata_t>& client_metadata_map);
+
/**
* For these session IDs, if a session exists with this ID, and it has
* dirty completed_requests, then persist it immediately
}
}
if (sessionmapv) {
+ unsigned diff = (used_preallocated_ino && !preallocated_inos.empty()) ? 2 : 1;
if (mds->sessionmap.get_version() >= sessionmapv) {
dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv
<< " <= table " << mds->sessionmap.get_version() << dendl;
- } else if (mds->sessionmap.get_version() + 2 >= sessionmapv) {
+ } else if (mds->sessionmap.get_version() + diff == sessionmapv) {
dout(10) << "EMetaBlob.replay sessionmap v " << sessionmapv
- << " -(1|2) == table " << mds->sessionmap.get_version()
+ << " - " << diff << " == table " << mds->sessionmap.get_version()
<< " prealloc " << preallocated_inos
<< " used " << used_preallocated_ino
<< dendl;
} else {
dout(10) << "EMetaBlob.replay no session for " << client_name << dendl;
- if (used_preallocated_ino) {
+ if (used_preallocated_ino)
mds->sessionmap.replay_advance_version();
- }
+
if (!preallocated_inos.empty())
mds->sessionmap.replay_advance_version();
}
ceph_assert(sessionmapv == mds->sessionmap.get_version());
} else {
- mds->clog->error() << "journal replay sessionmap v " << sessionmapv
- << " -(1|2) > table " << mds->sessionmap.get_version();
+ mds->clog->error() << "EMetaBlob.replay sessionmap v " << sessionmapv
+ << " - " << diff << " > table " << mds->sessionmap.get_version();
ceph_assert(g_conf()->mds_wipe_sessions);
mds->sessionmap.wipe();
mds->sessionmap.set_version(sessionmapv);
if (mds->sessionmap.get_version() >= cmapv) {
dout(10) << "ESession.replay sessionmap " << mds->sessionmap.get_version()
<< " >= " << cmapv << ", noop" << dendl;
- } else {
+ } else if (mds->sessionmap.get_version() + 1 == cmapv) {
dout(10) << "ESession.replay sessionmap " << mds->sessionmap.get_version()
<< " < " << cmapv << " " << (open ? "open":"close") << " " << client_inst << dendl;
Session *session;
mds->sessionmap.replay_advance_version();
}
ceph_assert(mds->sessionmap.get_version() == cmapv);
+ } else {
+ mds->clog->error() << "ESession.replay sessionmap v " << cmapv
+ << " - 1 > table " << mds->sessionmap.get_version();
+ ceph_assert(g_conf()->mds_wipe_sessions);
+ mds->sessionmap.wipe();
+ mds->sessionmap.set_version(cmapv);
}
if (inos.size() && inotablev) {