diff options
author | Sage Weil <sage@inktank.com> | 2013-07-26 13:58:46 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-08-07 13:52:39 -0700 |
commit | e8253ae5451b1c8e3d7d50199b8db7b2d4c66486 (patch) | |
tree | 5d30819308c2d38ec9737536c6052fc206ab59af | |
parent | 7a1d6d3e727fd8b6947c658e171bf7ec31cd7966 (diff) | |
download | ceph-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.cc | 38 | ||||
-rw-r--r-- | src/osd/ClassHandler.h | 2 | ||||
-rw-r--r-- | src/osd/OSD.cc | 1 |
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); |