Fix brute-force error locator for EC n+k with k > 2
Test / buildenv (push) Successful in 12s Details
Test / build (push) Successful in 2m39s Details
Test / make_test (push) Successful in 34s Details
Test / test_add_osd (push) Successful in 2m44s Details
Test / test_cas (push) Successful in 10s Details
Test / test_change_pg_count (push) Successful in 1m0s Details
Test / test_change_pg_count_ec (push) Successful in 2m23s Details
Test / test_change_pg_size (push) Successful in 20s Details
Test / test_create_nomaxid (push) Successful in 16s Details
Test / test_etcd_fail (push) Successful in 55s Details
Test / test_failure_domain (push) Successful in 12s Details
Test / test_interrupted_rebalance (push) Successful in 1m18s Details
Test / test_interrupted_rebalance_imm (push) Successful in 1m9s Details
Test / test_interrupted_rebalance_ec (push) Successful in 1m23s Details
Test / test_interrupted_rebalance_ec_imm (push) Successful in 1m8s Details
Test / test_minsize_1 (push) Successful in 22s Details
Test / test_move_reappear (push) Successful in 28s Details
Test / test_rebalance_verify (push) Successful in 2m17s Details
Test / test_rebalance_verify_imm (push) Successful in 2m19s Details
Test / test_rebalance_verify_ec (push) Successful in 3m4s Details
Test / test_rebalance_verify_ec_imm (push) Successful in 2m22s Details
Test / test_rm (push) Successful in 23s Details
Test / test_snapshot (push) Successful in 20s Details
Test / test_snapshot_ec (push) Successful in 34s Details
Test / test_splitbrain (push) Successful in 33s Details
Test / test_write (push) Successful in 1m15s Details
Test / test_write_xor (push) Successful in 2m6s Details
Test / test_write_no_same (push) Successful in 16s Details
Test / test_heal_pg_size_2 (push) Successful in 5m22s Details
Test / test_heal_ec (push) Successful in 5m31s Details
Test / test_scrub (push) Successful in 29s Details
Test / test_scrub_zero_osd_2 (push) Successful in 27s Details
Test / test_scrub_xor (push) Successful in 22s Details
Test / test_scrub_pg_size_3 (push) Failing after 37s Details
Test / test_scrub_pg_size_6_pg_minsize_4_osd_count_6_ec (push) Successful in 29s Details
Test / test_scrub_ec (push) Failing after 33s Details

test-double-alloc
Vitaliy Filippov 2023-05-21 00:57:14 +03:00
parent 88c1ba0790
commit f1961157f0
2 changed files with 54 additions and 38 deletions

View File

