From c91327bbee0fdee9b106434ce7cfd9431d992263 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 21 May 2009 16:40:05 -0700 Subject: [PATCH] class: add architecture to version --- src/Makefile.am | 2 ++ src/ceph.cc | 10 ++++-- src/common/ClassLibrary.cc | 23 ++++++++++++++ src/common/ClassVersion.h | 30 +++++++++++++----- src/common/arch.h | 15 +++++++++ src/include/ClassLibrary.h | 54 +++++++++++++++++++++++++++----- src/mon/ClassMonitor.cc | 64 ++++++++++++++++++++++++-------------- src/osd/ReplicatedPG.cc | 2 ++ 8 files changed, 157 insertions(+), 43 deletions(-) create mode 100644 src/common/ClassLibrary.cc create mode 100644 src/common/arch.h diff --git a/src/Makefile.am b/src/Makefile.am index e8488233d4f53..f1f40cc720d0b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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\ diff --git a/src/ceph.cc b/src/ceph.cc index 0b414b56795af..585a48e2606a9 100644 --- a/src/ceph.cc +++ b/src/ceph.cc @@ -185,9 +185,13 @@ void handle_notify(MMonObserveNotify *notify) ClassLibrary list; ::decode(list, p); // show the first class info - map::iterator iter = list.library_map.begin(); - if (iter != list.library_map.end()) { - dout(0) << " class " << iter->second << dendl; + map::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 index 0000000000000..bf6a95409ddd4 --- /dev/null +++ b/src/common/ClassLibrary.cc @@ -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; +} + diff --git a/src/common/ClassVersion.h b/src/common/ClassVersion.h index 43fa89418ffa5..72c74a1eddbd8 100644 --- a/src/common/ClassVersion.h +++ b/src/common/ClassVersion.h @@ -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 index 0000000000000..3b3a078500e7e --- /dev/null +++ b/src/common/arch.h @@ -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 diff --git a/src/include/ClassLibrary.h b/src/include/ClassLibrary.h index 34d7cd731a526..92a858eafc9ac 100644 --- a/src/include/ClassLibrary.h +++ b/src/include/ClassLibrary.h @@ -84,9 +84,43 @@ struct ClassLibraryIncremental { WRITE_CLASS_ENCODER(ClassLibraryIncremental) +typedef map 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 library_map; + map 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::iterator iter = library_map.find(name); - if (iter == library_map.end()) + bool get_ver(string& name, ClassVersion& reqver, ClassVersion *ver) { + map::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); diff --git a/src/mon/ClassMonitor.cc b/src/mon/ClassMonitor.cc index 59f25bad6b30e..169ce69d415c3 100644 --- a/src/mon/ClassMonitor.cc +++ b/src/mon/ClassMonitor.cc @@ -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 <-i filename>"; + ss << "error: usage: class <-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::iterator iter = list.library_map.find(name); + string ver = m->cmd[3]; + string arch = m->cmd[4]; + map::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(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::iterator iter = list.library_map.begin(); - if (iter != list.library_map.end()) { + map::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::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++; diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 07fb75548939f..145f4fa6b7dd4 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -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; -- 2.39.5