]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
erasure-code: add Ceph version check to plugins
authorLoic Dachary <loic-201408@dachary.org>
Thu, 21 Aug 2014 16:38:52 +0000 (18:38 +0200)
committerLoic Dachary <loic-201408@dachary.org>
Thu, 28 Aug 2014 10:17:15 +0000 (12:17 +0200)
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 <loic-201408@dachary.org>
19 files changed:
src/erasure-code/ErasureCodePlugin.cc
src/erasure-code/ErasureCodePlugin.h
src/erasure-code/Makefile.am
src/erasure-code/isa/ErasureCodePluginIsa.cc
src/erasure-code/isa/Makefile.am
src/erasure-code/jerasure/ErasureCodePluginJerasure.cc
src/erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc
src/erasure-code/jerasure/Makefile.am
src/test/erasure-code/ErasureCodePluginExample.cc
src/test/erasure-code/ErasureCodePluginFailToInitialize.cc
src/test/erasure-code/ErasureCodePluginFailToRegister.cc
src/test/erasure-code/ErasureCodePluginHangs.cc
src/test/erasure-code/ErasureCodePluginMissingEntryPoint.cc
src/test/erasure-code/ErasureCodePluginMissingVersion.cc [new file with mode: 0644]
src/test/erasure-code/Makefile.am
src/test/erasure-code/TestErasureCodePlugin.cc
src/test/erasure-code/TestJerasurePluginGeneric.cc
src/test/erasure-code/TestJerasurePluginSSE3.cc
src/test/erasure-code/TestJerasurePluginSSE4.cc

index fa3dec02bcc629f9350f3b95d2759b7f7852c63c..297b3c82cef0520af3d3f7ab52a6190a590929f1 100644 (file)
@@ -18,6 +18,7 @@
 #include <errno.h>
 #include <dlfcn.h>
 
+#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) {
index 3348eacc425b2d2a17fa32901043ee5e8da86d48..035bf2e5f1392c352212c0df68cec387f9de2290 100644 (file)
@@ -22,6 +22,7 @@
 #include "ErasureCodeInterface.h"
 
 extern "C" {
+  const char *__erasure_code_version();
   int __erasure_code_init(char *plugin_name, char *directory);
 }
 
index 5983ceaf395fecda00b307e2d81b736254483812..bada0a422f683f61665448cb3d88a5e09a836f87 100644 (file)
@@ -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
index 1bd9d25dd578a5fdf27842b878df22347ca4d09c..03afab92be014799ab2a9af8453f73aeea7fa0a4 100644 (file)
@@ -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();
index a17faed325b3c8fa81115980c7ba5067547d9510..2a30578f3d208c374a31b56d4894b8cb25673dfa 100644 (file)
@@ -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/
index 8f4f5c6ee46b173f746d78eee1ac6446c5a21ae1..e5f8b839f6856e2b8479ddc9e728f081d4dbe71c 100644 (file)
@@ -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();
index dfb609538804c1d1ac8e186f64f506b58082f7f7..53c70266a9b239b4f4f30e842ae6dfbaa7f4152d 100644 (file)
@@ -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();
index 914d1eda6cd8deff9edcf60b855a821f8c157564..86763af9d119f7fa5ad75e2b2be2c83b0cb3070f 100644 (file)
@@ -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
index 1d62a9da1f43b0bdf69961b78c609a2010f61385..7c8aaffe7897a1659d6c486c6fb73d79f96eca17 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <unistd.h>
 
+#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();
index 84b0ae499148bfd77bd5d1a36c542e4e2be6a0f0..f1219fab42af2c8392131b8f3386bc59870e747d 100644 (file)
  */
 
 #include <errno.h>
-#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;
 }
index 62518473b75b8a4a48238119e0211f05549faca8..9e8e0161e5c53919452f009f6bcedc4f06ab239c 100644 (file)
  * 
  */
 
-#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;
 }
index 30050c3460d36c7d71235186943fb58a4824413b..66db8e5cd39bf09e14271799cde128b05679df8d 100644 (file)
@@ -16,7 +16,9 @@
  */
 
 #include <unistd.h>
-#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)
 {
index c7ba17231cbcd61e6d011048d01b8453cab3081c..8a55214b195dffb2e810d0576efd352bf0637aaa 100644 (file)
@@ -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 (file)
index 0000000..da4ed0e
--- /dev/null
@@ -0,0 +1,3 @@
+// missing __erasure_code_version
+
+int __this_is_an_used_variable_to_avoid_warnings;
index be1ac77de9dc03ea4aa6a471f4979263fddbd0f6..e142f4e552b89724bd10d9288680396612ac05b0 100644 (file)
@@ -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)
index e9ffaa2c7dc96afdcef5819c6c764c2a7baa326d..e3d814cb1fbc1f58597be744d94d8b154b8b2dbf 100644 (file)
@@ -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);
index 40d540c9374233f77ab3ac785433dc350b9bf18e..e7a759757a9f1ed596d639664ca0b7fc072a37dc 100644 (file)
  * 
  */
 
-#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;
 }
index c5e2d7b5fee91ed77513e3edf42252dff09b56ae..0c752b2dd7dd78f310042903b2381153de2fe8aa 100644 (file)
  * 
  */
 
-#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;
 }
index aa943a922ddaa2ea233493a7554e247dc5ca88cc..a39a9b41150a000f660ad36b3eed847f8a59fd49 100644 (file)
  * 
  */
 
-#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;
 }