common/LogClient.cc \
msg/Message.cc \
common/Logger.cc \
+ common/ClassLibrary.cc \
common/Clock.cc \
common/Timer.cc \
common/Finisher.cc \
client/fuse_ll.h\
client/hadoop/CephFSInterface.h\
cm.txt\
+ common/arch.h\
common/debug.h\
common/lockdep.h\
common/BackTrace.h\
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;
--- /dev/null
+
+#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;
+}
+
{
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)
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();
--- /dev/null
+#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
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) {}
}
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) {
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);
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;
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;
// 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;
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!";
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;
{
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++;
#include "ReplicatedPG.h"
#include "OSD.h"
+#include "common/arch.h"
#include "common/Logger.h"
#include "messages/MOSDOp.h"
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;