⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rf_testcode.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 5 页
字号:
              rf_PrintAccessStripeMap(wasm);              exit(1);            }          }        }      }    }    for (p=wasm->stripeMap; p; p=p->next) {      rf_ReleaseStripeLock(lockTable, p->stripeID, &p->lockReqDesc);    }        if (rdag != NULL)            rf_FreeDAG(rdag);    if (wdag != NULL)      rf_FreeDAG(wdag);    rf_FreeAccessStripeMap(rasm);    rf_FreeAccessStripeMap(wasm);        RF_Free(sbuf, numbytes);    RF_Free(rbuf, numbytes);#if RF_DEMO > 0    if (!rf_demoMode)#endif /* RF_DEMO > 0 */    {      RF_Free(wbuf, numbytes);    }  }  gettimeofday(&tend, NULL);  RF_TIMEVAL_DIFF(&tstart, &tend, &diff);  printf("[%d] %d WRVs in %0.2f secs, avg KB %d avg wr,rd,tot resp time %d %d %d ms\n",	 tid, iocount, ((float) diff.tv_sec) + (((float) diff.tv_usec)/1000000.0),	 RF_DB0_CHECK(tot_size,iocount)/2, RF_DB0_CHECK(tot_wtime,iocount),	 RF_DB0_CHECK(tot_rtime,iocount), RF_DB0_CHECK((tot_wtime + tot_rtime),2*iocount));  rf_FreeMCPair(mcpair);  RF_THREADGROUP_DONE(&grp->group);}#endif /* !SIMULATE */static void PrintAccessInfo(raidPtr, offset, numsect, wasm, wdag, rasm, rdag)  RF_Raid_t                   *raidPtr;  RF_RaidAddr_t                offset;  RF_SectorCount_t             numsect;  RF_AccessStripeMapHeader_t  *wasm;  RF_DagHeader_t              *wdag;  RF_AccessStripeMapHeader_t  *rasm;  RF_DagHeader_t              *rdag;{  printf("Stripe info on access:\n");  rf_PrintRaidAddressInfo(raidPtr, offset, numsect);  printf("Write ASM was:\n");  rf_PrintAccessStripeMap(wasm);  printf("Write DAG was:\n");    rf_PrintDAGList(wdag);  printf("Read ASM was:\n");  rf_PrintAccessStripeMap(rasm);  printf("Read DAG was:\n");  rf_PrintDAGList(rdag);  fflush(stdout);}#ifndef SIMULATE/* * Write the entire array, each sector getting filled with its sector number. * At the end, verify that each sector contains what we think it should. */void WriteArrayTest(raidPtr, listp)  RF_Raid_t           *raidPtr;  RF_ShutdownList_t  **listp;{  int badrow, badcol, rc, do_copyback, l, i, old_pctg, new_pctg, k, j, uk;  RF_SectorNum_t sector, sec, *sp, *sp1;  char *buf, *buf1, cbuf[100], *b2, *b3;  RF_Thread_t fthread;  RF_GRpair_t *grp;  FILE *outf;  outf = stderr;  /*   * Do k sectors at a time.   */  k = raidPtr->Layout.dataSectorsPerStripe;  fprintf(stderr, "How many sectors to write at a time? [%d] ", k);  fflush(stderr);  gets(cbuf);  j = atoi(cbuf);  if (j > 0)    k = j;  fprintf(outf, "Writing %d sectors at a time\n", k);  RF_Malloc(buf, raidPtr->bytesPerSector*k, (char *));  if (buf == NULL) {    RF_PANIC();  }  sp = (RF_SectorNum_t *)buf;  RF_Malloc(buf1, raidPtr->bytesPerSector*k, (char *));  if (buf1 == NULL) {    RF_PANIC();  }  sp1 = (RF_SectorNum_t *)buf1;  l = raidPtr->bytesPerSector / sizeof(RF_SectorNum_t);  if ((l * sizeof(RF_SectorNum_t)) != raidPtr->bytesPerSector) {    RF_PANIC();  }  grp = rf_GetGrpair(listp);  if (grp == NULL) {    RF_PANIC();  }  grp->raidPtr = raidPtr;  fprintf(stderr,"Degraded mode? [n=none, c=constant, a=asynchronously, r=async+recon, C=async+recon+copyback] ");  gets(cbuf);  rf_testcode_degr_mode_type = *cbuf;  if (rf_testcode_degr_mode_type == 'C') {    rf_testcode_degr_mode_type = 'r';    do_copyback = 1;  }  if (rf_testcode_degr_mode_type == 'c') {    fprintf(stderr,"Row id of disk to mark as bad (-1 for none)? ");    gets(cbuf);    badrow = atoi(cbuf);    if ((badrow >= 0) && (badrow < raidPtr->numRow)) {      fprintf(stderr,"Column id of disk to mark as bad (-1 for none)? ");      gets(cbuf);      badcol = atoi(cbuf);      if (badcol < 0 || badcol >= raidPtr->numCol) {        /* cancel it if the user messes up */        fprintf(stderr, "Not failing a disk.\n");        rf_testcode_degr_mode_type = 'n';      }    }  }  fprintf(outf, "Initializing parity\n");  fflush(outf);  rf_rewriteParityStripes = (-1);  rf_RewriteParity(raidPtr);  fprintf(outf, "Done initializing parity\n");  fflush(outf);  if (rf_testcode_degr_mode_type == '2') {    /* jimz's secret, undocumented double failure test */    rf_FailDisk(raidPtr, 0, 0, 0);    rf_FailDisk(raidPtr, 0, 2, 0);  }  if (rf_testcode_degr_mode_type == '@') {    /* jimz's other secret, undocumented double failure test */    rf_FailDisk(raidPtr, 0, 2, 1);  }  if (rf_testcode_degr_mode_type == 'c') {    rf_FailDisk(raidPtr, badrow, badcol, 0);  }  if ((rf_testcode_degr_mode_type == 'a') || (rf_testcode_degr_mode_type == 'r')    || (rf_testcode_degr_mode_type == '@'))  {    if (RF_CREATE_THREAD(fthread, DiskFailingThread, grp)) {      RF_ERRORMSG1("Unable to create test thread number %d\n",i);      punt(1);    }    RF_THREADGROUP_STARTED(&grp->group);  }  RF_THREADGROUP_WAIT_START(&grp->group);#define INIT_SEC_BUF(_sp_,_sector_) { \  for(j=0;j<k;j++) { \    for(i=0;i<l;i++) { \      _sp_[j*l+i] = _sector_; \    } \  } \}  old_pctg = (-1);  for(sector=0;sector<raidPtr->totalSectors;sector+=uk) {    uk = RF_MIN(k,raidPtr->totalSectors-sector);    INIT_SEC_BUF(sp,sector);    rc = rf_DoAccess(raidPtr, RF_IO_TYPE_WRITE, 0, sector, uk,      buf, NULL, NULL, NULL, 0, NULL, NULL, NULL);    if (rc) {      RF_PANIC();    }    new_pctg = sector*10000/raidPtr->totalSectors;    if (new_pctg != old_pctg) {      fprintf(outf, "\rWrite data: %d.%02d%% complete", new_pctg/100, new_pctg%100);      fflush(outf);    }    old_pctg = new_pctg;  }  fprintf(outf, "\rWrite data: 100.00%% complete\n");  fflush(outf);  RF_THREADGROUP_WAIT_STOP(&grp->group);  /*   * Do the copyback only after all the user threads have exited,   * since it quiesces the array anyway.   */  if (do_copyback)    rf_CopybackReconstructedData(raidPtr);  rf_test_running = 0;  fprintf(outf, "Verifying data\n");  fflush(outf);  old_pctg = (-1);  for(sector=0;sector<raidPtr->totalSectors;sector+=k) {    INIT_SEC_BUF(sp1,sector);    uk = RF_MIN(k,raidPtr->totalSectors-sector);    rc = rf_DoAccess(raidPtr, RF_IO_TYPE_READ, 0, sector, uk,      buf, NULL, NULL, NULL, 0, NULL, NULL, NULL);    if (rc) {      RF_PANIC();    }    for(sec=sector;sec<sector+uk;sec++) {      b2 = buf + (sec-sector)*l;      b3 = buf1 + (sec-sector)*l;      rc = bcmp(b2, b3, raidPtr->bytesPerSector);      if (rc) {        fprintf(outf, "\nMiscompare, sector %lu\n", (unsigned long)sec);        fflush(outf);        old_pctg = (-1);      }    }    new_pctg = sector*10000/raidPtr->totalSectors;    if (new_pctg != old_pctg) {      fprintf(outf, "\rVerify data: %d.%02d%% complete", new_pctg/100, new_pctg%100);      fflush(outf);    }    old_pctg = new_pctg;  }  fprintf(outf, "\rVerify data: 100.00%% complete\n");  fprintf(outf, "Done verifying data\n");  fflush(outf);  fprintf(outf, "Verifying parity\n");  fflush(outf);  VerifyAllParity(raidPtr);  fprintf(outf, "Done verifying parity\n");  fflush(outf);}/* verifies that reconstruction is working right: *  1.  Write the entire array with known data.  The data to write is selected *      as follows.  Maintain a "writemap" that has one longword per sector *      in the array.  The data written to sector i is, in longwords: *         writemap[i], writemap[i]^2, writemap[i]^3, ... *      This allows us to modify the data in the array and still validate that *      it is correct after reconstruction completes. *  2.  Fire off a set of threads that write-read-verify the same (known) data. *      This means that writes occur, but no data ever actually changes. *      This isn't exactly optimal from a testing standpoint, but it makes *      the test easier to write.  If I just wrote random junk down to the *      array, how could I be sure that it got reconstructed correctly? *  3.  Fire off a thread that asynchronously fails a disk and initiates recon. *  4.  When recon finishes, cleanly halt the writing threads and verify that *      the data on the spare is what it is supposed to be. * * We re-use the RealLoopTest code to simplify things here. */void ReconTest(raidPtr, listp)  RF_Raid_t           *raidPtr;  RF_ShutdownList_t  **listp;{  RF_RaidLayout_t *layoutPtr = &raidPtr->Layout;  char cbuf[100];  int nthreads, i, j, k, retcode, rc;  RF_Thread_t *tthreads, fthread;  long status;  static void RealLoopTest(RF_ThreadArg_t arg);  int old_pctg, new_pctg, do_copyback = 0, secs;  long *buf;  int sectPerStripe = layoutPtr->dataSectorsPerStripe;  int bytesPerSect = (1<<raidPtr->logBytesPerSector);  int longsPerSect = bytesPerSect/sizeof(long);  unsigned long rval;  struct timespec ts;  unsigned long rv, rv2;  RF_GRpair_t *grp;  RF_DECLARE_RANDOM;    grp = rf_GetGrpair(listp);  if (grp == NULL) {    RF_PANIC();  }  grp->raidPtr = raidPtr;  lockTable = rf_MakeLockTable();           /* make our own stripe lock table */    RF_INIT_RANDOM(1);  rf_testcode_degr_mode_type = 'r';    fprintf(stderr,"How many parallel threads? [0 is ok] ");  gets(cbuf);  nthreads = atoi(cbuf);  if (nthreads < 0) {    fprintf(stderr,"Huh?\n");    exit(1);  }  fprintf(stderr,"Degraded-mode: none, const, double fail, async, async+recon, reconfig, recon+copyback? [n/c/d/a/r/R/C] ");  gets(cbuf);  rf_testcode_degr_mode_type = *cbuf;  if (rf_testcode_degr_mode_type == 'C') {    rf_testcode_degr_mode_type = 'r';    do_copyback = 1;  }  if (rf_maxTraceRunTimeSec == 0) {    fprintf(stderr,"How long after failure do you want to run for? [sec] ");     gets(cbuf);    secs = atoi(cbuf);    if (secs < 0) {      fprintf(stderr,"Huh?\n");      exit(1);    }    ts.tv_sec = secs;  }  else {    ts.tv_sec = rf_maxTraceRunTimeSec;  }  if (nthreads == 1 && rf_testcode_degr_mode_type != 'r') {    fprintf(stderr,"Perform the painful test? [y/n] ");    gets(cbuf);    if (*cbuf == 'y') painful_test = 1;  }  rc = rf_mutex_init(&writemap_mutex);  if (rc) {    RF_ERRORMSG3("Unable to init mutex file %s line %d rc=%d\n", __FILE__,      __LINE__, rc);    return;  }  /* initialize the write map */  RF_Malloc(writemap, raidPtr->totalSectors, (unsigned char *));  for (i=0; i<raidPtr->totalSectors; i++) {    rv = RF_RANDOM();    rv &= 0xff;    writemap[i] = (unsigned char)rv;  }    /* create a data buffer from which to initialize the array */  RF_Malloc(buf, layoutPtr->dataBytesPerStripe, (long *));  painful_test_buf = buf;  /* write the entire array */#if RF_DEMO > 0  if (!rf_demoSuppressReconInitVerify)#endif /* RF_DEMO > 0 */  {    old_pctg = -1;    for (i=0; i<layoutPtr->numStripe; i++) {      for (j=0; j<sectPerStripe; j++) {	rval = (unsigned long) writemap[i*sectPerStripe+j];	for (k=0; k<longsPerSect; k++) {     /* in sect i, data is writemap[i], writemap[i]^2, writemap[i]^4, ... */	  buf[j*longsPerSect+k] = rval;	  rval *= rval;	}      }      retcode = rf_DoAccess(raidPtr, RF_IO_TYPE_WRITE,NULL, i*layoutPtr->dataSectorsPerStripe, layoutPtr->dataSectorsPerStripe, (caddr_t)buf, NULL, NULL, NULL, 0, NULL,NULL,NULL);      new_pctg = i*100/layoutPtr->numStripe;      if (new_pctg != old_pctg) {fprintf(stderr,"\rInit: %d%% complete",new_pctg); fflush(stdout);}      old_pctg = new_pctg;    }  }  /*  VerifyAllData(raidPtr, buf);  VerifyAllParity(raidPtr);  */  if (rf_testcode_degr_mode_type == 'c') {    rv = RF_RANDOM();    rv2 = RF_RANDOM();    rf_FailDisk(raidPtr, rv % raidPtr->numRow, rv2 % raidPtr->numCol, 0);  }  if (rf_testcode_degr_mode_type == 'R') {    int col;    rv = RF_RANDOM();    col = rv%raidPtr->numCol;    rf_FailDisk(raidPtr, 0, col, 0);    rf_SetReconfiguredMode(raidPtr, 0, col);    rf_testcode_degr_mode_type = 'c';        /* pretend we're running degraded */  }  if (nthreads) {    RF_CallocAndAdd(tthreads, nthreads, sizeof(RF_Thread_t), (RF_Thread_t *), raidPtr->cleanupList);  }  for (i=0; i<nthreads; i++) {    if (RF_CREATE_THREAD(tthreads[i], RealLoopTest, grp)) {      RF_ERRORMSG1("Unable to create test thread number %d\n",i);      punt(1);    }    RF_THREADGROUP_STARTED(&grp->group);  }  if (rf_testcode_degr_mode_type == 'a' || rf_testcode_degr_mode_type == 'r') {    if (RF_CREATE_THREAD(fthread, DiskFailingThread, grp)) {      RF_ERRORMSG("Unable to create disk failing thread\n");      punt(1);    }    RF_THREADGROUP_STARTED(&grp->group);  }  if (rf_testcode_degr_mode_type == 'd' ) {    if (RF_CREATE_THREAD(fthread, DoubleDiskFailingThread, grp)) {      RF_ERRORMSG("Unable to create double disk failing thread\n");      punt(1);    } 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -