Load the jerasure plugin when ceph-osd starts to avoid the following
scenario:
* ceph-osd-v1 is running but did not load jerasure
* ceph-osd-v2 is installed being installed but takes time : the files
are installed before ceph-osd is restarted
* ceph-osd-v1 is required to handle an erasure coded placement group and
loads jerasure (the v2 version which is not API compatible)
* ceph-osd-v1 calls the v2 jerasure plugin and does not reference the
expected part of the code and crashes
Although this problem shows in the context of teuthology, it is unlikely
to happen on a real cluster because it involves upgrading immediately
after installing and running an OSD. Once it is backported to firefly,
it will not even happen in teuthology tests because the upgrade from
firefly to master will use the firefly version including this fix.
While it would be possible to walk the plugin directory and preload
whatever it contains, that would not work for plugins such as jerasure
that load other plugins depending on the CPU features, or even plugins
such as isa which only work on specific CPU.
http://tracker.ceph.com/issues/9153 Fixes: #9153
Backport: firefly
Signed-off-by: Loic Dachary <loic-201408@dachary.org>
(cherry picked from commit
9b802701f78288ba4f706c65b853415c69002d27)
Conflicts:
src/test/erasure-code/test-erasure-code.sh
src/common/config_opts.h
#include "include/assert.h"
+#include "erasure-code/ErasureCodePlugin.h"
+
#define dout_subsys ceph_subsys_osd
OSD *osd = NULL;
generic_server_usage();
}
+int preload_erasure_code()
+{
+ string directory = g_conf->osd_pool_default_erasure_code_directory;
+ string plugins = g_conf->osd_erasure_code_plugins;
+ stringstream ss;
+ int r = ErasureCodePluginRegistry::instance().preload(plugins,
+ directory,
+ 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;
return -1;
global_init_chdir(g_ceph_context);
+ if (preload_erasure_code() < -1)
+ return -1;
+
osd = new OSD(g_ceph_context,
store,
whoami,
"k=2 "
"m=1 "
) // default properties of osd pool create
+OPTION(osd_erasure_code_plugins, OPT_STR, "jerasure") // list of erasure code plugins
OPTION(osd_pool_default_flags, OPT_INT, 0) // default flags for new pools
OPTION(osd_pool_default_flag_hashpspool, OPT_BOOL, true) // use new pg hashing to prevent pool/pg overlap
OPTION(osd_pool_default_hit_set_bloom_fpp, OPT_FLOAT, .05)
* Ceph - scalable distributed file system
*
* Copyright (C) 2013,2014 Cloudwatt <libre.licensing@cloudwatt.com>
+ * Copyright (C) 2014 Red Hat <contact@redhat.com>
*
* Author: Loic Dachary <loic@dachary.org>
*
#include "ErasureCodePlugin.h"
#include "common/errno.h"
+#include "include/str_list.h"
#define PLUGIN_PREFIX "libec_"
#define PLUGIN_SUFFIX ".so"
(*plugin)->library = library;
+ ss << __func__ << ": " << plugin_name << " ";
+
return 0;
}
+int ErasureCodePluginRegistry::preload(const std::string &plugins,
+ const std::string &directory,
+ ostream &ss)
+{
+ map<string,string> profile;
+ profile["directory"] = directory;
+ list<string> plugins_list;
+ get_str_list(plugins, plugins_list);
+ for (list<string>::iterator i = plugins_list.begin();
+ i != plugins_list.end();
+ i++) {
+ ErasureCodePlugin *plugin;
+ int r = load(*i, profile, &plugin, ss);
+ if (r)
+ return r;
+ }
+ return 0;
+}
ErasureCodePlugin **plugin,
ostream &ss);
+ int preload(const std::string &plugins,
+ const std::string &directory,
+ ostream &ss);
};
}
CEPH_ARGS+=" --mon-host=$MONA"
CEPH_ARGS+=" --log-file=$DIR/\$name.log"
CEPH_ARGS+=" --pid-file=$DIR/\$name.pidfile"
+CEPH_ARGS+=" --osd-pool-default-erasure-code-directory=.libs"
CEPH_ARGS+=" --auth-supported=none"
CEPH_DISK_ARGS=
CEPH_DISK_ARGS+=" --statedir=$DIR"
for id in $(seq 0 4) ; do
run_osd $dir $id || return 1
done
+ # check that erasure code plugins are preloaded
+ CEPH_ARGS='' ./ceph --admin-daemon $dir/ceph-osd.0.asok log flush || return 1
+ grep 'load: jerasure' $dir/osd-0.log || return 1
create_erasure_coded_pool || return 1
FUNCTIONS=${FUNCTIONS:-$(set | sed -n -e 's/^\(TEST_[0-9a-z_]*\) .*/\1/p')}
for TEST_function in $FUNCTIONS ; do
ceph_args+=" --osd-journal-size=100"
ceph_args+=" --osd-data=$osd_data"
ceph_args+=" --chdir="
+ ceph_args+=" --osd-pool-default-erasure-code-directory=.libs"
ceph_args+=" --run-dir=$dir"
ceph_args+=" --debug-osd=20"
ceph_args+=" --log-file=$dir/osd-\$id.log"