📄 ck_restart.cxx
字号:
voidCheckpoint::AddCkDirent(CkptDirent& de, uint8_t generation){ assert (de.type != FRM_TYPE_INVALID); assert (de.lid != UNDEF_LID); assert (de.lid <= CkptDirent::MaxLidValue); CoreDirent *cld = new CoreDirent; assert(cld); cld->oid = de.oid; cld->count = de.count; cld->lid = de.lid; cld->type = de.type; cld->color = CoreDirent::red; coreGeneration[generation].rsrv.nDirent++; coreGeneration[generation].alloc.nCoreDirent++; DEBUG(ckdir) { const char* cty = "??"; switch(de.type) { case FRM_TYPE_ZDPAGE: cty = "zp"; break; case FRM_TYPE_DPAGE: cty = "dp"; break; case FRM_TYPE_NODE: cty = "nd"; break; case FRM_TYPE_ZNODE: cty = "zn"; break; } MsgLog::dprintf(true, "Adding %s 0x%08x%08x lid=0x%08x\n", cty, (uint32_t) (de.oid >> 32), (uint32_t) de.oid, de.lid); } assert (de.type == FRM_TYPE_ZDPAGE || de.type == FRM_TYPE_ZNODE || CONTENT_LID(de.lid)); uint32_t nFrames = 0; if (de.lid != ZERO_LID) { bool needFrame = FrameIsEmpty(de.lid); if (needFrame) { coreGeneration[generation].ReserveFrame(); nFrames = 1; } /* Nodes cause multiple allocations per frame, which is CORRECT. */ coreGeneration[generation].AllocateLid(de.lid); /* Allocating using AllocateLid won't grab a frame implicitly * unless the passed lid is undefined. Manage the alloc.nFrames * count expliticly: */ if (needFrame) coreGeneration[generation].alloc.nFrames++; } coreGeneration[generation].AddToOidMap(cld); switch (de.type) { case FRM_TYPE_NODE: assert(de.lid != ZERO_LID); coreGeneration[generation].rsrv.nNode++; coreGeneration[generation].rsrv.nNodeFrame += nFrames; coreGeneration[generation].alloc.nNode++; coreGeneration[generation].alloc.nNodeFrame += nFrames; break; case FRM_TYPE_DPAGE: assert(de.lid != ZERO_LID); coreGeneration[generation].rsrv.nPage++; coreGeneration[generation].alloc.nPage++; break; case FRM_TYPE_ZNODE: case FRM_TYPE_ZDPAGE: assert(de.lid == ZERO_LID); break; }}voidCheckpoint::ReloadSavedDirectory(){ /* Validate all of the content locations to make sure they are * present: */ DEBUG(reload) MsgLog::dprintf(true, "Validating content pages...\n"); if (lastCkptHdr->hasMigrated == true) { MsgLog::printf(" checkpoint has migrated\n"); return; } uint32_t entry = lastCkptHdr->nRsrvPage + lastCkptHdr->nThreadPage; for (uint32_t i = 0; i < lastCkptHdr->nDirPage; i++, entry++) { lid_t dirLid = lastCkptHdr->dirPage[entry]; coreGeneration[last_ckpt].ReserveFrame(); coreGeneration[last_ckpt].AllocateLid(dirLid); coreGeneration[last_ckpt].rsrv.nDirFrame++; coreGeneration[last_ckpt].alloc.nDirFrame++; DEBUG(ckdir) MsgLog::printf("reading dirpg 0x%x\n", dirLid); ObjectHeader *pObj = Persist::KernGetCkFrame(dirLid); assert(pObj); pObj->TransLock(); CkptDirPage *cdp = (CkptDirPage *) ObjectCache::ObHdrToPage(pObj); DEBUG(ckdir) MsgLog::printf(" nDirEnt = %d\n", cdp->nDirent); /* Scan all the directories to make sure we have all of the * corresponding object locations in the checkpoint area attached: */ for (uint32_t obent = 0; obent < cdp->nDirent; obent++) { lid_t lid = cdp->entry[obent].lid; if (!Persist::FindDivision(dt_Log, lid)) MsgLog::fatal("Checkpoint page 0x%08x [dirent %d] not mounted\n", lid, obent); AddCkDirent(cdp->entry[obent], last_ckpt); } pObj->TransUnlock(); } CheckConsistency("bot Ckpt::ReloadSavedDir()", true);}voidCheckpoint::ReserveCoreDirPages(){ /* Now that we have determined where everything is and what the free * map looks like, and it is safe to call ReserveLogPageFrame(), * preallocate the log frames for the thread list. Also, allocate * any necessary page frames to ensure that we can rewrite the * entire thread directory: */ DEBUG(reload) MsgLog::dprintf(true, "Allocating locations for reserve and thread dirs\n"); for (uint32_t t = 0; t < nThreadDirPage; t++) { if (threadDirHdr[t] == 0) { ObjectHeader *pObj = ObjectCache::GrabPageFrame(); threadDirHdr[t] = pObj; ThreadDirPage *tdp = (ThreadDirPage *) ObjectCache::ObHdrToPage(pObj); threadDirPg[t] = tdp; } if (lastThreadDirLid[t] == ZERO_LID) { lastThreadDirLid[t] = FindFreeFrame(); assert(lastThreadDirLid[t] != 0); AllocateMasterLid(lastThreadDirLid[t]); } if (nextThreadDirLid[t] == ZERO_LID) { nextThreadDirLid[t] = FindFreeFrame(); assert(nextThreadDirLid[t] != 0); AllocateMasterLid(nextThreadDirLid[t]); } } for (uint32_t r = 0; r < nReserveDirPage; r++) { if (reserveDirHdr[r] == 0) { ObjectHeader *pObj = ObjectCache::GrabPageFrame(); reserveDirHdr[r] = pObj; ReserveDirPage *rdp = (ReserveDirPage *) ObjectCache::ObHdrToPage(pObj); reserveDirPg[r] = rdp; } if (lastReserveDirLid[r] == ZERO_LID) { lastReserveDirLid[r] = FindFreeFrame(); assert( lastReserveDirLid[r] ); AllocateMasterLid(lastReserveDirLid[r]); } if (nextReserveDirLid[r] == ZERO_LID) { nextReserveDirLid[r] = FindFreeFrame(); assert( nextReserveDirLid[r] ); AllocateMasterLid(nextReserveDirLid[r]); }#if 0 MsgLog::dprintf(true, "ThreadDirPage[%d] = 0x%08x\n", t, ObjectCache::ObHdrToPage(threadDirHdr[t]));#endif } nextDirPageHdr = ObjectCache::GrabPageFrame(); nextDirPageHdr->ob.oid = UNDEF_LID; assert(nextDirPageHdr); nextDirPage = (CkptDirPage *) ObjectCache::ObHdrToPage(nextDirPageHdr); CheckConsistency("bot Ckpt::RsrvCrDirPgs()", true);}voidCheckpoint::LoadDirectory(){ /* If no ckpt range found, don't bother. */ if (totLogFrame == 0) return; CoreDirent::InitFreeList(totLogFrame); if ( !allocMap.IsFree((logframe_t) 0) || !allocMap.IsFree((logframe_t) 1) ) MsgLog::fatal("Checkpoint header range not found\n"); LoadDirectoryHeaders(); /* Last successful checkpoint record is now pointed to by * lastCkptHdr. Mark all of the directory pages allocated, * including the reserve and thread directory pages. */ if (diskDirPageHdr == 0) diskDirPageHdr = ObjectCache::GrabPageFrame(); ReloadSavedReserves(); ReloadSavedThreads(); ReloadSavedDirectory(); ReserveCoreDirPages(); DEBUG(ckinit) MsgLog::dprintf(true, "Checkpoint fully reloaded\n"); if (lastCkptHdr->hasMigrated == false) StartMigration(false);#if 0 MsgLog::printf("Tot: %d, Avail: %d curLogLoc %d chkLogLoc %d hdrLogLoc %d\n", totLogFrame, nAvailLogLoc, nCurLogLoc, nChkLogLoc, nHdrLogLoc); MsgLog::printf("chkDirPg %d chkNdPot %d chkPg %d chkZpg %d chkNd %d chkDirent %d\n", nChkDirPg, nChkNodePot, nChkPage, nChkZeroPage, nChkNode, nChkDirent);#endif#if 0 Debugger();#endif enabled = true; CheckConsistency("bot Ckpt::LoadDir", true);}voidCheckpoint::AttachRange(lid_t lolid, lid_t hilid){ MsgLog::printf("Attaching ckpt range [0x%x,0x%x)\n", lolid, hilid); logframe_t lo = lolid / EROS_OBJECTS_PER_FRAME; logframe_t hi = hilid / EROS_OBJECTS_PER_FRAME; for (logframe_t ll = lo; ll < hi; ll++) allocMap.MarkFree(ll); nAvailLogFrame += (hi - lo); totLogFrame += (hi - lo); /* FIX: This is not right for very small checkpoint areas, because * it does not account properly for the thread/reserve directory * pages! */ ckGenLimit = (nAvailLogFrame * 6) / 10;}voidCheckpoint::StartThreads(){#ifdef OPTION_DDB if ( Machine::IsDebugBoot() ) { MsgLog::printf("Stopping before waking up threads on restart\n"); Debugger(); }#endif CheckpointedThreads.WakeAll();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -