예제 #1
0
void *DBRM_deadlock(void *arg) 
{
	DBRM dbrm;
	int terr;
	VER_t txn = 2;
	vector<LBIDRange> ranges;
	LBIDRange range;
	vector<VBRange> freeList;

	range.start = 2000;
	range.size = 1000;
	ranges.push_back(range);
  	terr = dbrm.beginVBCopy(txn, ranges, freeList);

	range.start = 1000;
	range.size = 1000;
	ranges.clear();
	freeList.clear();
	ranges.push_back(range);
	terr = dbrm.beginVBCopy(txn, ranges, freeList);

	// block waiting on the main thread, main thread deadlocks, rolls back, 
	// thread wakes

	CPPUNIT_ASSERT(terr == 0);
	terr = dbrm.endVBCopy(txn, ranges);

 	CPPUNIT_ASSERT(terr == 0);
	terr = dbrm.vbCommit(txn);

  	CPPUNIT_ASSERT(terr == 0);

	return NULL;
}
예제 #2
0
void DBRM_resource_graph_1()
{
	DBRM dbrm;
	pthread_t t;
	VER_t txn = 1;
	int err, allocSize;
	LBIDRange range;
	vector<LBID_t> lbids;
	vector<LBIDRange> ranges;
	vector<VBRange> freeList;

	err = dbrm.createExtent(8000, 1, lbids, allocSize);
	CPPUNIT_ASSERT(err == 0);

	range.start = 1000;
	range.size = 1000;
	ranges.push_back(range);
	err = dbrm.beginVBCopy(txn, ranges, freeList);
	CPPUNIT_ASSERT(err == 0);

	pthread_create(&t, NULL, DBRM_dummy_1, NULL);
	sleep(1);
	
	// thread tries to grab 500-1500, blocks
	err = dbrm.endVBCopy(txn, ranges);
	CPPUNIT_ASSERT(err == 0);
	err = dbrm.vbCommit(txn);
	CPPUNIT_ASSERT(err == 0);

	dbrm.deleteOID(1);
	
	//thread finishes
	pthread_join(t, NULL);
}
예제 #3
0
void *DBRM_dummy_1(void *arg) 
{
	DBRM dbrm;
	int err;
	VER_t txn = 2;
	vector<LBIDRange> ranges;
	LBIDRange range;
	vector<VBRange> freeList;

	range.start = 500;
	range.size = 1000;
	ranges.push_back(range);
  	err = dbrm.beginVBCopy(txn, ranges, freeList);
  	CPPUNIT_ASSERT(err == 0);
  	err = dbrm.endVBCopy(txn, ranges);
 	CPPUNIT_ASSERT(err == 0);
	err = dbrm.vbCommit(txn);
 	CPPUNIT_ASSERT(err == 0);

	return NULL;
}
예제 #4
0
void dbrm_clear()
{
	DBRM dbrm;
	VSS vss;
	VBBM vbbm;
	int err, vssShmid, vbbmShmid, txnID = 1, i;
	struct shmid_ds vssShminfo[3], vbbmShminfo[3];
	LBIDRange_v ranges;
	LBIDRange range;
	VBRange_v freelist;

 	err = dbrm.clear();
 	CPPUNIT_ASSERT(err == ERR_OK);
	
	// grab the size of vss and vbbm shmsegs somehow
	vss.lock(VSS::READ);
	vbbm.lock(VBBM::READ);
	vssShmid = vss.getShmid();
	vbbmShmid = vbbm.getShmid();
	err = shmctl(vssShmid, IPC_STAT, &vssShminfo[0]);
	CPPUNIT_ASSERT(err == 0);
	err = shmctl(vbbmShmid, IPC_STAT, &vbbmShminfo[0]);
	CPPUNIT_ASSERT(err == 0);
	vss.release(VSS::READ);
	vbbm.release(VBBM::READ);

	// do begin, write, end vbcopy for 150k blocks
	cerr << endl << "Adding 150k block entries. ";
	range.start = 1;
	range.size = 150000;
	ranges.push_back(range);
	err = dbrm.beginVBCopy(txnID, ranges, freelist);
	CPPUNIT_ASSERT(err == 0);

	for (i = range.start; (uint32_t) i < range.size; i++) {
		if (i % 50000 == 0)
			cerr << " ... " << i;
		err = dbrm.writeVBEntry(txnID, i, 1, i);
		CPPUNIT_ASSERT(err == 0);
	}
	err = dbrm.endVBCopy(txnID, ranges);
	CPPUNIT_ASSERT(err == 0);
	cerr << "  done." << endl;

	// grab the sizes again
	vss.lock(VSS::READ);
	vbbm.lock(VBBM::READ);
	vssShmid = vss.getShmid();
	vbbmShmid = vbbm.getShmid();
	err = shmctl(vssShmid, IPC_STAT, &vssShminfo[1]);
	CPPUNIT_ASSERT(err == 0);
	err = shmctl(vbbmShmid, IPC_STAT, &vbbmShminfo[1]);
	CPPUNIT_ASSERT(err == 0);
	vss.release(VSS::READ);
	vbbm.release(VBBM::READ);

	// make sure they grew
	CPPUNIT_ASSERT(vssShminfo[0].shm_segsz < vssShminfo[1].shm_segsz);
	CPPUNIT_ASSERT(vbbmShminfo[0].shm_segsz < vbbmShminfo[1].shm_segsz);

	dbrm.clear();

	// check that the new size is the same as the original
	vss.lock(VSS::READ);
	vbbm.lock(VBBM::READ);
	vssShmid = vss.getShmid();
	vbbmShmid = vbbm.getShmid();
	err = shmctl(vssShmid, IPC_STAT, &vssShminfo[2]);
	CPPUNIT_ASSERT(err == 0);
	err = shmctl(vbbmShmid, IPC_STAT, &vbbmShminfo[2]);
	CPPUNIT_ASSERT(err == 0);
	vss.release(VSS::READ);
	vbbm.release(VBBM::READ);

	CPPUNIT_ASSERT(vssShminfo[0].shm_segsz == vssShminfo[2].shm_segsz);
	CPPUNIT_ASSERT(vbbmShminfo[0].shm_segsz == vbbmShminfo[2].shm_segsz);

}
예제 #5
0
void DBRM_resource_graph_deadlock()
{
	DBRM dbrm;
	pthread_t t;
	VER_t txn = 1;
	int err, i;
	LBIDRange range;
	vector<LBID_t> lbids;
	vector<LBIDRange> ranges;
	vector<VBRange> freeList;

	range.start = 1000;
	range.size = 1000;
	ranges.push_back(range);
	err = dbrm.beginVBCopy(txn, ranges, freeList);
	CPPUNIT_ASSERT(err == 0);

	for (i = range.start; i < range.start + range.size; i++) {
		err = dbrm.writeVBEntry(txn, i, 1, i);
		CPPUNIT_ASSERT(err == 0);
	}
	err = dbrm.endVBCopy(txn, ranges);
	CPPUNIT_ASSERT(err == 0);

	pthread_create(&t, NULL, DBRM_deadlock, NULL);

	// thread grabs 2000-2999 and 1000-1999 as 2 seperate ranges
	sleep(1);
	
	range.start = 2000;
	range.size = 1000;
	ranges.clear();
	ranges.push_back(range);
	err = dbrm.beginVBCopy(txn, ranges, freeList);
	CPPUNIT_ASSERT(err == ERR_DEADLOCK);
	
	// roll back the blocks we "wrote"
	range.start = 1000;
	range.size = 1000;
	ranges.clear();
	ranges.push_back(range);
	err = dbrm.vbRollback(txn, ranges);
	CPPUNIT_ASSERT(err == ERR_OK);

	// thread finishes	

	txn = 3;
	err = dbrm.beginVBCopy(txn, ranges, freeList);
	CPPUNIT_ASSERT(err == 0);

	for (i = range.start; i < range.start + range.size; i++) {
		err = dbrm.writeVBEntry(txn, i, 1, i);
		CPPUNIT_ASSERT(err == 0);
	}
	err = dbrm.endVBCopy(txn, ranges);
	CPPUNIT_ASSERT(err == 0);

	err = dbrm.vbRollback(txn, ranges);
	CPPUNIT_ASSERT(err == 0);

	pthread_join(t, NULL);
}
예제 #6
0
	// cut & pasted from brm_good_2(), but with rollback instead of commit.
	void brm_good_3()
	{
		DBRM brm;
		VBBM vbbm;
		VSS vss;
		CopyLocks cl;
		int i, err, size;
		vector<LBID_t> lbids;
		vector<LBID_t>::iterator lbid;
		vector<EMEntry> extents;
		LBIDRange_v ranges;
		LBIDRange_v::iterator lbidRangeIT;
		VBRange_v vbRanges, vbRanges2;
		VBRange_v::iterator vbRangesIT;
		LBIDRange_v tmp;
		EMEntry em;
		OID_t oid;
		uint32_t fbo;
		LBIDRange range;
		VBRange vbRange;
		VER_t verID;
		bool vbFlag;
		bool caughtException;
		
		// Buildbot times out on the getBlocks() call during leakcheck b/c it takes
		// > 5 mins for some reason.  Have to ping it before 300 seconds go by.
		void (*oldsig)(int);
		
 		cerr << "brm_good_3" << endl;

		oldsig = signal(SIGALRM, keepalive);
		alarm(290);
		
 		err = brm.lookup(0, 0, false, oid, fbo);
 		CPPUNIT_ASSERT(err != 0); 
		err = brm.lookup(0, 0, true, oid, fbo);
		CPPUNIT_ASSERT(err != 0);
		
 		err = brm.createExtent(8000, 1, lbids, size);
 		CPPUNIT_ASSERT(err == 0);
 		CPPUNIT_ASSERT(size == brm.getExtentSize());
 		CPPUNIT_ASSERT(lbids.size() == 1);
  		CPPUNIT_ASSERT(*(lbids.begin()) == 0);
		
		err = brm.getExtents(1, extents);
		CPPUNIT_ASSERT(err == 0);
		CPPUNIT_ASSERT(extents.size() == 1);
		
		em = *(extents.begin());
 		CPPUNIT_ASSERT(em.range.start == 0);
		CPPUNIT_ASSERT(em.range.size*1024 == static_cast<uint32_t>(brm.getExtentSize()));
		CPPUNIT_ASSERT(em.HWM == 0);
		CPPUNIT_ASSERT(em.blockOffset == 0);
		
		for (i = 0; i < 5; i++) {
			range.start = i * 100;
			range.size = 100;
			ranges.push_back(range);
		}

		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		err = brm.beginVBCopy(1, ranges, vbRanges);
		CPPUNIT_ASSERT(err == 0);
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		cl.lock(CopyLocks::READ);
		for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end(); 
				   lbidRangeIT++)
			CPPUNIT_ASSERT(cl.isLocked(*lbidRangeIT));
		cl.release(CopyLocks::READ);
		
		err = brm.beginVBCopy(1, ranges, vbRanges2);
		CPPUNIT_ASSERT(err != 0);
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		cl.lock(CopyLocks::READ);
		for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end(); 
				   lbidRangeIT++)
			CPPUNIT_ASSERT(cl.isLocked(*lbidRangeIT));
		cl.release(CopyLocks::READ);
		
		for (i = 0; i < 500; i++) {
			verID = MAXINT;
			err = brm.vssLookup(i, verID, 1, vbFlag);
			CPPUNIT_ASSERT(err != 0);
		}
		
		vbRange = *(vbRanges.begin());
