]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osdmap: encode/decode old + new version
authorSage Weil <sage@newdream.net>
Fri, 26 Aug 2011 16:55:20 +0000 (09:55 -0700)
committerSage Weil <sage.weil@dreamhost.com>
Sat, 27 Aug 2011 17:20:54 +0000 (10:20 -0700)
In MOSDMap, reencode map payloads using old format if the target doesn't
have the PGID64 feature bit.

Signed-off-by: Sage Weil <sage@newdream.net>
src/messages/MOSDMap.h
src/osd/OSDMap.cc
src/osd/OSDMap.h

index 58a7be90f77c2de87c3cf40625ca2f8422cff0eb..8ca06458ef5fcad93e59b6e48ebe051ef1e78016 100644 (file)
@@ -65,6 +65,30 @@ public:
   }
   void encode_payload(CephContext *cct) {
     ::encode(fsid, payload);
+    if (connection && !connection->has_feature(CEPH_FEATURE_PGID64)) {
+      // reencode maps using old format
+      //
+      // FIXME: this can probably be done more efficiently higher up
+      // the stack, or maybe replaced with something that only
+      // includes the pools the client cares about.
+      for (map<epoch_t,bufferlist>::iterator p = incremental_maps.begin();
+          p != incremental_maps.end();
+          ++p) {
+       OSDMap::Incremental inc;
+       bufferlist::iterator q = p->second.begin();
+       inc.decode(q);
+       p->second.clear();
+       inc.encode_client_old(p->second);
+      }
+      for (map<epoch_t,bufferlist>::iterator p = maps.begin();
+          p != maps.end();
+          ++p) {
+       OSDMap m;
+       m.decode(p->second);
+       p->second.clear();
+       m.encode_client_old(p->second);
+      }
+    }
     ::encode(incremental_maps, payload);
     ::encode(maps, payload);
   }
