]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
erasure-code: Backward compatibility with legacy EC plugins
authorBassam Tabbara <bassam.tabbara@quantum.com>
Wed, 21 Sep 2016 14:00:01 +0000 (07:00 -0700)
committerBassam Tabbara <bassam.tabbara@quantum.com>
Thu, 29 Sep 2016 17:34:34 +0000 (10:34 -0700)
Resurrected jerasure_generic, jerasure_sse3, jerasure_sse4, jerasure_neon,
shec_generic, shec_sse3, shec_sse4 and shec_neon. These all are exact
copies of the new jerasure and shec plugins that support SIMD detection.

Moved EC preload code in ceph-mon and ceph-osd to a central location, added
warning when preloading legacy plugins.

OSMonitor::get_erasure_code and OSDMonitor:normalize_profile will now check
if legacy EC plugins are used and log a warning.

Added tests to check that warnings make it to the log.

Signed-off-by: Bassam Tabbara <bassam.tabbara@quantum.com>
12 files changed:
cmake/modules/SIMDExt.cmake
src/ceph_mon.cc
src/ceph_osd.cc
src/erasure-code/CMakeLists.txt
src/erasure-code/jerasure/CMakeLists.txt
src/erasure-code/shec/CMakeLists.txt
src/global/global_init.cc
src/global/global_init.h
src/mon/OSDMonitor.cc
src/mon/OSDMonitor.h
src/test/erasure-code/CMakeLists.txt
src/test/erasure-code/test-erasure-code-plugins.sh [new file with mode: 0755]

index 378e2f843c45e71f4243703778d476ed8b93ec48..c531d8ca2f25b37614438cc4d301ec8a2b691357 100644 (file)
@@ -15,6 +15,7 @@
 #
 
 if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64")
+  set(HAVE_ARM 1) 
   CHECK_C_COMPILER_FLAG(-march=armv8-a+crc HAVE_ARMV8_CRC)
   if(HAVE_ARMV8_CRC)
     set(ARM_CRC_FLAGS "-march=armv8-a+crc")
@@ -24,11 +25,13 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64")
     set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -march=armv8-a+simd")
   endif()
 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM")
+  set(HAVE_ARM 1) 
   CHECK_C_COMPILER_FLAG(-mfpu=neon HAVE_ARM_NEON)
   if(HAVE_ARM_NEON)
     set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -mfpu=neon")
   endif()
 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686|amd64|x86_64|AMD64")
+  set(HAVE_INTEL 1) 
   CHECK_C_COMPILER_FLAG(-msse HAVE_INTEL_SSE)
   if(HAVE_INTEL_SSE)
     set(SIMD_COMPILE_FLAGS "${SIMD_COMPILE_FLAGS} -msse")
index 5755827f3ad14a22da1b88961237209bc6ed9b9c..de0447606c28113a9d0bc20ac5b85191c781a350 100644 (file)
@@ -45,8 +45,6 @@ using namespace std;
 
 #include "include/assert.h"
 
-#include "erasure-code/ErasureCodePlugin.h"
-
 #define dout_subsys ceph_subsys_mon
 
 Monitor *mon = NULL;
@@ -181,21 +179,6 @@ void usage()
   generic_server_usage();
 }
 
-int preload_erasure_code()
-{
-  string plugins = g_conf->osd_erasure_code_plugins;
-  stringstream ss;
-  int r = ErasureCodePluginRegistry::instance().preload(
-    plugins,
-    g_conf->erasure_code_dir,
-    &ss);
-  if (r)
-    derr << ss.str() << dendl;
-  else
-    dout(10) << ss.str() << dendl;
-  return r;
-}
-
 int main(int argc, const char **argv) 
 {
   int err;
@@ -507,7 +490,7 @@ int main(int argc, const char **argv)
     }
     common_init_finish(g_ceph_context);
     global_init_chdir(g_ceph_context);
-    if (preload_erasure_code() < 0)
+    if (global_init_preload_erasure_code(g_ceph_context) < 0)
       prefork.exit(1);
   }
 
index 33fafe1a3830f734be5042fe5621243d8321c3d9..521d9e87c6a138031dc900e4a039d08854c6e1ba 100644 (file)
@@ -47,8 +47,6 @@ using namespace std;
 
 #include "include/assert.h"
 
-#include "erasure-code/ErasureCodePlugin.h"
-
 #define dout_subsys ceph_subsys_osd
 
 namespace {
@@ -92,21 +90,6 @@ void usage()
   generic_server_usage();
 }
 
