summaryrefslogtreecommitdiff
path: root/src/mds/SessionMap.cc
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-02-25 15:50:09 -0800
committerSage Weil <sage@newdream.net>2010-02-26 13:14:29 -0800
commit155abb477215c472602929c49011c1b0d9ecd186 (patch)
tree5d20c63c90534a364c90d44060e1b01e58777a45 /src/mds/SessionMap.cc
parenta0e55647c5d74609d40ba99bc736c054c2253aa3 (diff)
downloadceph-155abb477215c472602929c49011c1b0d9ecd186.tar.gz
mds: revise mds sessionmap encoding [disk format change]
Encode session name before session itself, so that we can use an existing session instead of allocating a new one. This lets us keep eagerly reconnecting clients that connect before we load the sessionmap. Add proper struct_v. Drop useless/incorrect 'n' value. Continue to read old format, of course. Some minor hackery because we didn't have a struct_v before.
Diffstat (limited to 'src/mds/SessionMap.cc')
-rw-r--r--src/mds/SessionMap.cc68
1 files changed, 49 insertions, 19 deletions
diff --git a/src/mds/SessionMap.cc b/src/mds/SessionMap.cc
index 5244ab147c3..d3da3cee6ca 100644
--- a/src/mds/SessionMap.cc
+++ b/src/mds/SessionMap.cc
@@ -145,12 +145,13 @@ void SessionMap::_save_finish(version_t v)
void SessionMap::encode(bufferlist& bl)
{
- ::encode(version, bl);
+ __u64 pre = -1; // for 0.19 compatibility; we forgot an encoding prefix.
+ ::encode(pre, bl);
+
+ __u8 struct_v = 2;
+ ::encode(struct_v, bl);
- // this is a meaningless upper bound, because we don't include all
- // sessions below. it can be ignored by decode().
- __u32 n = session_map.size();
- ::encode(n, bl);
+ ::encode(version, bl);
for (hash_map<entity_name_t,Session*>::iterator p = session_map.begin();
p != session_map.end();
@@ -159,25 +160,54 @@ void SessionMap::encode(bufferlist& bl)
p->second->is_closing() ||
p->second->is_stale() ||
p->second->is_stale_purging() ||
- p->second->is_stale_closing())
+ p->second->is_stale_closing()) {
+ ::encode(p->first, bl);
p->second->encode(bl);
+ }
}
void SessionMap::decode(bufferlist::iterator& p)
{
utime_t now = g_clock.now();
-
- ::decode(version, p);
-
- // this is a meaningless upper bound. can be ignored.
- __u32 n;
- ::decode(n, p);
-
- while (n-- && !p.end()) {
- Session *s = new Session;
- s->decode(p);
- session_map[s->inst.name] = s;
- set_state(s, Session::STATE_OPEN);
- s->last_cap_renew = now;
+ __u64 pre;
+ ::decode(pre, p);
+ if (version == (__u64)-1) {
+ __u8 struct_v;
+ ::decode(struct_v, p);
+ assert(struct_v == 2);
+
+ while (!p.end()) {
+ entity_inst_t inst;
+ ::decode(inst.name, p);
+ Session *s = get_or_add_open_session(inst);
+ s->decode(p);
+ }
+
+ } else {
+ // --- old format ----
+ version = pre;
+
+ // this is a meaningless upper bound. can be ignored.
+ __u32 n;
+ ::decode(n, p);
+
+ while (n-- && !p.end()) {
+ bufferlist::iterator p2 = p;
+ Session *s = new Session;
+ s->decode(p);
+ if (session_map.count(s->inst.name)) {
+ // eager client connected too fast! aie.
+ dout(10) << " already had session for " << s->inst.name << ", recovering" << dendl;
+ entity_name_t n = s->inst.name;
+ delete s;
+ s = session_map[s->inst.name];
+ p = p2;
+ s->decode(p);
+ } else {
+ session_map[s->inst.name] = s;
+ }
+ set_state(s, Session::STATE_OPEN);
+ s->last_cap_renew = now;
+ }
}
}