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 fa3dec02bcc..297b3c82cef 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 3348eacc425..035bf2e5f13 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 5983ceaf395..bada0a422f6 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 1bd9d25dd57..03afab92be0 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 a17faed325b..2a30578f3d2 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 8f4f5c6ee46..e5f8b839f68 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 dfb60953880..53c70266a9b 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 914d1eda6cd..86763af9d11 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 1d62a9da1f4..7c8aaffe789 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 84b0ae49914..f1219fab42a 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 62518473b75..9e8e0161e5c 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 30050c3460d..66db8e5cd39 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 c7ba17231cb..8a55214b195 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 00000000000..da4ed0e48f6 --- /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 be1ac77de9d..e142f4e552b 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 e9ffaa2c7dc..e3d814cb1fb 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 40d540c9374..e7a759757a9 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 c5e2d7b5fee..0c752b2dd7d 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 aa943a922dd..a39a9b41150 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; }