test.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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(256)));
  21. struct raid6_calls raid6_call;
  22. char *dataptrs[NDISKS];
  23. char data[NDISKS][PAGE_SIZE];
  24. char recovi[PAGE_SIZE], recovj[PAGE_SIZE];
  25. static void makedata(void)
  26. {
  27. int i, j;
  28. for (i = 0; i < NDISKS; i++) {
  29. for (j = 0; j < PAGE_SIZE; j++)
  30. data[i][j] = rand();
  31. dataptrs[i] = data[i];
  32. }
  33. }
  34. static char disk_type(int d)
  35. {
  36. switch (d) {
  37. case NDISKS-2:
  38. return 'P';
  39. case NDISKS-1:
  40. return 'Q';
  41. default:
  42. return 'D';
  43. }
  44. }
  45. static int test_disks(int i, int j)
  46. {
  47. int erra, errb;
  48. memset(recovi, 0xf0, PAGE_SIZE);
  49. memset(recovj, 0xba, PAGE_SIZE);
  50. dataptrs[i] = recovi;
  51. dataptrs[j] = recovj;
  52. raid6_dual_recov(NDISKS, PAGE_SIZE, i, j, (void **)&dataptrs);
  53. erra = memcmp(data[i], recovi, PAGE_SIZE);
  54. errb = memcmp(data[j], recovj, PAGE_SIZE);
  55. if (i < NDISKS-2 && j == NDISKS-1) {
  56. /* We don't implement the DQ failure scenario, since it's
  57. equivalent to a RAID-5 failure (XOR, then recompute Q) */
  58. erra = errb = 0;
  59. } else {
  60. printf("algo=%-8s faila=%3d(%c) failb=%3d(%c) %s\n",
  61. raid6_call.name,
  62. i, disk_type(i),
  63. j, disk_type(j),
  64. (!erra && !errb) ? "OK" :
  65. !erra ? "ERRB" :
  66. !errb ? "ERRA" : "ERRAB");
  67. }
  68. dataptrs[i] = data[i];
  69. dataptrs[j] = data[j];
  70. return erra || errb;
  71. }
  72. int main(int argc, char *argv[])
  73. {
  74. const struct raid6_calls *const *algo;
  75. int i, j;
  76. int err = 0;
  77. makedata();
  78. for (algo = raid6_algos; *algo; algo++) {
  79. if (!(*algo)->valid || (*algo)->valid()) {
  80. raid6_call = **algo;
  81. /* Nuke syndromes */
  82. memset(data[NDISKS-2], 0xee, 2*PAGE_SIZE);
  83. /* Generate assumed good syndrome */
  84. raid6_call.gen_syndrome(NDISKS, PAGE_SIZE,
  85. (void **)&dataptrs);
  86. for (i = 0; i < NDISKS-1; i++)
  87. for (j = i+1; j < NDISKS; j++)
  88. err += test_disks(i, j);
  89. }
  90. printf("\n");
  91. }
  92. printf("\n");
  93. /* Pick the best algorithm test */
  94. raid6_select_algo();
  95. if (err)
  96. printf("\n*** ERRORS FOUND ***\n");
  97. return err;
  98. }