@ -1201,21 +1201,10 @@ std::vector<int> ec_find_good(osd_rmw_stripe_t *stripes, int pg_size, int pg_min
{
brute_stripes[i].read_buf = brute_stripes[i].write_buf;
}
int max_live = 0;
for (int i = 0; i < pg_size; i++)
{
if (!brute_stripes[i].missing)
{
max_live = i;
}
}
int valid_count = 0;
for (int i = 0; i < out_count; i++)
{
// Only compare with chunks after the last one so first N + each 1 after them don't repeat
// I.e. compare (1,2,3,4) with (5,6) and (1,2,3,5) only with (6) and so on
if (cur_live[outset[i]] > max_live &&
memcmp(brute_stripes[cur_live[outset[i]]].read_buf,
if (memcmp(brute_stripes[cur_live[outset[i]]].read_buf,
stripes[cur_live[outset[i]]].read_buf, chunk_size) == 0)
{
brute_stripes[cur_live[outset[i]]].missing = false;
@ -1226,15 +1215,34 @@ std::vector<int> ec_find_good(osd_rmw_stripe_t *stripes, int pg_size, int pg_min
{
if (found_valid.size())
{
// Ambiguity: we found multiple valid sets and don't know which one is correct
found_valid.clear();
break;
}
for (int i = 0; i < pg_size; i++)
{
if (!brute_stripes[i].missing)
// Check if we found the same set from the different point of view,
// like 1 2 3 -> valid 4 5 and 1 3 4 -> valid 2 5
for (int i = 0, j = 0; i < pg_size; i++)
{
found_valid.push_back(i);
if (!brute_stripes[i].missing)
{
if (j >= found_valid.size() || found_valid[j] != i)
{
// Ambiguity: we found multiple valid sets and don't know which one is correct
found_valid.clear();
break;
}
j++;
}
}
if (!found_valid.size())
{
break;
}
}
else
{
for (int i = 0; i < pg_size; i++)
{
if (!brute_stripes[i].missing)
{
found_valid.push_back(i);
}
}
}
if (valid_count == out_count)

View File

@ -28,7 +28,7 @@ void test14();
void test15(bool second);
void test16();
void test_recover_22_d2();
void test_ec42_error_bruteforce();
void test_ec43_error_bruteforce();
int main(int narg, char *args[])
{
@ -66,7 +66,7 @@ int main(int narg, char *args[])
// Test 17
test_recover_22_d2();
// Error bruteforce
test_ec42_error_bruteforce();
test_ec43_error_bruteforce();
// End
printf("all ok\n");
return 0;
@ -1116,7 +1116,7 @@ EC 4+2 error location bruteforce
***/
static void assert_eq_vec(const std::vector<int> & a, const std::vector<int> & b)
static void assert_eq_vec(const std::vector<int> & b, const std::vector<int> & a)
{
printf("Expect [");
for (int i = 0; i < a.size(); i++)
@ -1128,25 +1128,27 @@ static void assert_eq_vec(const std::vector<int> & a, const std::vector<int> & b
assert(a == b);
}
void test_ec42_error_bruteforce()
void test_ec43_error_bruteforce()
{
use_ec(6, 4, true);
osd_num_t osd_set[6] = { 1, 2, 3, 4, 5, 6 };
osd_rmw_stripe_t stripes[6] = {};
use_ec(7, 4, true);
osd_num_t osd_set[7] = { 1, 2, 3, 4, 5, 6, 7 };
osd_rmw_stripe_t stripes[7] = {};
split_stripes(4, 4096, 0, 4096 * 4, stripes);
uint8_t *write_buf = (uint8_t*)malloc_or_die(4096 * 6);
uint8_t *write_buf = (uint8_t*)malloc_or_die(4096 * 7);
set_pattern(write_buf+0*4096, 4096, PATTERN0);
set_pattern(write_buf+1*4096, 4096, PATTERN1);
set_pattern(write_buf+2*4096, 4096, PATTERN2);
set_pattern(write_buf+3*4096, 4096, PATTERN3);
uint8_t *rmw_buf = (uint8_t*)calc_rmw(write_buf, stripes, osd_set, 6, 4, 6, osd_set, 4096, 0);
calc_rmw_parity_ec(stripes, 6, 4, osd_set, osd_set, 4096, 0);
uint8_t *rmw_buf = (uint8_t*)calc_rmw(write_buf, stripes, osd_set, 7, 4, 7, osd_set, 4096, 0);
calc_rmw_parity_ec(stripes, 7, 4, osd_set, osd_set, 4096, 0);
check_pattern(stripes[4].write_buf, 4096, PATTERN0^PATTERN1^PATTERN2^PATTERN3);
check_pattern(stripes[5].write_buf, 4096, 0x139274739ae6f387); // 2nd EC chunk
check_pattern(stripes[5].write_buf, 4096, 0xfcee568ba36371ac); // 2nd EC chunk
check_pattern(stripes[6].write_buf, 4096, 0x139274739ae6f387); // 3rd EC chunk
memcpy(write_buf+4*4096, stripes[4].write_buf, 4096);
memcpy(write_buf+5*4096, stripes[5].write_buf, 4096);
memcpy(write_buf+6*4096, stripes[6].write_buf, 4096);
// Try to locate errors
for (int i = 0; i < 6; i++)
for (int i = 0; i < 7; i++)
{
stripes[i].read_start = 0;
stripes[i].read_end = 4096;
@ -1154,19 +1156,25 @@ void test_ec42_error_bruteforce()
stripes[i].write_buf = NULL;
}
// All good chunks
auto res = ec_find_good(stripes, 6, 4, false, 4096, 0, 100);
assert_eq_vec(res, std::vector<int>({0, 1, 2, 3, 4, 5}));
auto res = ec_find_good(stripes, 7, 4, false, 4096, 0, 100);
assert_eq_vec(res, std::vector<int>({0, 1, 2, 3, 4, 5, 6}));
// 1 missing chunk
set_pattern(write_buf+1*4096, 4096, 0);
res = ec_find_good(stripes, 6, 4, false, 4096, 0, 100);
assert_eq_vec(res, std::vector<int>({0, 2, 3, 4, 5}));
res = ec_find_good(stripes, 7, 4, false, 4096, 0, 100);
assert_eq_vec(res, std::vector<int>({0, 2, 3, 4, 5, 6}));
// 2 missing chunks
set_pattern(write_buf+1*4096, 4096, 0);
set_pattern(write_buf+5*4096, 4096, 0);
res = ec_find_good(stripes, 6, 4, false, 4096, 0, 100);
res = ec_find_good(stripes, 7, 4, false, 4096, 0, 100);
assert_eq_vec(res, std::vector<int>({0, 2, 3, 4, 6}));
// 3 missing chunks
set_pattern(write_buf+1*4096, 4096, 0);
set_pattern(write_buf+5*4096, 4096, 0);
set_pattern(write_buf+6*4096, 4096, 0);
res = ec_find_good(stripes, 7, 4, false, 4096, 0, 100);
assert_eq_vec(res, std::vector<int>());
// Done
free(rmw_buf);
free(write_buf);
use_ec(6, 4, false);
use_ec(7, 4, false);
}