]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
class: moving ClassHandler to common/
authorYehuda Sadeh <yehuda@hq.newdream.net>
Mon, 18 May 2009 17:17:27 +0000 (10:17 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Mon, 18 May 2009 17:17:27 +0000 (10:17 -0700)
src/common/ClassHandler.cc [new file with mode: 0644]
src/common/ClassHandler.h [new file with mode: 0644]
src/kernel/bookkeeper.h
src/osd/ClassHandler.h [deleted file]

diff --git a/src/common/ClassHandler.cc b/src/common/ClassHandler.cc
new file mode 100644 (file)
index 0000000..4266035
--- /dev/null
@@ -0,0 +1,149 @@
+
+#include "include/types.h"
+#include "msg/Message.h"
+#include "osd/OSD.h"
+#include "messages/MClass.h"
+#include "ClassHandler.h"
+
+#include <dlfcn.h>
+
+#include <map>
+
+#include "config.h"
+
+#define DOUT_SUBSYS osd
+#undef dout_prefix
+#define dout_prefix *_dout << dbeginl
+
+
+void ClassHandler::load_class(const nstring& cname)
+{
+  dout(10) << "load_class " << cname << dendl;
+
+  ClassData& data = classes[cname];
+  char *fname=strdup("/tmp/class-XXXXXX");
+  int fd = mkstemp(fname);
+
+  for (list<bufferptr>::const_iterator it = data.impl.binary.buffers().begin();
+       it != data.impl.binary.buffers().end(); it++)
+    write(fd, it->c_str(), it->length());
+
+  close(fd);
+
+  data.handle = dlopen(fname, RTLD_LAZY);
+  void (*cls_init)() = (void (*)())dlsym(data.handle, "class_init");
+  if (cls_init)
+    cls_init();
+
+  unlink(fname);
+  free(fname);
+}
+
+
+bool ClassHandler::get_class(const nstring& cname)
+{
+  ClassData& class_data = classes[cname];
+
+  switch (class_data.status) {
+  case ClassData::CLASS_LOADED:
+    return true;
+    
+  case ClassData::CLASS_REQUESTED:
+    return false;
+    break;
+
+  case ClassData::CLASS_UNKNOWN:
+    class_data.status = ClassData::CLASS_REQUESTED;
+    break;
+
+  default:
+    assert(0);
+  }
+
+  osd->send_class_request(cname.c_str());
+  return false;
+}
+
+void ClassHandler::handle_class(MClass *m)
+{
+  deque<ClassInfo>::iterator info_iter;
+  deque<ClassImpl>::iterator impl_iter;
+  deque<bool>::iterator add_iter;
+  
+  for (info_iter = m->info.begin(), add_iter = m->add.begin(), impl_iter = m->impl.begin();
+       info_iter != m->info.end();
+       ++info_iter, ++add_iter) {
+    ClassData& data = classes[info_iter->name];
+    
+    if (*add_iter) {
+      
+      if (data.status == ClassData::CLASS_REQUESTED) {
+       dout(0) << "added class '" << info_iter->name << "'" << dendl;
+       data.impl = *impl_iter;
+       ++impl_iter;
+       data.status = ClassData::CLASS_LOADED;
+       
+       load_class(info_iter->name);
+       osd->got_class(info_iter->name);
+      }
+    } else {
+      /* fixme: handle case in which we didn't get the class */
+    }
+  }
+}
+
+
+void ClassHandler::resend_class_requests()
+{
+  for (map<nstring,ClassData>::iterator p = classes.begin(); p != classes.end(); p++)
+    osd->send_class_request(p->first.c_str());
+}
+
+ClassHandler::ClassData *ClassHandler::register_class(const char *cname)
+{
+  ClassData& class_data = classes[cname];
+
+  if (class_data.status != ClassData::CLASS_LOADED) {
+    dout(0) << "class " << cname << " can't be loaded" << dendl;
+    return NULL;
+  }
+
+  if (class_data.registered) {
+    dout(0) << "class " << cname << " already registered" << dendl;
+  }
+
+  class_data.registered = true;
+
+  return &class_data;
+}
+
+void ClassHandler::unregister_class(ClassHandler::ClassData *cls)
+{
+  /* FIXME: do we really need this one? */
+}
+
+ClassHandler::ClassMethod *ClassHandler::ClassData::register_method(const char *mname, cls_method_call_t func)
+{
+  ClassMethod& method = methods_map[mname];
+  method.func = func;
+  method.name = mname;
+  method.cls = this;
+
+  return &method;
+}
+
+void ClassHandler::ClassData::unregister_method(ClassHandler::ClassMethod *method)
+{
+   map<string, ClassMethod>::iterator iter;
+
+   iter = methods_map.find(method->name);
+   if (iter == methods_map.end())
+     return;
+
+   methods_map.erase(iter);
+}
+
+void ClassHandler::ClassMethod::unregister()
+{
+   cls->unregister_method(this);
+}
diff --git a/src/common/ClassHandler.h b/src/common/ClassHandler.h
new file mode 100644 (file)
index 0000000..4831a0c
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef __CLASSHANDLER_H
+#define __CLASHANDLER_H
+
+#include "include/types.h"
+#include "include/ClassLibrary.h"
+
+#include "objclass/objclass.h"
+
+#include "common/Cond.h"
+
+
+class OSD;
+
+
+class ClassHandler
+{
+  OSD *osd;
+
+public:
+  class ClassData;
+
+  struct ClassMethod {
+    struct ClassHandler::ClassData *cls;
+    string name;
+    cls_method_call_t func;
+
+    void unregister();
+  };
+
+  struct ClassData {
+    enum { 
+      CLASS_UNKNOWN, 
+      //CLASS_UNLOADED, 
+      CLASS_LOADED, 
+      CLASS_REQUESTED, 
+      //CLASS_ERROR
+    } status;
+    version_t version;
+    ClassImpl impl;
+    void *handle;
+    bool registered;
+    map<string, ClassMethod> methods_map;
+
+    ClassData() : status(CLASS_UNKNOWN), version(-1), handle(NULL), registered(false) {}
+    ~ClassData() { }
+
+    ClassMethod *register_method(const char *mname,
+                          cls_method_call_t func);
+    void unregister_method(ClassMethod *method);
+  };
+  map<nstring, ClassData> classes;
+
+  void load_class(const nstring& cname);
+
+  ClassHandler(OSD *_osd) : osd(_osd) {}
+
+  bool get_class(const nstring& cname);
+  void resend_class_requests();
+
+  void handle_class(MClass *m);
+
+  ClassData *register_class(const char *cname);
+  void unregister_class(ClassData *cls);
+
+};
+
+
+#endif
index 85417706fce2f8e308e96f06135aa16cac80af48..f6c69152e75c5f9aeb21ea53f5cd04dde43e51e1 100644 (file)
@@ -6,7 +6,7 @@ extern void ceph_bookkeeper_dump(void);
 extern void ceph_bookkeeper_init(void);
 extern void ceph_bookkeeper_finalize(void);
 extern void *ceph_kmalloc(char *fname, int line, size_t size, gfp_t flags);
-extern void ceph_kfree(void *ptr);
+extern void ceph_kfree(const void *ptr);
 
 #ifndef CEPH_OVERRIDE_BOOKKEEPER
 #define kmalloc(size, flags)   ceph_kmalloc(__FILE__, __LINE__, size, flags)
diff --git a/src/osd/ClassHandler.h b/src/osd/ClassHandler.h
deleted file mode 100644 (file)
index 4831a0c..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef __CLASSHANDLER_H
-#define __CLASHANDLER_H
-
-#include "include/types.h"
-#include "include/ClassLibrary.h"
-
-#include "objclass/objclass.h"
-
-#include "common/Cond.h"
-
-
-class OSD;
-
-
-class ClassHandler
-{
-  OSD *osd;
-
-public:
-  class ClassData;
-
-  struct ClassMethod {
-    struct ClassHandler::ClassData *cls;
-    string name;
-    cls_method_call_t func;
-
-    void unregister();
-  };
-
-  struct ClassData {
-    enum { 
-      CLASS_UNKNOWN, 
-      //CLASS_UNLOADED, 
-      CLASS_LOADED, 
-      CLASS_REQUESTED, 
-      //CLASS_ERROR
-    } status;
-    version_t version;
-    ClassImpl impl;
-    void *handle;
-    bool registered;
-    map<string, ClassMethod> methods_map;
-
-    ClassData() : status(CLASS_UNKNOWN), version(-1), handle(NULL), registered(false) {}
-    ~ClassData() { }
-
-    ClassMethod *register_method(const char *mname,
-                          cls_method_call_t func);
-    void unregister_method(ClassMethod *method);
-  };
-  map<nstring, ClassData> classes;
-
-  void load_class(const nstring& cname);
-
-  ClassHandler(OSD *_osd) : osd(_osd) {}
-
-  bool get_class(const nstring& cname);
-  void resend_class_requests();
-
-  void handle_class(MClass *m);
-
-  ClassData *register_class(const char *cname);
-  void unregister_class(ClassData *cls);
-
-};
-
-
-#endif