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

📄 rf_reconstruct.c

📁 RAIDFrame是个非常好的磁盘阵列RAID仿真工具
💻 C
📖 第 1 页 / 共 5 页
字号:
  RF_LOCK_MUTEX(raidPtr->recon_done_proc_mutex);  for(p=raidPtr->recon_done_procs;p;p=p->next) {    p->proc(raidPtr, p->arg);  }  RF_UNLOCK_MUTEX(raidPtr->recon_done_proc_mutex);}int rf_RegisterReconDoneProc(  RF_Raid_t            *raidPtr,  void                (*proc)(),  void                 *arg,  RF_ReconDoneProc_t  **handlep){  RF_ReconDoneProc_t *p;  RF_FREELIST_GET(rf_rdp_freelist,p,next,(RF_ReconDoneProc_t *));  if (p == NULL)    return(ENOMEM);  p->proc = proc;  p->arg = arg;  RF_LOCK_MUTEX(raidPtr->recon_done_proc_mutex);  p->next = raidPtr->recon_done_procs;  raidPtr->recon_done_procs = p;  RF_UNLOCK_MUTEX(raidPtr->recon_done_proc_mutex);  if (handlep)    *handlep = p;  return(0);}/***************************************************************************************** * * sets up the parameters that will be used by the reconstruction process * currently there are none, except for those that the layout-specific * configuration (e.g. rf_ConfigureDeclustered) routine sets up. * * in the kernel, we fire off the recon thread. * ****************************************************************************************/static void rf_ShutdownReconstruction(ignored)  void  *ignored;{  RF_FREELIST_DESTROY(rf_recond_freelist,next,(RF_RaidReconDesc_t *));  RF_FREELIST_DESTROY(rf_rdp_freelist,next,(RF_ReconDoneProc_t *));}int rf_ConfigureReconstruction(listp)  RF_ShutdownList_t  **listp;{  int rc;  RF_FREELIST_CREATE(rf_recond_freelist, RF_MAX_FREE_RECOND,    RF_RECOND_INC, sizeof(RF_RaidReconDesc_t));  if (rf_recond_freelist == NULL)    return(ENOMEM);  RF_FREELIST_CREATE(rf_rdp_freelist, RF_MAX_FREE_RDP,    RF_RDP_INC, sizeof(RF_ReconDoneProc_t));  if (rf_rdp_freelist == NULL) {    RF_FREELIST_DESTROY(rf_recond_freelist,next,(RF_RaidReconDesc_t *));    return(ENOMEM);  }  rc = rf_ShutdownCreate(listp, rf_ShutdownReconstruction, NULL);  if (rc) {    RF_ERRORMSG3("Unable to add to shutdown list file %s line %d rc=%d\n",      __FILE__, __LINE__, rc);    rf_ShutdownReconstruction(NULL);    return(rc);  }#ifdef KERNEL  if (!recon_thread_initialized) {    RF_CREATE_THREAD(recon_thr_handle, rf_ReconKernelThread, NULL); recon_thread_initialized = 1;  }#endif /* KERNEL */  return(0);}static RF_RaidReconDesc_t *AllocRaidReconDesc(raidPtr, row, col, spareDiskPtr, numDisksDone, srow, scol)  RF_Raid_t      *raidPtr;  RF_RowCol_t     row;  RF_RowCol_t     col;  RF_RaidDisk_t  *spareDiskPtr;  int             numDisksDone;  RF_RowCol_t     srow;  RF_RowCol_t     scol;{    RF_RaidReconDesc_t *reconDesc;    RF_FREELIST_GET(rf_recond_freelist,reconDesc,next,(RF_RaidReconDesc_t *));  reconDesc->raidPtr     = raidPtr;  reconDesc->row         = row;  reconDesc->col         = col;  reconDesc->spareDiskPtr=spareDiskPtr;  reconDesc->numDisksDone=numDisksDone;   reconDesc->srow=srow;   reconDesc->scol=scol;  reconDesc->state      = 0;  reconDesc->next       = NULL;  return(reconDesc);}static void FreeReconDesc(reconDesc)  RF_RaidReconDesc_t  *reconDesc;{#if RF_RECON_STATS > 0  printf("RAIDframe: %lu recon event waits, %lu recon delays\n",    reconDesc->numReconEventWaits, reconDesc->numReconExecDelays);#endif /* RF_RECON_STATS > 0 */#ifdef KERNEL  printf("RAIDframe: %lu max exec ticks\n", reconDesc->maxReconExecTicks);#endif /* KERNEL */#if (RF_RECON_STATS > 0) || defined(KERNEL)  printf("\n");#endif /* (RF_RECON_STATS > 0) || KERNEL */  RF_FREELIST_FREE(rf_recond_freelist,reconDesc,next);}/***************************************************************************************** * * primary routine to reconstruct a failed disk.  This should be called from * within its own thread.  It won't return until reconstruction completes, * fails, or is aborted. ****************************************************************************************/int rf_ReconstructFailedDisk(raidPtr, row, col)  RF_Raid_t    *raidPtr;  RF_RowCol_t   row;  RF_RowCol_t   col;{#ifdef SIMULATE  RF_PendingRecon_t *pend;  RF_RowCol_t r, c;#endif /* SIMULATE */  RF_LayoutSW_t *lp;  int rc;  lp = raidPtr->Layout.map;  if (lp->SubmitReconBuffer) {    /*     * The current infrastructure only supports reconstructing one     * disk at a time for each array.     */#ifdef SIMULATE    if (raidPtr->reconInProgress) {      RF_Malloc(pend, sizeof(RF_PendingRecon_t), (RF_PendingRecon_t *));      pend->row = row;      pend->col = col;      pend->next = raidPtr->pendingRecon;      raidPtr->pendingRecon = pend;      /* defer until current recon completes */      return(0);    }    raidPtr->reconInProgress++;#else /* SIMULATE */    RF_LOCK_MUTEX(raidPtr->mutex);    while (raidPtr->reconInProgress) {      RF_WAIT_COND(raidPtr->waitForReconCond, raidPtr->mutex);    }    raidPtr->reconInProgress++;    RF_UNLOCK_MUTEX(raidPtr->mutex);#endif /* SIMULATE */    rc = rf_ReconstructFailedDiskBasic(raidPtr, row, col);  }  else {    RF_ERRORMSG1("RECON: no way to reconstruct failed disk for arch %c\n",      lp->parityConfig);    rc = EIO;  }#ifdef SIMULATE  pend = raidPtr->pendingRecon;  if (pend) {    /* launch next recon */    raidPtr->pendingRecon = pend->next;    r = pend->row;    c = pend->col;    RF_Free(pend, sizeof(RF_PendingRecon_t));    return(rf_ReconstructFailedDisk(raidPtr, r, c));  }#else /* SIMULATE */  RF_LOCK_MUTEX(raidPtr->mutex);  raidPtr->reconInProgress--;  RF_UNLOCK_MUTEX(raidPtr->mutex);  RF_SIGNAL_COND(raidPtr->waitForReconCond);#endif /* SIMULATE */  return(rc);}int rf_ReconstructFailedDiskBasic(raidPtr, row, col)  RF_Raid_t    *raidPtr;  RF_RowCol_t   row;  RF_RowCol_t   col;{  RF_RaidDisk_t *spareDiskPtr = NULL;  RF_RaidReconDesc_t *reconDesc;  RF_RowCol_t srow, scol;  int numDisksDone, rc;  /* first look for a spare drive onto which to reconstruct the data */  /* spare disk descriptors are stored in row 0.  This may have to change eventually */  RF_LOCK_MUTEX(raidPtr->mutex);  RF_ASSERT (raidPtr->Disks[row][col].status == rf_ds_failed);  if (raidPtr->Layout.map->flags & RF_DISTRIBUTE_SPARE) {    if (raidPtr->status[row] != rf_rs_degraded) {      RF_ERRORMSG2("Unable to reconstruct disk at row %d col %d because status not degraded\n",row,col);      RF_UNLOCK_MUTEX(raidPtr->mutex);      return(EINVAL);    }    srow = row;    scol = (-1);  }  else {    srow = 0;    for (scol=raidPtr->numCol; scol<raidPtr->numCol + raidPtr->numSpare; scol++) {      if (raidPtr->Disks[srow][scol].status == rf_ds_spare) {        spareDiskPtr = &raidPtr->Disks[srow][scol];        spareDiskPtr->status = rf_ds_used_spare;        break;      }    }    if (!spareDiskPtr) {      RF_ERRORMSG2("Unable to reconstruct disk at row %d col %d because no spares are available\n",row,col);      RF_UNLOCK_MUTEX(raidPtr->mutex);      return(ENOSPC);    }#if RF_DEMO > 0    if (!rf_demoMode) {#endif /* RF_DEMO > 0 */      printf("RECON: initiating reconstruction on row %d col %d -> spare at row %d col %d\n",row, col, srow, scol);#if RF_DEMO > 0    }#endif /* RF_DEMO > 0 */  }  RF_UNLOCK_MUTEX(raidPtr->mutex);  reconDesc = AllocRaidReconDesc((void *) raidPtr, row, col,spareDiskPtr, numDisksDone, srow , scol);  raidPtr->reconDesc = (void *) reconDesc;#if RF_RECON_STATS > 0  reconDesc->hsStallCount = 0;  reconDesc->numReconExecDelays = 0;  reconDesc->numReconEventWaits = 0;#endif /* RF_RECON_STATS > 0 */#ifdef KERNEL  reconDesc->reconExecTimerRunning = 0;  reconDesc->reconExecTicks = 0;  reconDesc->maxReconExecTicks = 0;#endif /* KERNEL */#if RF_DEMO > 0 && !defined(SIMULATE)  if (rf_demoMode) {    char cbuf[10];     printf("About to start reconstruction, hit return to continue:");    gets(cbuf);  }#endif /* RF_DEMO > 0 && !SIMULATE */  rc = rf_ContinueReconstructFailedDisk(reconDesc);  return(rc);}int rf_ContinueReconstructFailedDisk(reconDesc)  RF_RaidReconDesc_t  *reconDesc;{  RF_Raid_t             *raidPtr=reconDesc->raidPtr;     RF_RowCol_t            row=reconDesc->row;  RF_RowCol_t            col=reconDesc->col;  RF_RowCol_t            srow=reconDesc->srow;   RF_RowCol_t            scol=reconDesc->scol;  RF_ReconMap_t         *mapPtr;  RF_ReconEvent_t *event;  struct timeval etime, elpsd;  unsigned long xor_s, xor_resid_us;  int retcode,i, ds;    switch (reconDesc->state)    {                case 0:           raidPtr->accumXorTimeUs = 0;      /* create one trace record per physical disk */      RF_Malloc(raidPtr->recon_tracerecs, raidPtr->numCol * sizeof(RF_AccTraceEntry_t), (RF_AccTraceEntry_t *));            /* quiesce the array prior to starting recon.  this is needed to assure no nasty interactions       * with pending user writes.  We need to do this before we change the disk or row status.       */      reconDesc->state=1;      Dprintf("RECON: begin request suspend\n");            retcode =  rf_SuspendNewRequestsAndWait(raidPtr);      Dprintf("RECON: end request suspend\n");            rf_StartUserStats(raidPtr);              /* zero out the stats kept on user accs */#ifdef SIMULATE      if (retcode) return(0);#endif /* SIMULATE */      /* fall through to state 1 */    case 1:      RF_LOCK_MUTEX(raidPtr->mutex);            /* create the reconstruction control pointer and install it in the right slot */      raidPtr->reconControl[row] = rf_MakeReconControl(reconDesc, row, col, srow, scol);      mapPtr=raidPtr->reconControl[row]->reconMap;      raidPtr->status[row] = rf_rs_reconstructing;      raidPtr->Disks[row][col].status = rf_ds_reconstructing;

⌨️ 快捷键说明

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