// 		CPPUNIT_ASSERT(vbRange.vbFBO == 0);
		for (i = 0; i < (int)vbRange.size; i++) {
			err = brm.writeVBEntry(1, i, vbRange.vbOID, vbRange.vbFBO + i);
			CPPUNIT_ASSERT(err == 0);
		}
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		for (i = 0; i < (int)vbRange.size; i++) { 
			verID = MAXINT;
			err = brm.vssLookup(i, verID, 1, vbFlag);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(verID == 1);
			CPPUNIT_ASSERT(vbFlag == false);
			verID = MAXINT;
			err = brm.vssLookup(i, verID, 0, vbFlag);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(verID == 0);
			CPPUNIT_ASSERT(vbFlag == true);
		}
		
		for (; i < 500; i++) {
			verID = MAXINT;
			err = brm.vssLookup(i, verID, 1, vbFlag);
			CPPUNIT_ASSERT(err != 0);
		}
					
		err = brm.endVBCopy(0, ranges);
			
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		cl.lock(CopyLocks::READ);
		for (lbidRangeIT = ranges.begin(); lbidRangeIT != ranges.end(); 
				   lbidRangeIT++)
			CPPUNIT_ASSERT(!cl.isLocked(*lbidRangeIT));
		cl.release(CopyLocks::READ);
		
		err = brm.getUncommittedLBIDs(1, lbids);
		CPPUNIT_ASSERT(err == 0);
		CPPUNIT_ASSERT(lbids.size() == vbRange.size);
		sort<vector<LBID_t>::iterator>(lbids.begin(), lbids.end());
		lbid = lbids.begin();
		for (i = 0; i < static_cast<int>(lbids.size()); i++, lbid++)
			CPPUNIT_ASSERT((*lbid) == static_cast<LBID_t>(i));
		
		range.start = 0;
		range.size = i;
		tmp.push_back(range);
		err = brm.vbRollback(1, tmp);
		CPPUNIT_ASSERT(err == 0);
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		for (i = 0; i < (int)vbRange.size; i++) { 
			verID = MAXINT;
			
			err = brm.vssLookup(i, verID, 0, vbFlag);
			CPPUNIT_ASSERT(err == 0);
			CPPUNIT_ASSERT(verID == 0);
			CPPUNIT_ASSERT(vbFlag == false);
			
			err = brm.lookup(i, verID, vbFlag, oid, fbo);
			CPPUNIT_ASSERT(err == 0);
 			CPPUNIT_ASSERT(oid == 1);
			CPPUNIT_ASSERT(fbo == static_cast<uint32_t>(i));
			
			vbbm.lock(VBBM::WRITE);
			vss.lock(VSS::WRITE);

#ifdef BRM_DEBUG
 			caughtException = false;
			try {
				vbbm.removeEntry(i, verID);
				vbbm.confirmChanges();
			}
			catch (logic_error &e) {
				vbbm.undoChanges();
				caughtException = true;
			}
			CPPUNIT_ASSERT(caughtException);
			caughtException = false;
			try {
				vss.removeEntry(i, 1);
				vss.confirmChanges();
			}
			catch (logic_error &e) {
				vss.undoChanges();
				caughtException = true;
			}
			CPPUNIT_ASSERT(caughtException);
#endif

			vss.removeEntry(i, verID);
			vss.confirmChanges();
			vss.release(VSS::WRITE);
			vbbm.release(VBBM::WRITE);
		}
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);
		
		brm.deleteOID(1);
		
		vbbm.lock(VBBM::READ);
		vss.lock(VSS::READ);
		CPPUNIT_ASSERT(vbbm.size() == 0);
		CPPUNIT_ASSERT(vbbm.hashEmpty());
		CPPUNIT_ASSERT(vss.size() == 0);
		CPPUNIT_ASSERT(vss.hashEmpty());
		vss.release(VSS::READ);
		vbbm.release(VBBM::READ);
		
		CPPUNIT_ASSERT(brm.checkConsistency() == 0);

		err = brm.saveState();
		CPPUNIT_ASSERT(err==0);
	}
