summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--README.md7
-rw-r--r--doc/Makefile.am4
-rw-r--r--include/erasurecode/erasurecode.h10
-rw-r--r--src/Makefile.am6
-rw-r--r--src/erasurecode.c59
-rw-r--r--test/libec_slap.c12
-rw-r--r--test/liberasurecode_test.c41
8 files changed, 102 insertions, 42 deletions
diff --git a/.gitignore b/.gitignore
index 27497ac..1700161 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,8 +51,13 @@ compile
cscope.files
install-sh
libtool
+ltmain.sh
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltversion.m4
# doxygen documentation
^doc/.*\.doxytag
^doc/html
+^doc/latex
*doxygen.cfg
diff --git a/README.md b/README.md
index 00f7c1c..548208c 100644
--- a/README.md
+++ b/README.md
@@ -178,17 +178,16 @@ int liberasurecode_encode_cleanup(int desc, char **encoded_data,
* @param fragments - erasure encoded fragments (> = k)
* @param num_fragments - number of fragments being passed in
* @param fragment_len - length of each fragment (assume they are the same)
+ * @param force_metadata_checks - force fragment metadata checks (default: 0)
* @param out_data - _output_ pointer to decoded data
* @param out_data_len - _output_ length of decoded output
- * (both output data pointers are allocated by liberasurecode,
- * caller invokes liberasurecode_decode_clean() after it has
- * read decoded data in 'out_data')
*
* @return 0 on success, -error code otherwise
*/
int liberasurecode_decode(int desc,
char **available_fragments, /* input */
int num_fragments, uint64_t fragment_len, /* input */
+ int force_metadata_checks, /* input */
char **out_data, uint64_t *out_data_len); /* output */
/**
@@ -420,4 +419,4 @@ Code organization
|-- INSTALL
+-- ChangeLog
```
---- \ No newline at end of file
+---
diff --git a/doc/Makefile.am b/doc/Makefile.am
index aea521f..31804cb 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -16,14 +16,14 @@ clean-local:
rm -rf html
install-data-local: html
- $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)
+ ../install-sh -d $(DESTDIR)$(TARGET_DIR)
(installfiles=`echo html/*`; \
if test "$$installfiles" = 'html/*'; \
then echo '-- Nothing to install' ; \
else \
for i in $$installfiles; do \
echo '-- Installing '$$i ; \
- $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \
+ ../install-sh $$i $(DESTDIR)$(TARGET_DIR); \
done; \
fi)
diff --git a/include/erasurecode/erasurecode.h b/include/erasurecode/erasurecode.h
index e8ad056..74f6385 100644
--- a/include/erasurecode/erasurecode.h
+++ b/include/erasurecode/erasurecode.h
@@ -169,6 +169,7 @@ int liberasurecode_encode_cleanup(int desc, char **encoded_data,
* @param fragments - erasure encoded fragments (> = k)
* @param num_fragments - number of fragments being passed in
* @param fragment_len - length of each fragment (assume they are the same)
+ * @param force_metadata_checks - force fragment metadata checks (default: 0)
* @param out_data - _output_ pointer to decoded data
* @param out_data_len - _output_ length of decoded output
* (both output data pointers are allocated by liberasurecode,
@@ -180,6 +181,7 @@ int liberasurecode_encode_cleanup(int desc, char **encoded_data,
int liberasurecode_decode(int desc,
char **available_fragments, /* input */
int num_fragments, uint64_t fragment_len, /* input */
+ int force_metadata_checks, /* input */
char **out_data, uint64_t *out_data_len); /* output */
/**
@@ -279,9 +281,9 @@ int liberasurecode_get_fragment_metadata(char *fragment,
* from liberasurecode_instance_create()
* @param fragment - fragment to verify
*
-* @return 0 if fragment validation is successful, 1 otherwise.
+* @return 1 if fragment validation fails, 0 otherwise.
*/
-int is_valid_fragment(int desc, char *fragment);
+int is_invalid_fragment(int desc, char *fragment);
/**
* Verify a subset of fragments generated by encode()
@@ -333,6 +335,10 @@ typedef enum {
EBACKENDINITERR = 202,
EBACKENDINUSE = 203,
EBACKENDNOTAVAIL = 204,
+ EBADCHKSUM = 205,
+ EINVALIDPARAMS = 206,
+ EBADHEADER = 207,
+ EINSUFFFRAGS = 208,
} LIBERASURECODE_ERROR_CODES;
/* =~=*=~==~=*=~==~=*=~==~=*=~===~=*=~==~=*=~===~=*=~==~=*=~===~=*=~==~=*=~= */
diff --git a/src/Makefile.am b/src/Makefile.am
index c6c2a21..ce6ef50 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,6 +20,12 @@ liberasurecode_la_SOURCES = \
backends/jerasure/jerasure_rs_cauchy.c \
backends/isa-l/isa_l_vand.c
+# Install additional header files
+liberasurecodeincludedir = $(includedir)
+liberasurecodeinclude_HEADERS = \
+ ../include/erasurecode/erasurecode.h \
+ ../include/erasurecode/erasurecode_helpers.h
+
liberasurecode_la_CPPFLAGS = -Werror @GCOV_FLAGS@
liberasurecode_la_LIBADD = \
builtin/xor_codes/libXorcode.la -lpthread -lm @GCOV_LDFLAGS@
diff --git a/src/erasurecode.c b/src/erasurecode.c
index 64381e7..8272f3e 100644
--- a/src/erasurecode.c
+++ b/src/erasurecode.c
@@ -495,6 +495,7 @@ int liberasurecode_decode_cleanup(int desc, char *data)
* @param fragments - erasure encoded fragments (> = k)
* @param num_fragments - number of fragments being passed in
* @param fragment_len - length of each fragment (assume they are the same)
+ * @param force_metadata_checks - force fragment metadata checks (default: 0)
* @param out_data - _output_ pointer to decoded data
* @param out_data_len - _output_ length of decoded output
* @return 0 on success, -error code otherwise
@@ -502,6 +503,7 @@ int liberasurecode_decode_cleanup(int desc, char *data)
int liberasurecode_decode(int desc,
char **available_fragments, /* input */
int num_fragments, uint64_t fragment_len, /* input */
+ int force_metadata_checks, /* input */
char **out_data, uint64_t *out_data_len) /* output */
{
int i, j;
@@ -546,6 +548,11 @@ int liberasurecode_decode(int desc,
k = instance->args.uargs.k;
m = instance->args.uargs.m;
+ if (num_fragments < k) {
+ ret = -EINSUFFFRAGS;
+ goto out;
+ }
+
/*
* Try to re-assebmle the original data before attempting a decode
*/
@@ -578,6 +585,21 @@ int liberasurecode_decode(int desc,
log_error("Could not allocate missing_idxs buffer!");
goto out;
}
+
+ /* If metadata checks requested, check fragment integrity upfront */
+ if (force_metadata_checks) {
+ int num_invalid_fragments = 0;
+ for (i = 0; i < num_fragments; ++i) {
+ if (is_invalid_fragment(desc, available_fragments[i])) {
+ ++num_invalid_fragments;
+ }
+ }
+ if (num_invalid_fragments > (k - 1)) {
+ ret = -EINSUFFFRAGS;
+ log_error("Not enough valid fragments available for decode!");
+ goto out;
+ }
+ }
/*
* Separate the fragments into data and parity. Also determine which
@@ -937,6 +959,8 @@ int liberasurecode_get_fragment_metadata(char *fragment,
computed_chksum = crc32(0, fragment_data, fragment_size);
if (stored_chksum != computed_chksum) {
fragment_metadata->chksum_mismatch = 1;
+ } else {
+ fragment_metadata->chksum_mismatch = 0;
}
break;
}
@@ -963,13 +987,13 @@ int liberasurecode_verify_fragment_metadata(ec_backend_t be,
return 0;
}
-int is_valid_fragment(int desc, char *fragment)
+int is_invalid_fragment(int desc, char *fragment)
{
uint32_t ver = 0;
fragment_metadata_t fragment_metadata;
ec_backend_t be = liberasurecode_backend_instance_get_by_desc(desc);
if (!be) {
- log_error("Unable to verify stripe metadata: invalid backend id %d.",
+ log_error("Unable to verify fragment metadata: invalid backend id %d.",
desc);
return 1;
}
@@ -992,23 +1016,46 @@ int is_valid_fragment(int desc, char *fragment)
return 0;
}
+int is_valid_fragment_metadata(int desc, fragment_metadata_t *fragment_metadata)
+{
+ ec_backend_t be = liberasurecode_backend_instance_get_by_desc(desc);
+ if (!be) {
+ log_error("Unable to verify stripe metadata: invalid backend id %d.",
+ desc);
+ return -EINVALIDPARAMS;
+ }
+ if (liberasurecode_verify_fragment_metadata(be,
+ fragment_metadata) != 0) {
+ return -EBADHEADER;
+ }
+ if (!be->common.ops->is_compatible_with(fragment_metadata->backend_version)) {
+ return -EBADHEADER;
+ }
+ if (fragment_metadata->chksum_mismatch == 1) {
+ return -EBADCHKSUM;
+ }
+ return 0;
+}
+
int liberasurecode_verify_stripe_metadata(int desc,
char **fragments, int num_fragments)
{
int i = 0;
if (!fragments) {
log_error("Unable to verify stripe metadata: fragments missing.");
- return 1;
+ return -EINVALIDPARAMS;
}
if (num_fragments <= 0) {
log_error("Unable to verify stripe metadata: "
"number of fragments must be greater than 0.");
- return 1;
+ return -EINVALIDPARAMS;
}
for (i = 0; i < num_fragments; i++) {
- if (is_valid_fragment(desc, fragments[i]) == 1) {
- return 1;
+ fragment_metadata_t *fragment_metadata = (fragment_metadata_t*)fragments[i];
+ int ret = is_valid_fragment_metadata(desc, fragment_metadata);
+ if (ret < 0) {
+ return ret;
}
}
diff --git a/test/libec_slap.c b/test/libec_slap.c
index fb9e69a..0f3c24b 100644
--- a/test/libec_slap.c
+++ b/test/libec_slap.c
@@ -283,8 +283,8 @@ static int test_hd_code(struct ec_args *args,
create_frags_array_set(&frags,encoded_data, args->k, encoded_parity,
args->m, mask);
rc = liberasurecode_decode(desc, frags.array, frags.num_fragments,
- encoded_fragment_len, &out_data,
- &out_data_len);
+ encoded_fragment_len, 1,
+ &out_data, &out_data_len);
assert(rc == 0);
assert(out_data_len == blocksize * args->k);
if (memcmp(data, out_data, out_data_len) != 0) {
@@ -308,15 +308,13 @@ static int test_hd_code(struct ec_args *args,
create_frags_array_set(&frags,encoded_data, args->k, encoded_parity,
args->m, mask);
rc = liberasurecode_decode(desc, frags.array, frags.num_fragments,
- encoded_fragment_len, &out_data,
- &out_data_len);
+ encoded_fragment_len, 1,
+ &out_data, &out_data_len);
free(frags.array);
free(out_data);
assert(rc == 0);
- fprintf(stderr," Decode Scenario - ");
- print_mask(mask);
- fprintf(stderr,": OK\n");
+ //print_mask(mask);
}
for (j = 0; j < args->k; j++) {
free(encoded_data[j]);
diff --git a/test/liberasurecode_test.c b/test/liberasurecode_test.c
index 61492d1..b3c17df 100644
--- a/test/liberasurecode_test.c
+++ b/test/liberasurecode_test.c
@@ -346,23 +346,23 @@ static void test_decode_invalid_args()
encoded_parity, &null_args, skips);
rc = liberasurecode_decode(-1, avail_frags, num_avail_frags,
- encoded_fragment_len, &decoded_data,
- &decoded_data_len);
+ encoded_fragment_len, 1,
+ &decoded_data, &decoded_data_len);
assert(rc < 0);
rc = liberasurecode_decode(desc, NULL, num_avail_frags,
- encoded_fragment_len, &decoded_data,
- &decoded_data_len);
+ encoded_fragment_len, 1,
+ &decoded_data, &decoded_data_len);
assert(rc < 0);
rc = liberasurecode_decode(desc, avail_frags, num_avail_frags,
- encoded_fragment_len, NULL,
- &decoded_data_len);
+ encoded_fragment_len, 1,
+ NULL, &decoded_data_len);
assert(rc < 0);
rc = liberasurecode_decode(desc, avail_frags, num_avail_frags,
- encoded_fragment_len, &decoded_data,
- NULL);
+ encoded_fragment_len, 1,
+ &decoded_data, NULL);
assert(rc < 0);
free(skips);
liberasurecode_encode_cleanup(desc, encoded_data, encoded_parity);
@@ -470,19 +470,19 @@ static void test_verify_stripe_metadata_invalid_args() {
char **frags = malloc(sizeof(char *) * num_frags);
rc = liberasurecode_verify_stripe_metadata(desc, frags, num_frags);
- assert(rc == 1);
+ assert(rc == -EINVALIDPARAMS);
desc = liberasurecode_instance_create(EC_BACKEND_NULL, &null_args);
assert(desc > 0);
rc = liberasurecode_verify_stripe_metadata(desc, NULL, num_frags);
- assert(rc == 1);
+ assert(rc == -EINVALIDPARAMS);
rc = liberasurecode_verify_stripe_metadata(desc, frags, -1);
- assert(rc == 1);
+ assert(rc == -EINVALIDPARAMS);
rc = liberasurecode_verify_stripe_metadata(desc, frags, 0);
- assert(rc == 1);
+ assert(rc == -EINVALIDPARAMS);
}
@@ -540,8 +540,8 @@ static void encode_decode_test_impl(const ec_backend_id_t be_id,
assert(num_avail_frags != -1);
rc = liberasurecode_decode(desc, avail_frags, num_avail_frags,
- encoded_fragment_len, &decoded_data,
- &decoded_data_len);
+ encoded_fragment_len, 1,
+ &decoded_data, &decoded_data_len);
assert(0 == rc);
assert(decoded_data_len == orig_data_size);
assert(memcmp(decoded_data, orig_data, orig_data_size) == 0);
@@ -952,7 +952,7 @@ static void test_verify_stripe_metadata(const ec_backend_id_t be_id,
free(skip);
}
-static void verify_stripe_metadata_mismatch_impl(const ec_backend_id_t be_id, struct ec_args *args,
+static void verify_fragment_metadata_mismatch_impl(const ec_backend_id_t be_id, struct ec_args *args,
fragment_mismatch_scenario_t scenario)
{
int orig_data_size = 1024;
@@ -1002,8 +1002,7 @@ static void verify_stripe_metadata_mismatch_impl(const ec_backend_id_t be_id, st
default:
assert(false);
}
- rc = liberasurecode_verify_stripe_metadata(desc, avail_frags,
- num_avail_frags);
+ rc = is_invalid_fragment(desc, avail_frags[i]);
assert(rc == 1);
//heal fragment
switch (scenario) {
@@ -1030,25 +1029,25 @@ static void verify_stripe_metadata_mismatch_impl(const ec_backend_id_t be_id, st
static void test_verify_stripe_metadata_libec_mismatch(
const ec_backend_id_t be_id, struct ec_args *args)
{
- verify_stripe_metadata_mismatch_impl(be_id, args, LIBEC_VERSION_MISMATCH);
+ verify_fragment_metadata_mismatch_impl(be_id, args, LIBEC_VERSION_MISMATCH);
}
static void test_verify_stripe_metadata_magic_mismatch(
const ec_backend_id_t be_id, struct ec_args *args)
{
- verify_stripe_metadata_mismatch_impl(be_id, args, MAGIC_MISMATCH);
+ verify_fragment_metadata_mismatch_impl(be_id, args, MAGIC_MISMATCH);
}
static void test_verify_stripe_metadata_be_id_mismatch(
const ec_backend_id_t be_id, struct ec_args *args)
{
- verify_stripe_metadata_mismatch_impl(be_id, args, BACKEND_ID_MISMATCH);
+ verify_fragment_metadata_mismatch_impl(be_id, args, BACKEND_ID_MISMATCH);
}
static void test_verify_stripe_metadata_be_ver_mismatch(
const ec_backend_id_t be_id, struct ec_args *args)
{
- verify_stripe_metadata_mismatch_impl(be_id, args, BACKEND_VERSION_MISMATCH);
+ verify_fragment_metadata_mismatch_impl(be_id, args, BACKEND_VERSION_MISMATCH);
}