]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: load all classes on startup
authorSage Weil <sage@inktank.com>
Fri, 26 Jul 2013 20:58:46 +0000 (13:58 -0700)
committerSage Weil <sage@inktank.com>
Wed, 7 Aug 2013 20:52:39 +0000 (13:52 -0700)
This avoid creating a wide window between when ceph-osd is started and
when a request arrives needing a class and it is loaded.  In particular,
upgrading the packages in that window may cause linkage errors (if the
class API has changed, for example).

Fixes: #5752
Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Yehuda Sadeh <yehuda@inktank.com>
(cherry picked from commit c24e652d8c5e693498814ebe38c6adbec079ea36)

Conflicts:
src/osd/ClassHandler.cc

src/osd/ClassHandler.cc
src/osd/ClassHandler.h
src/osd/OSD.cc

index 6675e9e4fc40ec3d9e54e678c04c3e0f10c1e006..9137b64be57f70f6768e142afac225d45b24befc 100644 (file)
 #undef dout_prefix
 #define dout_prefix *_dout
 
+
+#define CLS_PREFIX "libcls_"
+#define CLS_SUFFIX ".so"
+
+
 int ClassHandler::open_class(const string& cname, ClassData **pcls)
 {
   Mutex::Locker lock(mutex);
@@ -31,6 +36,37 @@ int ClassHandler::open_class(const string& cname, ClassData **pcls)
   return 0;
 }
 
+int ClassHandler::open_all_classes()
+{
+  dout(10) << __func__ << dendl;
+  DIR *dir = ::opendir(g_conf->osd_class_dir.c_str());
+  if (!dir)
+    return -errno;
+
+  char buf[offsetof(struct dirent, d_name) + PATH_MAX + 1];
+  struct dirent *pde;
+  int r = 0;
+  while ((r = ::readdir_r(dir, (dirent *)&buf, &pde)) == 0 && pde) {
+    if (pde->d_name[0] == '.')
+      continue;
+    if (strlen(pde->d_name) > sizeof(CLS_PREFIX) - 1 + sizeof(CLS_SUFFIX) - 1 &&
+       strncmp(pde->d_name, CLS_PREFIX, sizeof(CLS_PREFIX) - 1) == 0 &&
+       strcmp(pde->d_name + strlen(pde->d_name) - (sizeof(CLS_SUFFIX) - 1), CLS_SUFFIX) == 0) {
+      char cname[strlen(pde->d_name)];
+      strcpy(cname, pde->d_name + sizeof(CLS_PREFIX) - 1);
+      cname[strlen(cname) - (sizeof(CLS_SUFFIX) - 1)] = '\0';
+      dout(10) << __func__ << " found " << cname << dendl;
+      ClassData *cls;
+      r = open_class(cname, &cls);
+      if (r < 0)
+       goto out;
+    }
+  }
+ out:
+  closedir(dir);
+  return r;
+}
+
 ClassHandler::ClassData *ClassHandler::_get_class(const string& cname)
 {
   ClassData *cls;
@@ -56,7 +92,7 @@ int ClassHandler::_load_class(ClassData *cls)
   if (cls->status == ClassData::CLASS_UNKNOWN ||
       cls->status == ClassData::CLASS_MISSING) {
     char fname[PATH_MAX];
-    snprintf(fname, sizeof(fname), "%s/libcls_%s.so",
+    snprintf(fname, sizeof(fname), "%s/" CLS_PREFIX "%s" CLS_SUFFIX,
             g_conf->osd_class_dir.c_str(),
             cls->name.c_str());
     dout(10) << "_load_class " << cls->name << " from " << fname << dendl;
index f336d861fbcc4372147f8bacf2b0c63a071def75..0a391b9b0721894c316428dad772305dbcb76f53 100644 (file)
@@ -78,6 +78,8 @@ private:
 public:
   ClassHandler() : mutex("ClassHandler") {}
   
+  int open_all_classes();
+
   int open_class(const string& cname, ClassData **pcls);
   
   ClassData *register_class(const char *cname);
index 6202bac3461d9d07db4791f68b75b27855620a8f..e2894e81559c9ab0fe64de235c353bf7f4d98a73 100644 (file)
@@ -1090,6 +1090,7 @@ int OSD::init()
 
   class_handler = new ClassHandler();
   cls_initialize(class_handler);
+  class_handler->open_all_classes();
 
   // load up "current" osdmap
   assert_warn(!osdmap);