예제 #7
0
static void *BRMRunner_2(void *arg)
{
	
	vector<Range> copyList, copiedList, committedList;
	vector<Range>::iterator rit;
	vector<LBID_t> writtenList;
	vector<LBID_t>::iterator lit;
	
	pthread_mutex_t listMutex;
	int op;
	uint randstate;
	DBRM *brm;
	struct timeval tv;
	
	pthread_mutex_init(&listMutex, NULL);
	gettimeofday(&tv, NULL);
	randstate = static_cast<uint>(tv.tv_usec);
	brm = new DBRM();
	
	while (!threadStop) {
		op = rand_r(&randstate) % 9;
		
		switch(op) {
			case 0:   // beginVBCopy
			{
				int blockCount, size, err;
				Range newEntry;
				VBRange_v vbRanges;
				VBRange_v::iterator vit;
				LBIDRange_v ranges;
				LBIDRange range;
				VER_t txnID;
				
				size = rand_r(&randstate) % 10000;
				
				pthread_mutex_lock(&mutex);
				newEntry.start = lbidCounter;
				lbidCounter += size;
				txnID = nextTxnID++;
				pthread_mutex_unlock(&mutex);
				
				newEntry.nextBlock = newEntry.start;
				newEntry.end = newEntry.start + size;
				range.start = newEntry.start;
				range.size = size;
				
				err = brm->beginVBCopy(txnID, ranges, vbRanges);
				CPPUNIT_ASSERT(err == 0);
				for (blockCount = 0, vit = vbRanges.begin(); vit != vbRanges.end(); vit++)
					blockCount += (*vit).size;
				CPPUNIT_ASSERT(blockCount == size);
				
				pthread_mutex_lock(&listMutex);
				copyList.push_back(newEntry);
				pthread_mutex_unlock(&listMutex);
				
				err = brm->beginVBCopy(txnID, ranges, vbRanges);
				CPPUNIT_ASSERT(err == -1);
				break;
			}
			case 1:		// writeVBEntry
			{	
				int randIndex;
				VER_t txnID;
				Range *entry;
				
				pthread_mutex_lock(&listMutex);
				if (copyList.size() == 0)
					break;
				
				randIndex = rand_r(&randstate) % copyList.size();
				entry = &(copyList[randIndex]);
				entry->nextBlock++;
				txnID = entry->txnID;
				/********** WORKING HERE **********/
			}
			default:
				cerr << "not finished yet" << endl;
		}
	} 
	return NULL;
}