Add raid selftest for raid_rec_dataonly()

This commit is contained in:
Andrea Mazzoleni 2015-03-10 22:09:48 +01:00
parent 348ca97493
commit 1d9b0abc3f
2 changed files with 89 additions and 12 deletions

View file

@ -180,23 +180,70 @@ static int raid_test_rec(int nr, int *ir, int nd, int np, size_t size, void **v,
int i, j;
void *t[TEST_COUNT + RAID_PARITY_MAX];
/* setup vector */
/* setup data and parity vector */
for (i = 0, j = 0; i < nd + np; ++i) {
if (j < nr && ir[j] == i) {
/* this block has to be recovered */
t[i] = v[i];
++j;
} else {
/* this block is used for recovering */
t[i] = ref[i];
}
}
raid_rec(nr, ir, nd, np, size, t);
/* compare all data and parity */
for (i = 0; i < nd + np; ++i) {
if (t[i] != ref[i]
&& memcmp(t[i], ref[i], size) != 0) {
return -1;
}
}
return 0;
}
/*
* Recovering test for dataonly.
*/
static int raid_test_rec_dataonly(int nr, int *id, int *ip, int nd, int np, size_t size, void **v, void **ref)
{
int i, j;
void *t[TEST_COUNT + RAID_PARITY_MAX];
/* setup data vector */
for (i = 0, j = 0; i < nd; ++i) {
if (j < nr && id[j] == i) {
/* this block has to be recovered */
t[i] = v[i];
++j;
} else {
/* this block is left unchanged */
t[i] = ref[i];
}
}
raid_rec(nr, ir, nd, np, size, t);
/* setup parity vector */
for (i = 0, j = 0; i < np; ++i) {
if (j < nr && ip[j] == i) {
/* this block is used for recovering */
t[nd + i] = ref[nd + i];
++j;
} else {
/* this block should not be read or written */
t[nd + i] = 0;
}
}
raid_rec_dataonly(nr, id, ip, nd, size, t);
/* compare all data and parity */
for (i = 0; i < nd + np; ++i) {
if (t[i] != ref[i] && memcmp(t[i], ref[i], size) != 0) {
for (i = 0; i < nd; ++i) {
if (t[i] != ref[i]
&& t[i] != 0
&& memcmp(t[i], ref[i], size) != 0) {
return -1;
}
}
@ -216,6 +263,7 @@ int raid_selftest(void)
void **v;
void *ref[nd + RAID_PARITY_MAX];
int ir[RAID_PARITY_MAX];
int ip[RAID_PARITY_MAX];
int i, np;
int ret = 0;
@ -247,18 +295,33 @@ int raid_selftest(void)
if (ret != 0)
goto bail;
/* test recovering with full broken data disks */
for (i = 0; i < np; ++i)
/* test recovering with broken ending data disks */
for (i = 0; i < np; ++i) {
/* bad data */
ir[i] = nd - np + i;
/* good parity */
ip[i] = i;
}
ret = raid_test_rec(np, ir, nd, np, size, v, ref);
if (ret != 0)
goto bail;
/* test recovering with half broken data and leading parity */
for (i = 0; i < np / 2; ++i)
ret = raid_test_rec_dataonly(np, ir, ip, nd, np, size, v, ref);
if (ret != 0)
goto bail;
/* test recovering with broken leading data and broken leading parity */
for (i = 0; i < np / 2; ++i) {
/* bad data */
ir[i] = i;
/* good parity */
ip[i] = (np + 1) / 2 + i;
}
/* bad parity */
for (i = 0; i < (np + 1) / 2; ++i)
ir[np / 2 + i] = nd + i;
@ -266,16 +329,30 @@ int raid_selftest(void)
if (ret != 0)
goto bail;
/* test recovering with half broken data and ending parity */
for (i = 0; i < np / 2; ++i)
ret = raid_test_rec_dataonly(np / 2, ir, ip, nd, np, size, v, ref);
if (ret != 0)
goto bail;
/* test recovering with broken leading data and broken ending parity */
for (i = 0; i < np / 2; ++i) {
/* bad data */
ir[i] = i;
/* good parity */
ip[i] = i;
}
/* bad parity */
for (i = 0; i < (np + 1) / 2; ++i)
ir[np / 2 + i] = nd + np - (np + 1) / 2 + i;
ret = raid_test_rec(np, ir, nd, np, size, v, ref);
if (ret != 0)
goto bail;
ret = raid_test_rec_dataonly(np / 2, ir, ip, nd, np, size, v, ref);
if (ret != 0)
goto bail;
}
bail:

View file

@ -139,9 +139,9 @@ void raid_gen(int nd, int np, size_t size, void **v);
void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v);
/**
* Recovers failures in data blocks using the specified parities.
* Recovers failures in data blocks only.
*
* The data blocks marked as bad in the @id vector are recovered.
* This function recovers all the data blocks marked as bad in the @id vector.
* The parity blocks are not modified.
*
* @nr Number of failed data blocks to recover.