summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-07-26 13:58:46 -0700
committerSage Weil <sage@inktank.com>2013-08-07 13:52:39 -0700
commite8253ae5451b1c8e3d7d50199b8db7b2d4c66486 (patch)
tree5d30819308c2d38ec9737536c6052fc206ab59af
parent7a1d6d3e727fd8b6947c658e171bf7ec31cd7966 (diff)
downloadceph-e8253ae5451b1c8e3d7d50199b8db7b2d4c66486.tar.gz
osd: load all classes on startup
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
-rw-r--r--src/osd/ClassHandler.cc38
-rw-r--r--src/osd/ClassHandler.h2
-rw-r--r--src/osd/OSD.cc1
3 files changed, 40 insertions, 1 deletions
diff --git a/src/osd/ClassHandler.cc b/src/osd/ClassHandler.cc
index 6675e9e4fc4..9137b64be57 100644
--- a/src/osd/ClassHandler.cc
+++ b/src/osd/ClassHandler.cc
@@ -18,6 +18,11 @@
#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;
diff --git a/src/osd/ClassHandler.h b/src/osd/ClassHandler.h
index f336d861fbc..0a391b9b072 100644
--- a/src/osd/ClassHandler.h
+++ b/src/osd/ClassHandler.h
@@ -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);
diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc
index 6202bac3461..e2894e81559 100644
--- a/src/osd/OSD.cc
+++ b/src/osd/OSD.cc
@@ -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);