test.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* -*- linux-c -*- ------------------------------------------------------- *
  3. *
  4. * Copyright 2002-2007 H. Peter Anvin - All Rights Reserved
  5. *
  6. * ----------------------------------------------------------------------- */
  7. /*
  8. * raid6test.c
  9. *
  10. * Test RAID-6 recovery with various algorithms
  11. */
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <linux/raid/pq.h>
  16. #define NDISKS 16 /* Including P and Q */
  17. const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
  18. char *dataptrs[NDISKS];
  19. char data[NDISKS][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
  20. char recovi[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
  21. char recovj[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
  22. static void makedata(int start, int stop)
  23. {
  24. int i, j;
  25. for (i = start; i <= stop; i++) {
  26. for (j = 0; j < PAGE_SIZE; j++)
  27. data[i][j] = rand();
  28. dataptrs[i] = data[i];
  29. }
  30. }
  31. static char disk_type(int d)
  32. {
  33. switch (d) {
  34. case NDISKS-2:
  35. return 'P';
  36. case NDISKS-1:
  37. return 'Q';
  38. default:
  39. return 'D';
  40. }
  41. }
  42. static int test_disks(int i, int j)
  43. {
  44. int erra, errb;
  45. memset(recovi, 0xf0, PAGE_SIZE);
  46. memset(recovj, 0xba, PAGE_SIZE);
  47. dataptrs[i] = recovi;
  48. dataptrs[j] = recovj;
  49. raid6_dual_recov(NDISKS, PAGE_SIZE, i, j, (void **)&dataptrs);
  50. erra = memcmp(data[i], recovi, PAGE_SIZE);
  51. errb = memcmp(data[j], recovj, PAGE_SIZE);
  52. if (i < NDISKS-2 && j == NDISKS-1) {
  53. /* We don't implement the DQ failure scenario, since it's
  54. equivalent to a RAID-5 failure (XOR, then recompute Q) */
  55. erra = errb = 0;
  56. } else {
  57. printf("algo=%-8s faila=%3d(%c) failb=%3d(%c) %s\n",
  58. raid6_call.name,
  59. i, disk_type(i),
  60. j, disk_type(j),
  61. (!erra && !errb) ? "OK" :
  62. !erra ? "ERRB" :
  63. !errb ? "ERRA" : "ERRAB");
  64. }
  65. dataptrs[i] = data[i];
  66. dataptrs[j] = data[j];
  67. return erra || errb;
  68. }
  69. int main(int argc, char *argv[])
  70. {
  71. const struct raid6_calls *const *algo;
  72. const struct raid6_recov_calls *const *ra;
  73. int i, j, p1, p2;
  74. int err = 0;
  75. makedata(0, NDISKS-1);
  76. for (ra = raid6_recov_algos; *ra; ra++) {
  77. if ((*ra)->valid && !(*ra)->valid())
  78. continue;
  79. raid6_2data_recov = (*ra)->data2;
  80. raid6_datap_recov = (*ra)->datap;
  81. printf("using recovery %s\n", (*ra)->name);
  82. for (algo = raid6_algos; *algo; algo++) {
  83. if ((*algo)->valid && !(*algo)->valid())
  84. continue;
  85. raid6_call = **algo;
  86. /* Nuke syndromes */
  87. memset(data[NDISKS-2], 0xee, 2*PAGE_SIZE);
  88. /* Generate assumed good syndrome */
  89. raid6_call.gen_syndrome(NDISKS, PAGE_SIZE,
  90. (void **)&dataptrs);
  91. for (i = 0; i < NDISKS-1; i++)
  92. for (j = i+1; j < NDISKS; j++)
  93. err += test_disks(i, j);
  94. if (!raid6_call.xor_syndrome)
  95. continue;
  96. for (p1 = 0; p1 < NDISKS-2; p1++)
  97. for (p2 = p1; p2 < NDISKS-2; p2++) {
  98. /* Simulate rmw run */
  99. raid6_call.xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
  100. (void **)&dataptrs);
  101. makedata(p1, p2);
  102. raid6_call.xor_syndrome(NDISKS, p1, p2, PAGE_SIZE,
  103. (void **)&dataptrs);
  104. for (i = 0; i < NDISKS-1; i++)
  105. for (j = i+1; j < NDISKS; j++)
  106. err += test_disks(i, j);
  107. }
  108. }
  109. printf("\n");
  110. }
  111. printf("\n");
  112. /* Pick the best algorithm test */
  113. raid6_select_algo();
  114. if (err)
  115. printf("\n*** ERRORS FOUND ***\n");
  116. return err;
  117. }