]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
class: add architecture to version
authorYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 21 May 2009 23:40:05 +0000 (16:40 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Thu, 21 May 2009 23:40:05 +0000 (16:40 -0700)
src/Makefile.am
src/ceph.cc
src/common/ClassLibrary.cc [new file with mode: 0644]
src/common/ClassVersion.h
src/common/arch.h [new file with mode: 0644]
src/include/ClassLibrary.h
src/mon/ClassMonitor.cc
src/osd/ReplicatedPG.cc

index e8488233d4f531db4be4b188a8cb33074f93038d..f1f40cc720d0bf121b00f5a85b0a605951a88da1 100644 (file)
@@ -215,6 +215,7 @@ libcommon_files = \
        common/LogClient.cc \
        msg/Message.cc \
        common/Logger.cc \
+       common/ClassLibrary.cc \
        common/Clock.cc \
        common/Timer.cc \
        common/Finisher.cc \
@@ -312,6 +313,7 @@ noinst_HEADERS = \
         client/fuse_ll.h\
         client/hadoop/CephFSInterface.h\
        cm.txt\
+        common/arch.h\
        common/debug.h\
        common/lockdep.h\
        common/BackTrace.h\
index 0b414b56795afda37060e320e0ff12df83d8f95e..585a48e2606a98e33d6484580b11048ae5357ea7 100644 (file)
@@ -185,9 +185,13 @@ void handle_notify(MMonObserveNotify *notify)
        ClassLibrary list;
        ::decode(list, p);
        // show the first class info
-        map<string, ClassInfo>::iterator iter = list.library_map.begin();
-       if (iter != list.library_map.end()) {
-         dout(0) << "   class " <<  iter->second << dendl;
+        map<string, ClassVersionMap>::iterator mapiter = list.library_map.begin();
+       if (mapiter != list.library_map.end()) {
+          ClassVersionMap& map = mapiter->second;
+          tClassVersionMap::iterator iter = map.begin();
+
+          if (iter != map.end())
+           dout(0) << "   class " <<  iter->second << dendl;
        }
       } else {
        ClassInfo info;
diff --git a/src/common/ClassLibrary.cc b/src/common/ClassLibrary.cc
new file mode 100644 (file)
index 0000000..bf6a954
--- /dev/null
@@ -0,0 +1,23 @@
+
+#include "common/ClassVersion.h"
+#include "include/ClassLibrary.h"
+
+#include "config.h"
+
+ClassInfo *ClassVersionMap::get(ClassVersion& ver)
+{
+  ClassVersion v = ver;
+  tClassVersionMap::iterator iter;
+
+  if (ver.is_default()) {
+    v.ver = default_ver;
+  }
+
+  iter = m.find(ver);
+
+  if (iter != m.end())
+    return &(iter->second);
+
+  return NULL;
+}
+
index 43fa89418ffa51679361b7cb34854f334b1a492d..72c74a1eddbd8b7ee1eb10acc5b2f06e9e9ad552 100644 (file)
@@ -8,26 +8,40 @@ class ClassVersion
 {
 protected:
   std::string ver;
+  std::string architecture;
 
 public:
-  ClassVersion(string& v) : ver(v) {}
-  ClassVersion(const char *s) : ver(s) {}
+  ClassVersion(string& v, string& a) : ver(v), architecture(a) {}
+  ClassVersion(const char *s, const char *a) : ver(s), architecture(a) {}
   ClassVersion() {}
 
   void operator=(const char *s) { ver = s; }
   void operator=(string& v) { ver = v; }
 
-  friend bool operator==(ClassVersion& v1, ClassVersion& v2);
-  friend bool operator<(ClassVersion& v1, ClassVersion& v2);
+  friend bool operator==(const ClassVersion& v1, const ClassVersion& v2);
+  friend bool operator<(const ClassVersion& v1, const ClassVersion& v2);
   friend std::ostream& operator<<(std::ostream& out, const ClassVersion& v);
+  friend class ClassVersionMap;
+
   void encode(bufferlist& bl) const {
     ::encode(ver, bl);
+    ::encode(architecture, bl);
   }
   void decode(bufferlist::iterator& bl) {
     ::decode(ver, bl);
+    ::decode(architecture, bl);
   }
 
-  const char *str() { return ver.c_str(); };
+  const char *str() { return ver.c_str(); }
+  const char *arch() { 
+    if (architecture.length() == 0)
+      return "unknown";
+    else
+      return architecture.c_str(); 
+  }
+  void set_arch(const char *arch) {
+    architecture = arch;
+  }
   bool is_default() { return (ver.length() == 0); }
 };
 WRITE_CLASS_ENCODER(ClassVersion)
@@ -53,16 +67,16 @@ static int compare_single(const char *v1, const char *v2)
 
 inline std::ostream& operator<<(std::ostream& out, const ClassVersion& v)
 {
-  out << v.ver;
+  out << v.ver << " [" << v.architecture << "]";
 
   return out;
 }
-inline bool operator==(ClassVersion& v1, ClassVersion& v2)
+inline bool operator==(const ClassVersion& v1, const ClassVersion& v2)
 {
   return (v1.ver == v2.ver);
 }
 
-inline bool operator<(ClassVersion& v1, ClassVersion& v2)
+inline bool operator<(const ClassVersion& v1, const ClassVersion& v2)
 {
   const char *_s1 = v1.ver.c_str();
   const char *_s2 = v2.ver.c_str();
diff --git a/src/common/arch.h b/src/common/arch.h
new file mode 100644 (file)
index 0000000..3b3a078
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __ARCH_H
+
+
+static const char *get_arch()
+{
+#if defined(__i386__)
+  return "i386";
+#elif defined(__x86_64__)
+  return "x86-64";
+#else
+    return "unknown";
+#endif
+}
+
+#endif
index 34d7cd731a526377cc035370ee12e77ea7bc5ff3..92a858eafc9ac53538491c2f81aceb67a630f6c9 100644 (file)
@@ -84,9 +84,43 @@ struct ClassLibraryIncremental {
 
 WRITE_CLASS_ENCODER(ClassLibraryIncremental)
 
+typedef map<ClassVersion, ClassInfo> tClassVersionMap;
+class ClassVersionMap
+{
+public:
+  tClassVersionMap m;
+  string default_ver;
+
+  void encode(bufferlist& bl) const {
+    ::encode(m, bl);
+  }
+  void decode(bufferlist::iterator& bl) {
+    ::decode(m, bl);
+  }
+
+  tClassVersionMap::iterator begin() { return m.begin(); }
+  tClassVersionMap::iterator end() { return m.end(); }
+
+  void add(ClassInfo& library) {
+    m[library.version] = library;
+  }
+
+  void remove(ClassInfo& library) {
+    tClassVersionMap::iterator iter;
+    iter = m.find(library.version);
+    if (iter != m.end()) {
+      m.erase(iter);
+    }
+  }
+
+  ClassInfo *get(ClassVersion& ver);
+  void set_default(string ver) { default_ver = ver; }
+};
+WRITE_CLASS_ENCODER(ClassVersionMap)
+
 struct ClassLibrary {
   version_t version;
-  map<string, ClassInfo> library_map;
+  map<string, ClassVersionMap> library_map;
 
   ClassLibrary() : version(0) {}
 
@@ -98,7 +132,8 @@ struct ClassLibrary {
   }
 
   void add(ClassInfo& library) {
-    library_map[library.name] = library;
+    ClassVersionMap& vmap = library_map[library.name];
+    vmap.add(library);
   }
 
   void remove(const string& name, const ClassVersion& version) {
@@ -108,15 +143,18 @@ struct ClassLibrary {
   bool contains(string& name) {
     return (library_map.find(name) != library_map.end());
   }
-
-  bool get_ver(string& name, ClassVersion *ver) {
-    map<string, ClassInfo>::iterator iter = library_map.find(name);
-    if (iter == library_map.end())
+  bool get_ver(string& name, ClassVersion& reqver, ClassVersion *ver) {
+    map<string, ClassVersionMap>::iterator mapiter = library_map.find(name);
+    if (mapiter == library_map.end())
       return false;
-    *ver = (iter->second).version;
+    string ver_str;
+    ClassVersionMap& map = mapiter->second;
+    ClassInfo *info = map.get(reqver);
+    if (info)
+      *ver = info->version;
+    
     return true;
   }
-
   void encode(bufferlist& bl) const {
     ::encode(version, bl);
     ::encode(library_map, bl);
index 59f25bad6b30efd2cea3a3e4f1322af6aed7e36e..169ce69d415c39faf37d122cfe52dc085b763290 100644 (file)
@@ -80,7 +80,7 @@ bool ClassMonitor::store_impl(ClassInfo& info, ClassImpl& impl)
   int len = info.name.length() + 16;
   char store_name[len];
 
-  snprintf(store_name, len, "%s.%s", info.name.c_str(), info.version.str());
+  snprintf(store_name, len, "%s.%s.%s", info.name.c_str(), info.version.str(), info.version.arch());
   dout(0) << "storing inc.impl length=" << impl.binary.length() << dendl;
   mon->store->put_bl_ss(impl.binary, "class_impl", store_name);
   bufferlist bl;
@@ -268,7 +268,7 @@ bool ClassMonitor::preprocess_command(MMonCommand *m)
       return false;
     }
   }
-  ss << "error: usage: ceph <add | del> <name> <version> <-i filename>";
+  ss << "error: usage: class <add | del> <name> <version> <arch> <-i filename>";
   r = -EINVAL;
 
   string rs;
@@ -286,10 +286,13 @@ bool ClassMonitor::prepare_command(MMonCommand *m)
 
   // nothing here yet
   if (m->cmd.size() > 1) {
-    if (m->cmd[1] == "add" && m->cmd.size() >= 4) {
+    if (m->cmd[1] == "add" && m->cmd.size() >= 5) {
       string name = m->cmd[2];
       string ver = m->cmd[3];
-      ClassInfo& info = list.library_map[name];
+      string arch = m->cmd[4];
+      ClassVersionMap& map = list.library_map[name];
+      ClassVersion cv(ver, arch);
+      ClassInfo& info = map.m[cv];
       ClassImpl impl;
       impl.binary = m->get_data();
       dout(0) << "payload.length=" << m->get_data().length() << dendl;
@@ -309,35 +312,48 @@ bool ClassMonitor::prepare_command(MMonCommand *m)
       getline(ss, rs);
       paxos->wait_for_commit(new Monitor::C_Command(mon, m, 0, rs));
       return true;
-    } else if (m->cmd[1] == "del" && m->cmd.size() >= 2) {
+    } else if (m->cmd[1] == "del" && m->cmd.size() >= 5) {
       string name = m->cmd[2];
-      map<string, ClassInfo>::iterator iter = list.library_map.find(name);
+      string ver = m->cmd[3];
+      string arch = m->cmd[4];
+      map<string, ClassVersionMap>::iterator iter = list.library_map.find(name);
       if (iter == list.library_map.end()) {
         ss << "couldn't find class " << name;
         rs = -ENOENT;
         goto done;
       }
-      ClassInfo& info = iter->second;
-      /* store_impl(info, impl); */
-      dout(0) << "removing class " << name << " v" << info.version << dendl;
+      ClassVersionMap& map = iter->second;
+      ClassVersion v(ver, arch);
+      ClassInfo *info = map.get(v);
+      if (!info) {
+        ss << "couldn't find class " << name << " v" << v;
+        rs = -ENOENT;
+        goto done;
+      }
+      dout(0) << "removing class " << name << " v" << info->version << dendl;
       ClassLibraryIncremental inc;
       ClassImpl impl;
-      ::encode(info, inc.info);
+      ::encode(*info, inc.info);
       inc.add = false;
-      pending_list.add(info);
+      pending_list.add(*info);
       pending_class.insert(pair<utime_t,ClassLibraryIncremental>(impl.stamp, inc));
 
       ss << "updated";
       getline(ss, rs);
       paxos->wait_for_commit(new Monitor::C_Command(mon, m, 0, rs));
     } else if (m->cmd[1] == "list") {
-      map<string, ClassInfo>::iterator iter = list.library_map.begin();
-      if (iter != list.library_map.end()) {
+      map<string, ClassVersionMap>::iterator mapiter = list.library_map.begin();
+      if (mapiter != list.library_map.end()) {
         ss << "installed classes: " << std::endl;      
 
-        while (iter != list.library_map.end()) {
-          ss << iter->second.name << " (v" << iter->second.version << ")" << std::endl;
-          ++iter;
+       while (mapiter != list.library_map.end()) {
+          ClassVersionMap& map = mapiter->second;
+          tClassVersionMap::iterator iter = map.begin();
+          while (iter != map.end()) {
+            ss << iter->second.name << " (v" << iter->second.version << ")" << std::endl;
+            ++iter;
+          }
+          ++mapiter;
         }
       } else {
         ss << "no installed classes!";
@@ -379,11 +395,11 @@ void ClassMonitor::handle_request(MClass *m)
     reply->info.push_back(*p);
     switch (m->action) {
     case CLASS_GET:
-      if (list.get_ver((*p).name, &ver)) {
+      if (list.get_ver((*p).name, (*p).version, &ver)) {
         int len = (*p).name.length() + 16;
         int bin_len;
         char store_name[len];
-        snprintf(store_name, len, "%s.%s", (*p).name.c_str(), ver.str());
+        snprintf(store_name, len, "%s.%s.%s", (*p).name.c_str(), ver.str(), ver.arch());
         bin_len = mon->store->get_bl_ss(impl.binary, "class_impl", store_name);
         assert(bin_len > 0);
         dout(0) << "replying with name=" << (*p).name << " version=" << ver <<  " store_name=" << store_name << dendl;
@@ -398,15 +414,15 @@ void ClassMonitor::handle_request(MClass *m)
        {
          dout(0) << "ClassMonitor::handle_request() CLASS_SET" << dendl;
          bool add = *add_iter;
+         ClassVersionMap& cv = list.library_map[(*p).name];
+         ClassInfo entry;
+         entry.name = (*p).name;
+         entry.version = (*p).version;
          if (add) {
-           ClassInfo& entry = list.library_map[(*p).name];
-           entry.name = (*p).name;
-           entry.version = (*p).version;
+           cv.add(entry);
            store_impl(entry, *impl_iter);
          } else {
-           map<string, ClassInfo>::iterator iter = list.library_map.find((*p).name);
-           if (iter != list.library_map.end())
-             list.library_map.erase(iter);
+           cv.remove(entry);
          }
          impl_iter++;
          add_iter++;
index 07fb75548939f66a20976b5ff944caebdb67f683..145f4fa6b7dd48d243cb61deb021aee6325461fb 100644 (file)
@@ -15,6 +15,7 @@
 #include "ReplicatedPG.h"
 #include "OSD.h"
 
+#include "common/arch.h"
 #include "common/Logger.h"
 
 #include "messages/MOSDOp.h"
@@ -684,6 +685,7 @@ int ReplicatedPG::do_read_ops(ReadOpContext *ctx,
        
        ClassHandler::ClassData *cls;
         ClassVersion version;
+        version.set_arch(get_arch());
         result = osd->get_class(cname, version, info.pgid, ctx->op, &cls);
        if (result) {
          dout(10) << "rdcall class " << cname << " does not exist" << dendl;