index f545d9a9266af2087e12608623ca4ccc4fc16cf0..3f42659798f5fc47833eb8ecfa13c8bf13f2db2b 100644 (file)
@@ -130,7 +130,7 @@ void OSDMap::print(ostream& out) const
  
   for (map<int64_t,pg_pool_t>::const_iterator p = pools.begin(); p != pools.end(); ++p) {
     std::string name("<unknown>");
-    map<int32_t,string>::const_iterator pni = pool_name.find(p->first);
+    map<int64_t,string>::const_iterator pni = pool_name.find(p->first);
     if (pni != pool_name.end())
       name = pni->second;
     out << "pg_pool " << p->first
index 397bf0396bb0b83485e64e5f5d05808851aaae65..af11432c4a32acae6361f69524c93f3078264d51 100644 (file)
@@ -135,7 +135,7 @@ public:
     ceph_fsid_t fsid;
     epoch_t epoch;   // new epoch; we are a diff from epoch-1 to epoch
     utime_t modified;
-    int32_t new_pool_max; //incremented by the OSDMonitor on each pool create
+    int64_t new_pool_max; //incremented by the OSDMonitor on each pool create
     int32_t new_flags;
 
     /*
@@ -153,9 +153,9 @@ public:
 
     // incremental
     int32_t new_max_osd;
-    map<int32_t,pg_pool_t> new_pools;
-    map<int32_t,string> new_pool_names;
-    set<int32_t> old_pools;
+    map<int64_t,pg_pool_t> new_pools;
+    map<int64_t,string> new_pool_names;
+    set<int64_t> old_pools;
     map<int32_t,entity_addr_t> new_up_client;
     map<int32_t,entity_addr_t> new_up_internal;
     map<int32_t,uint8_t> new_state;             // XORed onto previous state.
@@ -171,9 +171,62 @@ public:
 
     string cluster_snapshot;
 
+    void encode_client_old(bufferlist& bl) {
+      __u16 v = 5;
+      ::encode(v, bl);
+      ::encode(fsid, bl);
+      ::encode(epoch, bl);
+      ::encode(modified, bl);
+      int32_t new_t = new_pool_max;
+      ::encode(new_t, bl);
+      ::encode(new_flags, bl);
+      ::encode(fullmap, bl);
+      ::encode(crush, bl);
+
+      ::encode(new_max_osd, bl);
+      // for ::encode(new_pools, bl);
+      __u32 n = new_pools.size();
+      ::encode(n, bl);
+      for (map<int64_t,pg_pool_t>::iterator p = new_pools.begin();
+          p != new_pools.end();
+          ++p) {
+       n = p->first;
+       ::encode(n, bl);
+       ::encode(p->second, bl);
+      }
+      // for ::encode(new_pool_names, bl);
+      n = new_pool_names.size();
+      ::encode(n, bl);
+      for (map<int64_t, string>::iterator p = new_pool_names.begin(); p != new_pool_names.end(); ++p) {
+       n = p->first;
+       ::encode(n, bl);
+       ::encode(p->second, bl);
+      }
+      // for ::encode(old_pools, bl);
+      n = old_pools.size();
+      ::encode(n, bl);
+      for (set<int64_t>::iterator p = old_pools.begin(); p != old_pools.end(); ++p) {
+       n = *p;
+       ::encode(n, bl);
+      }
+      ::encode(new_up_client, bl);
+      ::encode(new_state, bl);
+      ::encode(new_weight, bl);
+      // for ::encode(new_pg_temp, bl);
+      n = new_pg_temp.size();
+      ::encode(n, bl);
+      for (map<pg_t,vector<int32_t> >::iterator p = new_pg_temp.begin();
+          p != new_pg_temp.end();
+          ++p) {
+       old_pg_t opg = p->first.get_old_pg();
+       ::encode(opg, bl);
+       ::encode(p->second, bl);
+      }
+    }
+
     void encode(bufferlist& bl) {
       // base
-      __u16 v = CEPH_OSDMAP_INC_VERSION;
+      __u16 v = 6;
       ::encode(v, bl);
       ::encode(fsid, bl);
       ::encode(epoch, bl); 
@@ -205,27 +258,68 @@ public:
       ::encode(cluster_snapshot, bl);
     }
     void decode(bufferlist::iterator &p) {
+      __u32 n, t;
       // base
       __u16 v;
       ::decode(v, p);
       ::decode(fsid, p);
       ::decode(epoch, p);
       ::decode(modified, p);
-      if (v >= 4)
-       ::decode(new_pool_max, p);
+      if (v == 4 || v == 5) {
+       ::decode(n, p);
+       new_pool_max = n;
+      } else if (v >= 6)
+       ::decode(new_pool_max, p);      
       ::decode(new_flags, p);
       ::decode(fullmap, p);
       ::decode(crush, p);
 
       ::decode(new_max_osd, p);
-      ::decode(new_pools, p);
-      if (v >= 5)
+      if (v < 6) {
+       new_pools.clear();
+       ::decode(n, p);
+       while (n--) {
+         ::decode(t, p);
+         ::decode(new_pools[t], p);
+       }
+      } else {
+       ::decode(new_pools, p);
+      }
+      if (v == 5) {
+       new_pool_names.clear();
+       ::decode(n, p);
+       while (n--) {
+         ::decode(t, p);
+         ::decode(new_pool_names[t], p);
+       }
+      } else if (v >= 6) {
        ::decode(new_pool_names, p);
-      ::decode(old_pools, p);
+      }
+      if (v < 6) {
+       old_pools.clear();
+       ::decode(n, p);
+       while (n--) {
+         ::decode(t, p);
+         old_pools.insert(t);
+       }
+      } else {
+       ::decode(old_pools, p);
+      }
       ::decode(new_up_client, p);
       ::decode(new_state, p);
       ::decode(new_weight, p);
-      ::decode(new_pg_temp, p);
+
+      if (v < 6) {
+       new_pg_temp.clear();
+       ::decode(n, p);
+       while (n--) {
+         old_pg_t opg;
+         ::decode_raw(opg, p);
+         ::decode(new_pg_temp[pg_t(opg)], p);
+       }
+      } else {
+       ::decode(new_pg_temp, p);
+      }
 
       // extended
       __u16 ev = 0;
@@ -277,7 +371,7 @@ private:
   map<pg_t,vector<int> > pg_temp;  // temp pg mapping (e.g. while we rebuild)
 
   map<int64_t,pg_pool_t> pools;
-  map<int32_t,string> pool_name;
+  map<int64_t,string> pool_name;
   map<string,int64_t> name_pool;
 
   hash_map<entity_addr_t,utime_t> blacklist;
@@ -559,20 +653,20 @@ private:
     if (inc.new_pool_max != -1)
       pool_max = inc.new_pool_max;
 
-    for (set<int32_t>::iterator p = inc.old_pools.begin();
+    for (set<int64_t>::iterator p = inc.old_pools.begin();
         p != inc.old_pools.end();
         p++) {
       pools.erase(*p);
       name_pool.erase(pool_name[*p]);
       pool_name.erase(*p);
     }
-    for (map<int32_t,pg_pool_t>::iterator p = inc.new_pools.begin();
+    for (map<int64_t,pg_pool_t>::iterator p = inc.new_pools.begin();
         p != inc.new_pools.end();
         p++) {
       pools[p->first] = p->second;
       pools[p->first].v.last_change = epoch;
     }
-    for (map<int32_t,string>::iterator p = inc.new_pool_names.begin();
+    for (map<int64_t,string>::iterator p = inc.new_pool_names.begin();
         p != inc.new_pool_names.end();
         p++) {
       pool_name[p->first] = p->second;
@@ -662,8 +756,66 @@ private:
   }
 
   // serialize, unserialize
+  void encode_client_old(bufferlist& bl) {
+    __u16 v = 5;
+    ::encode(v, bl);
+
+    // base
+    ::encode(fsid, bl);
+    ::encode(epoch, bl);
+    ::encode(created, bl);
+    ::encode(modified, bl);
+
+    // for ::encode(pools, bl);
+    __u32 n = pools.size();
+    ::encode(n, bl);
+    for (map<int64_t,pg_pool_t>::iterator p = pools.begin();
+        p != pools.end();
+        ++p) {
+      n = p->first;
+      ::encode(n, bl);
+      ::encode(p->second, bl);
+    }
+    // for ::encode(pool_name, bl);
+    n = pool_name.size();
+    ::encode(n, bl);
+    for (map<int64_t, string>::iterator p = pool_name.begin();
+        p != pool_name.end();
+        ++p) {
+      n = p->first;
+      ::encode(n, bl);
+      ::encode(p->second, bl);
+    }
+    // for ::encode(pool_max, bl);
+    n = pool_max;
+    ::encode(n, bl);
+
+    ::encode(flags, bl);
+    
+    ::encode(max_osd, bl);
+    ::encode(osd_state, bl);
+    ::encode(osd_weight, bl);
+    ::encode(osd_addr, bl);
+
+    // for ::encode(pg_temp, bl);
+    n = pg_temp.size();
+    ::encode(n, bl);
+    for (map<pg_t,vector<int32_t> >::iterator p = pg_temp.begin();
+        p != pg_temp.end();
+        ++p) {
+      old_pg_t opg = p->first.get_old_pg();
+      ::encode(opg, bl);
+      ::encode(p->second, bl);
+    }
+
+    // crush
+    bufferlist cbl;
+    crush.encode(cbl);
+    ::encode(cbl, bl);
+  }
+
   void encode(bufferlist& bl) {
-    __u16 v = CEPH_OSDMAP_VERSION;
+    __u16 v = 6;
     ::encode(v, bl);
 
     // base
@@ -702,6 +854,7 @@ private:
   }
   
   void decode(bufferlist& bl) {
+    __u32 n, t;
     bufferlist::iterator p = bl.begin();
     __u16 v;
     ::decode(v, p);
@@ -716,13 +869,34 @@ private:
     if (v < 4) {
       ::decode(max_pools, p);
     }
-    ::decode(pools, p);
-    if (v >= 5)
+    if (v < 6) {
+      pools.clear();
+      ::decode(n, p);
+      while (n--) {
+       ::decode(t, p);
+       ::decode(pools[t], p);
+      }
+    } else {
+      ::decode(pools, p);
+    }
+    if (v == 5) {
+      pool_name.clear();
+      ::decode(n, p);
+      while (n--) {
+       ::decode(t, p);
+       ::decode(pool_name[t], p);
+      }
+    } else if (v >= 6) {
       ::decode(pool_name, p);
-    if (v >= 4)
+    }
+    if (v == 4 || v == 5) {
+      ::decode(n, p);
+      pool_max = n;
+    } else if (v >= 6) {
       ::decode(pool_max, p);
-    else
+    } else {
       pool_max = max_pools;
+    }
 
     ::decode(flags, p);
 
@@ -730,7 +904,17 @@ private:
     ::decode(osd_state, p);
     ::decode(osd_weight, p);
     ::decode(osd_addr, p);
-    ::decode(pg_temp, p);
+    if (v <= 5) {
+      pg_temp.clear();
+      ::decode(n, p);
+      while (n--) {
+       old_pg_t opg;
+       ::decode_raw(opg, p);
+       ::decode(pg_temp[pg_t(opg)], p);
+      }
+    } else {
+      ::decode(pg_temp, p);
+    }
 
     // crush
     bufferlist cbl;
@@ -760,7 +944,7 @@ private:
 
     // index pool names
     name_pool.clear();
-    for (map<int32_t,string>::iterator i = pool_name.begin(); i != pool_name.end(); i++)
+    for (map<int64_t,string>::iterator i = pool_name.begin(); i != pool_name.end(); i++)
       name_pool[i->second] = i->first;
     
     calc_num_osds();