-int preload_erasure_code()
-{
-  string plugins = g_conf->osd_erasure_code_plugins;
-  stringstream ss;
-  int r = ErasureCodePluginRegistry::instance().preload(
-    plugins,
-    g_conf->erasure_code_dir,
-    &ss);
-  if (r)
-    derr << ss.str() << dendl;
-  else
-    dout(10) << ss.str() << dendl;
-  return r;
-}
-
 int main(int argc, const char **argv) 
 {
   vector<const char*> args;
@@ -575,7 +558,7 @@ int main(int argc, const char **argv)
     return -1;
   global_init_chdir(g_ceph_context);
 
-  if (preload_erasure_code() < 0)
+  if (global_init_preload_erasure_code(g_ceph_context) < 0)
     return -1;
 
   osd = new OSD(g_ceph_context,
index 943dea187f263bdd1c466d67f713a52c55567a59..1b4870403a366962214cbb97ec04ec4ab7d05ec4 100644 (file)
@@ -7,6 +7,16 @@ include_directories(jerasure/jerasure/include)
 include_directories(jerasure/gf-complete/include)
 include_directories(jerasure)
 
+# legacy jerasure flavors. these are left here for backward compatibility
+# and should be removed in future versions
+set(jerasure_legacy_flavors generic)
+if(HAVE_ARM)
+  list(APPEND jerasure_legacy_flavors neon)
+endif()
+if(HAVE_INTEL)
+ list(APPEND jerasure_legacy_flavors sse3 sse4)
+endif()
+
 add_subdirectory(jerasure)
 add_subdirectory(lrc)
 add_subdirectory(shec)
@@ -25,4 +35,5 @@ add_library(erasure_code_objs OBJECT ErasureCode.cc)
 add_custom_target(erasure_code_plugins DEPENDS
     ${EC_ISA_LIB}
     ec_lrc
-    ec_jerasure)
+    ec_jerasure
+    ec_shec)
index a17f5c392382a2a3d9f0ddef8034534fd431b085..3225b6b99e114e91c943c1967201280fcad4deb6 100644 (file)
@@ -72,10 +72,21 @@ set(jerasure_srcs
   jerasure_init.cc)
 add_library(jerasure_objs OBJECT ${jerasure_srcs}) 
 
-add_library(ec_jerasure SHARED
+set(ec_jerasure_objs
   $<TARGET_OBJECTS:gf-complete_objs>
   $<TARGET_OBJECTS:jerasure_objs>
   $<TARGET_OBJECTS:jerasure_utils>
   $<TARGET_OBJECTS:erasure_code_objs>)
+
+add_library(ec_jerasure SHARED ${ec_jerasure_objs})
 target_link_libraries(ec_jerasure ${EXTRALIBS})
 install(TARGETS ec_jerasure DESTINATION ${erasure_plugin_dir})
+
+# legacy libraries
+foreach(flavor ${jerasure_legacy_flavors})
+  set(plugin_name "ec_jerasure_${flavor}")
+  add_library(${plugin_name} SHARED ${ec_jerasure_objs})
+  install(TARGETS ${plugin_name} DESTINATION ${erasure_plugin_dir})
+  add_dependencies(ec_jerasure ${plugin_name})
+endforeach()
+
index 4c5eaf408b85b9d553e7a7ceb0138eb8f9b7ee66..64cac19465fe92b27b201a5f330cd3b0e6a5f8bc 100644 (file)
@@ -10,10 +10,20 @@ add_library(shec_utils OBJECT
   determinant.c)
 add_dependencies(shec_utils ${CMAKE_SOURCE_DIR}/src/ceph_ver.h)
 
-add_library(ec_shec SHARED
+set(ec_shec_objs
   $<TARGET_OBJECTS:gf-complete_objs>
   $<TARGET_OBJECTS:jerasure_objs>
   $<TARGET_OBJECTS:shec_utils>)
+
+add_library(ec_shec SHARED ${ec_shec_objs})
 add_dependencies(ec_shec ${CMAKE_SOURCE_DIR}/src/ceph_ver.h)
 target_link_libraries(ec_shec ${EXTRALIBS})
 install(TARGETS ec_shec DESTINATION ${erasure_plugin_dir})
+
+# legacy libraries
+foreach(flavor ${jerasure_legacy_flavors})
+  set(plugin_name "ec_shec_${flavor}")
+  add_library(${plugin_name} SHARED ${ec_shec_objs})
+  install(TARGETS ${plugin_name} DESTINATION ${erasure_plugin_dir})
+  add_dependencies(ec_shec ${plugin_name})
+endforeach()
index 033516240b6c5b6fecb8ffb63d67292b9f743ce2..3a905c0b5763cf1c96fc1217a8241dc8a79b75e4 100644 (file)
 #include "common/errno.h"
 #include "common/signal.h"
 #include "common/version.h"
+#include "erasure-code/ErasureCodePlugin.h"
 #include "global/global_context.h"
 #include "global/global_init.h"
 #include "global/pidfile.h"
 #include "global/signal_handler.h"
 #include "include/compat.h"
+#include "include/str_list.h"
 
 #include <pwd.h>
 #include <grp.h>
@@ -454,3 +456,48 @@ int global_init_shutdown_stderr(CephContext *cct)
   return 0;
 }
 
+int global_init_preload_erasure_code(const CephContext *cct)
+{
+  const md_config_t *conf = cct->_conf;
+  string plugins = conf->osd_erasure_code_plugins;
+
+  // validate that this is a not a legacy plugin
+  list<string> plugins_list;
+  get_str_list(plugins, plugins_list);
+  for (list<string>::iterator i = plugins_list.begin();
+       i != plugins_list.end();
+       ++i) {
+       string plugin_name = *i;
+       string replacement = "";
+
+       if (plugin_name == "jerasure_generic" || 
+           plugin_name == "jerasure_sse3" ||
+           plugin_name == "jerasure_sse4" ||
+           plugin_name == "jerasure_neon") {
+         replacement = "jerasure";
+       }
+       else if (plugin_name == "shec_generic" ||
+                plugin_name == "shec_sse3" ||
+                plugin_name == "shec_sse4" ||
+                plugin_name == "shec_neon") {
+         replacement = "shec";
+       }
+
+       if (replacement != "") {
+         dout(0) << "WARNING: osd_erasure_code_plugins contains plugin "
+                 << plugin_name << " that is now deprecated. Please modify the value "
+                 << "for osd_erasure_code_plugins to use "  << replacement << " instead." << dendl;
+       }
+  }
+
+  stringstream ss;
+  int r = ErasureCodePluginRegistry::instance().preload(
+    plugins,
+    conf->erasure_code_dir,
+    &ss);
+  if (r)
+    derr << ss.str() << dendl;
+  else
+    dout(10) << ss.str() << dendl;
+  return r;
+}
index ad3fd6286a356b644f7a020e51c40f3285b33ece..1fe877d9cf4c4376934ce1ac59ce8a52d88a600d 100644 (file)
@@ -88,6 +88,12 @@ void global_init_chdir(const CephContext *cct);
  */
 int global_init_shutdown_stderr(CephContext *cct);
 
+/*
+ * Preload the erasure coding libraries to detect early issues with
+ * configuration.
+ */
+int global_init_preload_erasure_code(const CephContext *cct);
+
 /**
  * print daemon startup banner/warning
  */
index 9196a283f9a5a32b3f24a6e5cd9e387becd01e0e..81cd181daed9f5f8fd2d1e6e90b075a834c528ec 100644 (file)
@@ -67,7 +67,7 @@
 #define dout_subsys ceph_subsys_mon
 #undef dout_prefix
 #define dout_prefix _prefix(_dout, mon, osdmap)
-static ostream& _prefix(std::ostream *_dout, Monitor *mon, OSDMap& osdmap) {
+static ostream& _prefix(std::ostream *_dout, Monitor *mon, const OSDMap& osdmap) {
   return *_dout << "mon." << mon->name << "@" << mon->rank
                << "(" << mon->get_state_name()
                << ").osd e" << osdmap.get_epoch() << " ";
@@ -4418,20 +4418,47 @@ int OSDMonitor::crush_rename_bucket(const string& srcname,
 
   pending_inc.crush.clear();
   newcrush.encode(pending_inc.crush);
-  *ss << "renamed bucket " << srcname << " into " << dstname;
+  *ss << "renamed bucket " << srcname << " into " << dstname;  
   return 0;
 }
 
-int OSDMonitor::normalize_profile(ErasureCodeProfile &profile, ostream *ss)
+void OSDMonitor::check_legacy_ec_plugin(const string& plugin, const string& profile) const
+{
+  string replacement = "";
+
+  if (plugin == "jerasure_generic" || 
+      plugin == "jerasure_sse3" ||
+      plugin == "jerasure_sse4" ||
+      plugin == "jerasure_neon") {
+    replacement = "jerasure";
+  } else if (plugin == "shec_generic" ||
+            plugin == "shec_sse3" ||
+            plugin == "shec_sse4" ||
+             plugin == "shec_neon") {
+    replacement = "shec";
+  }
+
+  if (replacement != "") {
+    dout(0) << "WARNING: erasure coding profile " << profile << " uses plugin "
+           << plugin << " that has been deprecated. Please use " 
+           << replacement << " instead." << dendl;
+  }
+}
+
+int OSDMonitor::normalize_profile(const string& profilename, 
+                                 ErasureCodeProfile &profile, 
+                                 ostream *ss)
 {
   ErasureCodeInterfaceRef erasure_code;
   ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance();
   ErasureCodeProfile::const_iterator plugin = profile.find("plugin");
+  check_legacy_ec_plugin(plugin->second, profilename);
   int err = instance.factory(plugin->second,
                             g_conf->erasure_code_dir,
                             profile, &erasure_code, ss);
   if (err)
     return err;
+
   return erasure_code->init(profile, ss);
 }
 
@@ -4488,6 +4515,7 @@ int OSDMonitor::get_erasure_code(const string &erasure_code_profile,
        << profile << std::endl;
     return -EINVAL;
   }
+  check_legacy_ec_plugin(plugin->second, erasure_code_profile);
   ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance();
   return instance.factory(plugin->second,
                          g_conf->erasure_code_dir,
@@ -6158,14 +6186,14 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
        if (err)
          goto reply;
       }
-      err = normalize_profile(profile_map, &ss);
+      err = normalize_profile(name, profile_map, &ss);
       if (err)
        goto reply;
 
       if (osdmap.has_erasure_code_profile(name)) {
        ErasureCodeProfile existing_profile_map =
          osdmap.get_erasure_code_profile(name);
-       err = normalize_profile(existing_profile_map, &ss);
+       err = normalize_profile(name, existing_profile_map, &ss);
        if (err)
          goto reply;
 
@@ -6219,7 +6247,7 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
                                                      &ss);
        if (err)
          goto reply;
-       err = normalize_profile(profile_map, &ss);
+       err = normalize_profile(name, profile_map, &ss);
        if (err)
          goto reply;
        dout(20) << "erasure code profile set " << profile << "="
index c1d60317553598abf3ddd3dde2fbfe30a4d6e1ad..8e55bf778d6f59d3676ebe88d8fe86e23d4ed910 100644 (file)
@@ -278,7 +278,11 @@ private:
   int crush_rename_bucket(const string& srcname,
                          const string& dstname,
                          ostream *ss);
-  int normalize_profile(ErasureCodeProfile &profile, ostream *ss);
+  void check_legacy_ec_plugin(const string& plugin, 
+                             const string& profile) const;
+  int normalize_profile(const string& profilename, 
+                       ErasureCodeProfile &profile,
+                       ostream *ss);
   int crush_ruleset_create_erasure(const string &name,
                                   const string &profile,
                                   int *ruleset,
index 4426d88710e82d15d8f9406ac9579f2efa055392..2d8b3e3bb08fd42b2b6373a1a104caafaeb56b8a 100644 (file)
@@ -1,3 +1,4 @@
+add_ceph_test(test-erasure-code-plugins.sh ${CMAKE_CURRENT_SOURCE_DIR}/test-erasure-code-plugins.sh)
 
 add_executable(ceph_erasure_code_benchmark 
   ${CMAKE_SOURCE_DIR}/src/erasure-code/ErasureCode.cc
diff --git a/src/test/erasure-code/test-erasure-code-plugins.sh b/src/test/erasure-code/test-erasure-code-plugins.sh
new file mode 100755 (executable)
index 0000000..3fa49c9
--- /dev/null
@@ -0,0 +1,109 @@
+#!/bin/bash -x
+
+source $(dirname $0)/../detect-build-env-vars.sh
+source $CEPH_ROOT/qa/workunits/ceph-helpers.sh
+
+arch=$(uname -p)
+
+case $arch in
+    i[[3456]]86*|x86_64*|amd64*)
+        legacy_jerasure_plugins=(jerasure_generic jerasure_sse3 jerasure_sse4)
+        legacy_shec_plugins=(shec_generic shec_sse3 shec_sse4)
+        ;;
+    aarch64*|arm*) 
+        legacy_jerasure_plugins=(jerasure_generic jerasure_neon)
+        legacy_shec_plugins=(shec_generic shec_neon)
+        ;;
+esac
+
+plugins=(jerasure shec lrc isa)
+
+function run() {
+    local dir=$1
+    shift
+
+    export CEPH_MON="127.0.0.1:17109"
+    export CEPH_ARGS
+    CEPH_ARGS+="--fsid=$(uuidgen) --auth-supported=none "
+    CEPH_ARGS+="--mon-host=$CEPH_MON "
+
+    local funcs=${@:-$(set | sed -n -e 's/^\(TEST_[0-9a-z_]*\) .*/\1/p')}
+    for func in $funcs ; do
+        $func $dir || return 1
+    done
+}
+
+function TEST_preload_warning() {
+    local dir=$1
+    
+    for plugin in ${legacy_jerasure_plugins[*]} ${legacy_shec_plugins[*]}; do
+        setup $dir || return 1
+        run_mon $dir a --osd_erasure_code_plugins="${plugin}" || return 1 
+        CEPH_ARGS='' ceph --admin-daemon $dir/ceph-mon.a.asok log flush || return 1
+        run_osd $dir 0 --osd_erasure_code_plugins="${plugin}" || return 1 
+        CEPH_ARGS='' ceph --admin-daemon $dir/ceph-osd.0.asok log flush || return 1
+        grep "WARNING: osd_erasure_code_plugins contains plugin ${plugin}" $dir/mon.a.log || return 1
+        grep "WARNING: osd_erasure_code_plugins contains plugin ${plugin}" $dir/osd.0.log || return 1
+        teardown $dir || return 1
+    done
+    return 0
+}
+
+function TEST_preload_no_warning() {
+    local dir=$1
+
+    for plugin in ${plugins[*]}; do
+        setup $dir || return 1
+        run_mon $dir a --osd_erasure_code_plugins="${plugin}" || return 1 
+        CEPH_ARGS='' ceph --admin-daemon $dir/ceph-mon.a.asok log flush || return 1
+        run_osd $dir 0 --osd_erasure_code_plugins="${plugin}" || return 1 
+        CEPH_ARGS='' ceph --admin-daemon $dir/ceph-osd.0.asok log flush || return 1
+        ! grep "WARNING: osd_erasure_code_plugins contains plugin" $dir/mon.a.log || return 1
+        ! grep "WARNING: osd_erasure_code_plugins contains plugin" $dir/osd.0.log || return 1
+        teardown $dir || return 1
+    done
+
+    return 0
+}
+
+function TEST_preload_no_warning_default() {
+    local dir=$1
+
+    setup $dir || return 1
+    run_mon $dir a || return 1 
+    CEPH_ARGS='' ceph --admin-daemon $dir/ceph-mon.a.asok log flush || return 1
+    run_osd $dir 0 || return 1 
+    CEPH_ARGS='' ceph --admin-daemon $dir/ceph-osd.0.asok log flush || return 1
+    ! grep "WARNING: osd_erasure_code_plugins" $dir/mon.a.log || return 1
+    ! grep "WARNING: osd_erasure_code_plugins" $dir/osd.0.log || return 1
+    teardown $dir || return 1
+
+    return 0
+}
+
+function TEST_ec_profile_warning() {
+    local dir=$1
+
+    setup $dir || return 1
+    run_mon $dir a || return 1 
+    for id in $(seq 0 2) ; do
+        run_osd $dir $id || return 1 
+    done
+    wait_for_clean || return 1
+
+    for plugin in ${legacy_jerasure_plugins[*]}; do
+        ceph osd erasure-code-profile set prof-${plugin} ruleset-failure-domain=osd technique=reed_sol_van plugin=${plugin} || return 1
+        CEPH_ARGS='' ceph --admin-daemon $dir/ceph-mon.a.asok log flush || return 1
+        grep "WARNING: erasure coding profile prof-${plugin} uses plugin ${plugin}" $dir/mon.a.log || return 1
+    done
+
+    for plugin in ${legacy_shec_plugins[*]}; do
+        ceph osd erasure-code-profile set prof-${plugin} ruleset-failure-domain=osd plugin=${plugin} || return 1
+        CEPH_ARGS='' ceph --admin-daemon $dir/ceph-mon.a.asok log flush || return 1
+        grep "WARNING: erasure coding profile prof-${plugin} uses plugin ${plugin}" $dir/mon.a.log || return 1
+    done
+
+    teardown $dir || return 1
+}
+
+main test-erasure-code-plugins "$@"