From: Loic Dachary Date: Thu, 21 Aug 2014 16:38:52 +0000 (+0200) Subject: erasure-code: add Ceph version check to plugins X-Git-Tag: v0.86~193^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3c4220e14de50ee74252f90615e050076b0ce442;p=ceph.git erasure-code: add Ceph version check to plugins Add the __erasure_code_version function to all plugins, to return the Ceph version against which they have been compiled. When a plugin is loaded, an error is thrown if the version of the plugin does not match the version of the daemon loading it. If the symbol does not exist, which will be true of older plugins, set the version to "an older version" so it never matches. http://tracker.ceph.com/issues/9167 Fixes: #9167 Signed-off-by: Loic Dachary --- diff --git a/src/erasure-code/ErasureCodePlugin.cc b/src/erasure-code/ErasureCodePlugin.cc index fa3dec02bcc6..297b3c82cef0 100644 --- a/src/erasure-code/ErasureCodePlugin.cc +++ b/src/erasure-code/ErasureCodePlugin.cc @@ -18,6 +18,7 @@ #include #include +#include "ceph_ver.h" #include "ErasureCodePlugin.h" #include "common/errno.h" #include "include/str_list.h" @@ -25,6 +26,7 @@ #define PLUGIN_PREFIX "libec_" #define PLUGIN_SUFFIX ".so" #define PLUGIN_INIT_FUNCTION "__erasure_code_init" +#define PLUGIN_VERSION_FUNCTION "__erasure_code_version" ErasureCodePluginRegistry ErasureCodePluginRegistry::singleton; @@ -101,6 +103,10 @@ int ErasureCodePluginRegistry::factory(const std::string &plugin_name, return plugin->factory(parameters, erasure_code); } +static const char *an_older_version() { + return "an older version"; +} + int ErasureCodePluginRegistry::load(const std::string &plugin_name, const std::string &directory, ErasureCodePlugin **plugin, @@ -114,6 +120,17 @@ int ErasureCodePluginRegistry::load(const std::string &plugin_name, return -EIO; } + const char * (*erasure_code_version)() = + (const char *(*)())dlsym(library, PLUGIN_VERSION_FUNCTION); + if (erasure_code_version == NULL) + erasure_code_version = an_older_version; + if (erasure_code_version() != string(CEPH_GIT_NICE_VER)) { + ss << "expected plugin " << fname << " version " << CEPH_GIT_NICE_VER + << " but it claims to be " << erasure_code_version() << " instead"; + dlclose(library); + return -EXDEV; + } + int (*erasure_code_init)(const char *, const char *) = (int (*)(const char *, const char *))dlsym(library, PLUGIN_INIT_FUNCTION); if (erasure_code_init) { diff --git a/src/erasure-code/ErasureCodePlugin.h b/src/erasure-code/ErasureCodePlugin.h index 3348eacc425b..035bf2e5f139 100644 --- a/src/erasure-code/ErasureCodePlugin.h +++ b/src/erasure-code/ErasureCodePlugin.h @@ -22,6 +22,7 @@ #include "ErasureCodeInterface.h" extern "C" { + const char *__erasure_code_version(); int __erasure_code_init(char *plugin_name, char *directory); } diff --git a/src/erasure-code/Makefile.am b/src/erasure-code/Makefile.am index 5983ceaf395f..bada0a422f68 100644 --- a/src/erasure-code/Makefile.am +++ b/src/erasure-code/Makefile.am @@ -11,7 +11,7 @@ endif # WITH_BETTER_YASM_ELF64 liberasure_code_la_SOURCES = \ erasure-code/ErasureCodePlugin.cc - +erasure-code/ErasureCodePlugin.cc: ./ceph_ver.h if LINUX liberasure_code_la_LIBADD = -ldl endif # LINUX diff --git a/src/erasure-code/isa/ErasureCodePluginIsa.cc b/src/erasure-code/isa/ErasureCodePluginIsa.cc index 1bd9d25dd578..03afab92be01 100644 --- a/src/erasure-code/isa/ErasureCodePluginIsa.cc +++ b/src/erasure-code/isa/ErasureCodePluginIsa.cc @@ -25,6 +25,7 @@ */ // ----------------------------------------------------------------------------- +#include "ceph_ver.h" #include "common/debug.h" #include "erasure-code/ErasureCodePlugin.h" #include "ErasureCodeIsa.h" @@ -76,6 +77,8 @@ public: // ----------------------------------------------------------------------------- +const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + int __erasure_code_init(char *plugin_name, char *directory) { ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); diff --git a/src/erasure-code/isa/Makefile.am b/src/erasure-code/isa/Makefile.am index a17faed325b3..2a30578f3d20 100644 --- a/src/erasure-code/isa/Makefile.am +++ b/src/erasure-code/isa/Makefile.am @@ -38,6 +38,8 @@ isa_sources = \ erasure-code/isa/ErasureCodePluginIsa.cc \ erasure-code/isa/xor_op.cc +erasure-code/isa/ErasureCodePluginIsa.cc: ./ceph_ver.h + libec_isa_la_SOURCES = ${isa_sources} libec_isa_la_CFLAGS = ${AM_CFLAGS} -I $(srcdir)/erasure-code/isa/isa-l/include/ diff --git a/src/erasure-code/jerasure/ErasureCodePluginJerasure.cc b/src/erasure-code/jerasure/ErasureCodePluginJerasure.cc index 8f4f5c6ee46b..e5f8b839f685 100644 --- a/src/erasure-code/jerasure/ErasureCodePluginJerasure.cc +++ b/src/erasure-code/jerasure/ErasureCodePluginJerasure.cc @@ -15,6 +15,7 @@ * */ +#include "ceph_ver.h" #include "common/debug.h" #include "erasure-code/ErasureCodePlugin.h" #include "ErasureCodeJerasure.h" @@ -71,6 +72,8 @@ extern gf_t *gfp_array[]; extern int gfp_is_composite[]; } +const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + int __erasure_code_init(char *plugin_name, char *directory) { ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); diff --git a/src/erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc b/src/erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc index dfb609538804..53c70266a9b2 100644 --- a/src/erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc +++ b/src/erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc @@ -15,6 +15,7 @@ * */ +#include "ceph_ver.h" #include "common/debug.h" #include "arch/probe.h" #include "arch/intel.h" @@ -74,6 +75,8 @@ public: } }; +const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + int __erasure_code_init(char *plugin_name, char *directory) { ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); diff --git a/src/erasure-code/jerasure/Makefile.am b/src/erasure-code/jerasure/Makefile.am index 914d1eda6cd8..86763af9d119 100644 --- a/src/erasure-code/jerasure/Makefile.am +++ b/src/erasure-code/jerasure/Makefile.am @@ -33,6 +33,8 @@ jerasure_sources = \ erasure-code/jerasure/ErasureCodePluginJerasure.cc \ erasure-code/jerasure/ErasureCodeJerasure.cc +erasure-code/jerasure/ErasureCodePluginJerasure.cc: ./ceph_ver.h + libec_jerasure_generic_la_SOURCES = ${jerasure_sources} libec_jerasure_generic_la_CFLAGS = ${AM_CFLAGS} \ -I$(srcdir)/erasure-code/jerasure/gf-complete/include \ @@ -108,4 +110,6 @@ if LINUX libec_jerasure_la_LDFLAGS += -export-symbols-regex '.*__erasure_code_.*' endif +erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc: ./ceph_ver.h + erasure_codelib_LTLIBRARIES += libec_jerasure.la diff --git a/src/test/erasure-code/ErasureCodePluginExample.cc b/src/test/erasure-code/ErasureCodePluginExample.cc index 1d62a9da1f43..7c8aaffe7897 100644 --- a/src/test/erasure-code/ErasureCodePluginExample.cc +++ b/src/test/erasure-code/ErasureCodePluginExample.cc @@ -17,6 +17,7 @@ #include +#include "ceph_ver.h" #include "erasure-code/ErasureCodePlugin.h" #include "ErasureCodeExample.h" @@ -30,6 +31,8 @@ public: } }; +const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + int __erasure_code_init(char *plugin_name, char *directory) { ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); diff --git a/src/test/erasure-code/ErasureCodePluginFailToInitialize.cc b/src/test/erasure-code/ErasureCodePluginFailToInitialize.cc index 84b0ae499148..f1219fab42af 100644 --- a/src/test/erasure-code/ErasureCodePluginFailToInitialize.cc +++ b/src/test/erasure-code/ErasureCodePluginFailToInitialize.cc @@ -16,9 +16,11 @@ */ #include -#include "erasure-code/ErasureCodePlugin.h" +#include "ceph_ver.h" -int __erasure_code_init(char *plugin_name, char *directory) +extern "C" const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + +extern "C" int __erasure_code_init(char *plugin_name, char *directory) { return -ESRCH; } diff --git a/src/test/erasure-code/ErasureCodePluginFailToRegister.cc b/src/test/erasure-code/ErasureCodePluginFailToRegister.cc index 62518473b75b..9e8e0161e5c5 100644 --- a/src/test/erasure-code/ErasureCodePluginFailToRegister.cc +++ b/src/test/erasure-code/ErasureCodePluginFailToRegister.cc @@ -15,9 +15,11 @@ * */ -#include "erasure-code/ErasureCodePlugin.h" +#include "ceph_ver.h" -int __erasure_code_init(char *plugin_name, char *directory) +extern "C" const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + +extern "C" int __erasure_code_init(char *plugin_name, char *directory) { return 0; } diff --git a/src/test/erasure-code/ErasureCodePluginHangs.cc b/src/test/erasure-code/ErasureCodePluginHangs.cc index 30050c3460d3..66db8e5cd39b 100644 --- a/src/test/erasure-code/ErasureCodePluginHangs.cc +++ b/src/test/erasure-code/ErasureCodePluginHangs.cc @@ -16,7 +16,9 @@ */ #include -#include "erasure-code/ErasureCodePlugin.h" +#include "ceph_ver.h" + +extern "C" const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } int __erasure_code_init(char *plugin_name, char *directory) { diff --git a/src/test/erasure-code/ErasureCodePluginMissingEntryPoint.cc b/src/test/erasure-code/ErasureCodePluginMissingEntryPoint.cc index c7ba17231cbc..8a55214b195d 100644 --- a/src/test/erasure-code/ErasureCodePluginMissingEntryPoint.cc +++ b/src/test/erasure-code/ErasureCodePluginMissingEntryPoint.cc @@ -1,4 +1,6 @@ +#include "ceph_ver.h" + // missing int __erasure_code_init(char *plugin_name, char *directory) {} -// avoid warnings about library containing no symbols -int __this_is_an_used_variable_to_avoid_warnings; +extern "C" const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + diff --git a/src/test/erasure-code/ErasureCodePluginMissingVersion.cc b/src/test/erasure-code/ErasureCodePluginMissingVersion.cc new file mode 100644 index 000000000000..da4ed0e48f6f --- /dev/null +++ b/src/test/erasure-code/ErasureCodePluginMissingVersion.cc @@ -0,0 +1,3 @@ +// missing __erasure_code_version + +int __this_is_an_used_variable_to_avoid_warnings; diff --git a/src/test/erasure-code/Makefile.am b/src/test/erasure-code/Makefile.am index be1ac77de9dc..e142f4e552b8 100644 --- a/src/test/erasure-code/Makefile.am +++ b/src/test/erasure-code/Makefile.am @@ -18,6 +18,7 @@ endif bin_DEBUGPROGRAMS += ceph_erasure_code libec_example_la_SOURCES = test/erasure-code/ErasureCodePluginExample.cc +test/erasure-code/ErasureCodePluginExample.cc: ./ceph_ver.h libec_example_la_CFLAGS = ${AM_CFLAGS} libec_example_la_CXXFLAGS= ${AM_CXXFLAGS} libec_example_la_LIBADD = $(LIBCRUSH) $(PTHREAD_LIBS) $(EXTRALIBS) @@ -25,13 +26,22 @@ libec_example_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code erasure_codelib_LTLIBRARIES += libec_example.la libec_missing_entry_point_la_SOURCES = test/erasure-code/ErasureCodePluginMissingEntryPoint.cc +test/erasure-code/ErasureCodePluginMissingEntryPoint.cc: ./ceph_ver.h libec_missing_entry_point_la_CFLAGS = ${AM_CFLAGS} libec_missing_entry_point_la_CXXFLAGS= ${AM_CXXFLAGS} libec_missing_entry_point_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) libec_missing_entry_point_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code_.*' erasure_codelib_LTLIBRARIES += libec_missing_entry_point.la +libec_missing_version_la_SOURCES = test/erasure-code/ErasureCodePluginMissingVersion.cc +libec_missing_version_la_CFLAGS = ${AM_CFLAGS} +libec_missing_version_la_CXXFLAGS= ${AM_CXXFLAGS} +libec_missing_version_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) +libec_missing_version_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code_.*' +erasure_codelib_LTLIBRARIES += libec_missing_version.la + libec_hangs_la_SOURCES = test/erasure-code/ErasureCodePluginHangs.cc +test/erasure-code/ErasureCodePluginHangs.cc: ./ceph_ver.h libec_hangs_la_CFLAGS = ${AM_CFLAGS} libec_hangs_la_CXXFLAGS= ${AM_CXXFLAGS} libec_hangs_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) @@ -39,6 +49,7 @@ libec_hangs_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code_. erasure_codelib_LTLIBRARIES += libec_hangs.la libec_fail_to_initialize_la_SOURCES = test/erasure-code/ErasureCodePluginFailToInitialize.cc +test/erasure-code/ErasureCodePluginFailToInitialize.cc: ./ceph_ver.h libec_fail_to_initialize_la_CFLAGS = ${AM_CFLAGS} libec_fail_to_initialize_la_CXXFLAGS= ${AM_CXXFLAGS} libec_fail_to_initialize_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) @@ -46,6 +57,7 @@ libec_fail_to_initialize_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__e erasure_codelib_LTLIBRARIES += libec_fail_to_initialize.la libec_fail_to_register_la_SOURCES = test/erasure-code/ErasureCodePluginFailToRegister.cc +test/erasure-code/ErasureCodePluginFailToRegister.cc: ./ceph_ver.h libec_fail_to_register_la_CFLAGS = ${AM_CFLAGS} libec_fail_to_register_la_CXXFLAGS= ${AM_CXXFLAGS} libec_fail_to_register_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) @@ -53,6 +65,7 @@ libec_fail_to_register_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__era erasure_codelib_LTLIBRARIES += libec_fail_to_register.la libec_test_jerasure_sse4_la_SOURCES = test/erasure-code/TestJerasurePluginSSE4.cc +test/erasure-code/TestJerasurePluginSSE4.cc: ./ceph_ver.h libec_test_jerasure_sse4_la_CFLAGS = ${AM_CFLAGS} libec_test_jerasure_sse4_la_CXXFLAGS= ${AM_CXXFLAGS} libec_test_jerasure_sse4_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) @@ -60,6 +73,7 @@ libec_test_jerasure_sse4_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__e erasure_codelib_LTLIBRARIES += libec_test_jerasure_sse4.la libec_test_jerasure_sse3_la_SOURCES = test/erasure-code/TestJerasurePluginSSE3.cc +test/erasure-code/TestJerasurePluginSSE3.cc: ./ceph_ver.h libec_test_jerasure_sse3_la_CFLAGS = ${AM_CFLAGS} libec_test_jerasure_sse3_la_CXXFLAGS= ${AM_CXXFLAGS} libec_test_jerasure_sse3_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) @@ -67,6 +81,7 @@ libec_test_jerasure_sse3_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__e erasure_codelib_LTLIBRARIES += libec_test_jerasure_sse3.la libec_test_jerasure_generic_la_SOURCES = test/erasure-code/TestJerasurePluginGeneric.cc +test/erasure-code/TestJerasurePluginGeneric.cc: ./ceph_ver.h libec_test_jerasure_generic_la_CFLAGS = ${AM_CFLAGS} libec_test_jerasure_generic_la_CXXFLAGS= ${AM_CXXFLAGS} libec_test_jerasure_generic_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) diff --git a/src/test/erasure-code/TestErasureCodePlugin.cc b/src/test/erasure-code/TestErasureCodePlugin.cc index e9ffaa2c7dc9..e3d814cb1fbc 100644 --- a/src/test/erasure-code/TestErasureCodePlugin.cc +++ b/src/test/erasure-code/TestErasureCodePlugin.cc @@ -81,6 +81,9 @@ TEST_F(ErasureCodePluginRegistryTest, all) EXPECT_FALSE(erasure_code); EXPECT_EQ(-EIO, instance.factory("invalid", parameters, &erasure_code, ss)); EXPECT_FALSE(erasure_code); + EXPECT_EQ(-EXDEV, instance.factory("missing_version", parameters, + &erasure_code, ss)); + EXPECT_FALSE(erasure_code); EXPECT_EQ(-ENOENT, instance.factory("missing_entry_point", parameters, &erasure_code, ss)); EXPECT_FALSE(erasure_code); diff --git a/src/test/erasure-code/TestJerasurePluginGeneric.cc b/src/test/erasure-code/TestJerasurePluginGeneric.cc index 40d540c93742..e7a759757a9f 100644 --- a/src/test/erasure-code/TestJerasurePluginGeneric.cc +++ b/src/test/erasure-code/TestJerasurePluginGeneric.cc @@ -15,9 +15,11 @@ * */ -#include "erasure-code/ErasureCodePlugin.h" +#include "ceph_ver.h" -int __erasure_code_init(char *plugin_name, char *directory) +extern "C" const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + +extern "C" int __erasure_code_init(char *plugin_name, char *directory) { return -111; } diff --git a/src/test/erasure-code/TestJerasurePluginSSE3.cc b/src/test/erasure-code/TestJerasurePluginSSE3.cc index c5e2d7b5fee9..0c752b2dd7dd 100644 --- a/src/test/erasure-code/TestJerasurePluginSSE3.cc +++ b/src/test/erasure-code/TestJerasurePluginSSE3.cc @@ -15,9 +15,11 @@ * */ -#include "erasure-code/ErasureCodePlugin.h" +#include "ceph_ver.h" -int __erasure_code_init(char *plugin_name, char *directory) +extern "C" const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + +extern "C" int __erasure_code_init(char *plugin_name, char *directory) { return -333; } diff --git a/src/test/erasure-code/TestJerasurePluginSSE4.cc b/src/test/erasure-code/TestJerasurePluginSSE4.cc index aa943a922dda..a39a9b41150a 100644 --- a/src/test/erasure-code/TestJerasurePluginSSE4.cc +++ b/src/test/erasure-code/TestJerasurePluginSSE4.cc @@ -15,9 +15,11 @@ * */ -#include "erasure-code/ErasureCodePlugin.h" +#include "ceph_ver.h" -int __erasure_code_init(char *plugin_name, char *directory) +extern "C" const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + +extern "C" int __erasure_code_init(char *plugin_name, char *directory) { return -444; }