root/lib/raid6/test/test.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. makedata
  2. disk_type
  3. test_disks
  4. main

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

/* [<][>][^][v][top][bottom][index][help] */