📄 rf_testcode.c
字号:
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 + -