Merge pull request #4712 from dachary/wip-11663-verify-erasure-code-profile

normalize and verify the erasure code profile

Reviewed-by: Andreas Peters <andreas.joachim.peters@cern.ch>
This commit is contained in:
Loic Dachary 2015-06-03 10:47:50 +02:00
commit 3ca1b50975
13 changed files with 95 additions and 25 deletions

View File

@ -33,9 +33,19 @@ namespace ceph {
static const unsigned SIMD_ALIGN;
vector<int> chunk_mapping;
ErasureCodeProfile _profile;
virtual ~ErasureCode() {}
virtual int init(ErasureCodeProfile &profile, ostream *ss) {
_profile = profile;
return 0;
}
virtual const ErasureCodeProfile &get_profile() const {
return _profile;
}
virtual unsigned int get_coding_chunk_count() const {
return get_chunk_count() - get_data_chunk_count();
}

View File

@ -153,6 +153,20 @@ using namespace std;
namespace ceph {
typedef map<std::string,std::string> ErasureCodeProfile;
inline ostream& operator<<(ostream& out, const ErasureCodeProfile& profile) {
out << "{";
for (ErasureCodeProfile::const_iterator it = profile.begin();
it != profile.end();
++it) {
if (it != profile.begin()) out << ",";
out << it->first << "=" << it->second;
}
out << "}";
return out;
}
class ErasureCodeInterface {
public:
virtual ~ErasureCodeInterface() {}
@ -173,6 +187,14 @@ namespace ceph {
*/
virtual int init(ErasureCodeProfile &profile, ostream *ss) = 0;
/**
* Return the profile that was used to initialize the instance
* with the **init** method.
*
* @return the profile in use by the instance
*/
virtual const ErasureCodeProfile &get_profile() const = 0;
/**
* Create a new ruleset in **crush** under the name **name**,
* unless it already exists.

View File

@ -102,7 +102,15 @@ int ErasureCodePluginRegistry::factory(const std::string &plugin_name,
}
}
return plugin->factory(profile, erasure_code, ss);
int r = plugin->factory(profile, erasure_code, ss);
if (r)
return r;
if (profile != (*erasure_code)->get_profile()) {
*ss << __func__ << " profile " << profile << " != get_profile() "
<< (*erasure_code)->get_profile() << std::endl;
return -EINVAL;
}
return 0;
}
static const char *an_older_version() {

View File

@ -80,6 +80,7 @@ ErasureCodeIsa::init(ErasureCodeProfile &profile, ostream *ss)
if (err)
return err;
prepare();
ErasureCode::init(profile, ss);
return err;
}

View File

@ -67,6 +67,7 @@ int ErasureCodeJerasure::init(ErasureCodeProfile& profile, ostream *ss)
if (err)
return err;
prepare();
ErasureCode::init(profile, ss);
return err;
}

View File

@ -534,6 +534,7 @@ int ErasureCodeLrc::init(ErasureCodeProfile &profile,
profile.erase("mapping");
profile.erase("layers");
}
ErasureCode::init(profile, ss);
return 0;
}

View File

@ -68,6 +68,7 @@ int ErasureCodeShec::init(ErasureCodeProfile &profile,
if (err)
return err;
prepare();
ErasureCode::init(profile, ss);
return err;
}

View File

@ -3940,6 +3940,17 @@ int OSDMonitor::crush_rename_bucket(const string& srcname,
return 0;
}
int OSDMonitor::normalize_profile(ErasureCodeProfile &profile, ostream *ss)
{
ErasureCodeInterfaceRef erasure_code;
ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance();
ErasureCodeProfile::const_iterator plugin = profile.find("plugin");
int err = instance.factory(plugin->second, profile, &erasure_code, ss);
if (err)
return err;
return erasure_code->init(profile, ss);
}
int OSDMonitor::crush_ruleset_create_erasure(const string &name,
const string &profile,
int *ruleset,
@ -5452,22 +5463,6 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m,
}
string plugin = profile_map["plugin"];
if (osdmap.has_erasure_code_profile(name)) {
if (osdmap.get_erasure_code_profile(name) == profile_map) {
err = 0;
goto reply;
}
if (!force) {
err = -EPERM;
ss << "will not override erasure code profile " << name
<< " because the existing profile "
<< osdmap.get_erasure_code_profile(name)
<< " is different from the proposed profile "
<< profile_map;
goto reply;
}
}
if (pending_inc.has_erasure_code_profile(name)) {
dout(20) << "erasure code profile " << name << " try again" << dendl;
goto wait;
@ -5484,7 +5479,34 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m,
goto reply;
}
}
dout(20) << "erasure code profile " << name << " set" << dendl;
err = normalize_profile(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);
if (err)
goto reply;
if (existing_profile_map == profile_map) {
err = 0;
goto reply;
}
if (!force) {
err = -EPERM;
ss << "will not override erasure code profile " << name
<< " because the existing profile "
<< existing_profile_map
<< " is different from the proposed profile "
<< profile_map;
goto reply;
}
}
dout(20) << "erasure code profile set " << name << "="
<< profile_map << dendl;
pending_inc.set_erasure_code_profile(name, profile_map);
}
@ -5518,7 +5540,11 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m,
&ss);
if (err)
goto reply;
dout(20) << "erasure code profile " << profile << " set" << dendl;
err = normalize_profile(profile_map, &ss);
if (err)
goto reply;
dout(20) << "erasure code profile set " << profile << "="
<< profile_map << dendl;
pending_inc.set_erasure_code_profile(profile, profile_map);
goto wait;
}

View File

@ -277,6 +277,7 @@ private:
int crush_rename_bucket(const string& srcname,
const string& dstname,
ostream *ss);
int normalize_profile(ErasureCodeProfile &profile, ostream *ss);
int crush_ruleset_create_erasure(const string &name,
const string &profile,
int *ruleset,

View File

@ -39,10 +39,6 @@ class ErasureCodeExample : public ErasureCode {
public:
virtual ~ErasureCodeExample() {}
virtual int init(ErasureCodeProfile &profile, ostream *ss) {
return 0;
}
virtual int create_ruleset(const string &name,
CrushWrapper &crush,
ostream *ss) const {

View File

@ -28,6 +28,7 @@ public:
ostream *ss)
{
*erasure_code = ErasureCodeInterfaceRef(new ErasureCodeExample());
(*erasure_code)->init(profile, ss);
return 0;
}
};

View File

@ -35,7 +35,9 @@ ceph_erasure_code_LDADD += -ldl
endif
bin_DEBUGPROGRAMS += ceph_erasure_code
libec_example_la_SOURCES = test/erasure-code/ErasureCodePluginExample.cc
libec_example_la_SOURCES = \
erasure-code/ErasureCode.cc \
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}

View File

@ -113,7 +113,7 @@ function TEST_crush_rule_create_erasure() {
! ./ceph osd erasure-code-profile ls | grep default || return 1
./ceph osd crush rule create-erasure $ruleset || return 1
CEPH_ARGS='' ./ceph --admin-daemon $dir/ceph-mon.a.asok log flush || return 1
grep 'profile default set' $dir/mon.a.log || return 1
grep 'profile set default' $dir/mon.a.log || return 1
./ceph osd erasure-code-profile ls | grep default || return 1
./ceph osd crush rule rm $ruleset || return 1
! ./ceph osd crush rule ls | grep $ruleset || return 1