diff options
author | Kota Tsuyuzaki <tsuyuzaki.kota@lab.ntt.co.jp> | 2016-11-03 19:49:49 -0700 |
---|---|---|
committer | Clay Gerrard <clay.gerrard@gmail.com> | 2016-11-09 23:28:55 +0000 |
commit | 74eaa374c107d1a9e140fc7a8c1bf91386619940 (patch) | |
tree | 14aa116eb85e3cb1fa3db7e77fd1974385432b5e /test | |
parent | b96cf4b2cc98dbdcdf60c80cd4a353f5c11959c8 (diff) | |
download | liberasurecode-74eaa374c107d1a9e140fc7a8c1bf91386619940.tar.gz |
Fix error handling on gf_ivnert_matrix in isa-l backend
Current isa-l has possibility to return corrupted decoded data or
corrupted reconstructed data on decode/reconstruct without error code.
That is from the specification of isa-l rs vandermond matrix discussed
at [1]. With many # of parities cases, we may hit the case above due to
failing to get the inverse matrix from the encode matrix.
The isa-l maintener gbtucker suggests a good way to detect the failing
inverse matrix, that we should handle the return value gf_invert_matrix.
If gf_invert_matrix returns not 0, we should stop to decode/reconstruct
and return failure return code to the caller immediately. Otherwise, the
caller regards the garbage data/fragment as correct one.
And this patch adds the specific test case we can hit the issue (it
happens not so general).
1: https://github.com/01org/isa-l/issues/10
Related-Change: I6eb150d9d0c3febf233570fa7729f9f72df2e9be
Change-Id: Icee788a0931fe692fe0de31fabc4ba450e338a87
Diffstat (limited to 'test')
-rw-r--r-- | test/liberasurecode_test.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/test/liberasurecode_test.c b/test/liberasurecode_test.c index c94c466..386d49f 100644 --- a/test/liberasurecode_test.c +++ b/test/liberasurecode_test.c @@ -1346,6 +1346,102 @@ static void test_decode_with_missing_multi_data_parity( } } +static void test_decode_reconstruct_specific_error_case( + const ec_backend_id_t be_id, struct ec_args *args) +{ + struct ec_args specific_1010_args = { + .k = 10, + .m = 10, + }; + + int rc = 0; + int desc = -1; + int orig_data_size = 1024 * 1024; + char *orig_data = create_buffer(orig_data_size, 'x'); + char **encoded_data = NULL, **encoded_parity = NULL; + uint64_t encoded_fragment_len = 0; + int num_avail_frags = -1; + char **avail_frags = NULL; + char *decoded_data = NULL; + char *out_frag = NULL; + uint64_t decoded_data_len = 0; + + int *skips = create_skips_array(&specific_1010_args,-1); + assert(skips != NULL); + // available frags for a bad pattern: [0, 1, 2, 3, 4, 6, 7, 10, 12, 15] + skips[5] = skips[8] = skips[9] = skips[11] = skips[13] = skips[14] = + skips[16] = skips[17] = skips[18] = skips[19] = 1; + + desc = liberasurecode_instance_create( + EC_BACKEND_ISA_L_RS_VAND, &specific_1010_args); + if (-EBACKENDNOTAVAIL == desc) { + fprintf (stderr, "Backend library not available!\n"); + return; + } + assert(desc > 0); + + rc = liberasurecode_encode(desc, orig_data, orig_data_size, + &encoded_data, &encoded_parity, &encoded_fragment_len); + assert(rc == 0); + + num_avail_frags = create_frags_array(&avail_frags, encoded_data, + encoded_parity, &specific_1010_args, + skips); + assert(num_avail_frags > 0); + + rc = liberasurecode_decode(desc, avail_frags, num_avail_frags, + encoded_fragment_len, 1, + &decoded_data, &decoded_data_len); + assert(rc == -1); + free(avail_frags); + + // 5 is a hole in available frags + num_avail_frags = create_frags_array(&avail_frags, encoded_data, + encoded_parity, &specific_1010_args, + skips); + out_frag = malloc(sizeof(char) * encoded_fragment_len); + rc = liberasurecode_reconstruct_fragment( + desc, avail_frags, 10, encoded_fragment_len, 5, out_frag); + assert(rc == -1); + + free(out_frag); + free(avail_frags); + + // sanity; [0, 1, 2, 3, 4, 6, 7, 10, 12, 14] is ok + skips[15] = 1; skips[14] = 0; + num_avail_frags = create_frags_array(&avail_frags, encoded_data, + encoded_parity, &specific_1010_args, + skips); + assert(num_avail_frags > 0); + rc = liberasurecode_decode(desc, avail_frags, num_avail_frags, + encoded_fragment_len, 1, + &decoded_data, &decoded_data_len); + assert(rc == 0); + // 5 is a hole in available frags + out_frag = malloc(sizeof(char) * encoded_fragment_len); + rc = liberasurecode_reconstruct_fragment( + desc, avail_frags, 10, encoded_fragment_len, 5, out_frag); + + assert(rc == 0); + + free(out_frag); + + // cleanup all + rc = liberasurecode_encode_cleanup(desc, encoded_data, encoded_parity); + assert(rc == 0); + + rc = liberasurecode_decode_cleanup(desc, decoded_data); + assert(rc == 0); + + if (desc) { + assert(0 == liberasurecode_instance_destroy(desc)); + } + + free(orig_data); + free(avail_frags); + free(skips); +} + static void test_simple_encode_decode(const ec_backend_id_t be_id, struct ec_args *args) { @@ -1875,6 +1971,10 @@ struct testcase testcases[] = { test_verify_stripe_metadata_frag_idx_invalid, EC_BACKEND_ISA_L_RS_VAND, CHKSUM_CRC32, .skip = false}, + {"test_isa_l_decode_reconstruct_specific_error_case", + test_decode_reconstruct_specific_error_case, + EC_BACKENDS_MAX, 0, // note this test is using ISA-L in hard coded + .skip = false}, // shss tests {"create_and_destroy_backend", test_create_and_destroy_backend, |