test.c 3.5 KB

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