Ejemplo n.º 1
0
Archivo: pmqlsi.c Proyecto: b/ION
static void	*handleMessages(void *parm)
{
	/*	Main loop for message reception and handling.		*/

	ReceiverThreadParms	*rtp = (ReceiverThreadParms *) parm;
	int			segLength;
	char			msgbuf[PMQLSA_MSGSIZE];
	unsigned int		mqp;	/*	Priority of rec'd msg.	*/

	iblock(SIGTERM);
	while (rtp->running)
	{	
		segLength = mq_receive(rtp->mq, msgbuf, sizeof msgbuf, &mqp);
		switch (segLength)
		{
		case 1:				/*	Normal stop.	*/
			continue;

		case -1:
			putSysErrmsg("pmqlsi failed receiving msg", NULL);
			pthread_kill(rtp->mainThread, SIGTERM);
			rtp->running = 0;
			continue;
		}

		if (ltpHandleInboundSegment(msgbuf, segLength) < 0)
		{
			putErrmsg("Can't handle inbound segment.", NULL);
			pthread_kill(rtp->mainThread, SIGTERM);
			rtp->running = 0;
			continue;
		}

		/*	Make sure other tasks have a chance to run.	*/

		sm_TaskYield();
	}

	writeErrmsgMemos();
	writeMemo("[i] pmqlsi receiver thread has ended.");
	return NULL;
}
Ejemplo n.º 2
0
Archivo: stcpclo.c Proyecto: b/ION
static void	*sendKeepalives(void *parm)
{
	KeepaliveThreadParms	*parms = (KeepaliveThreadParms *) parm;
	int			count = KEEPALIVE_PERIOD;
	int			bytesSent;

	iblock(SIGTERM);
	while (*(parms->cloRunning))
	{
		snooze(1);
		count++;
		if (count < KEEPALIVE_PERIOD)
		{
			continue;
		}

		/*	Time to send a keepalive.  Note that the
		 *	interval between keepalive attempts will be
		 *	KEEPALIVE_PERIOD plus (if the remote induct
		 *	is not reachable) the length of time taken
		 *	by TCP to determine that the connection
		 *	attempt will not succeed (e.g., 3 seconds).	*/

		count = 0;
		pthread_mutex_lock(parms->mutex);
		bytesSent = sendBundleByTCP(parms->socketName,
				parms->ductSocket, 0, 0, NULL);
		pthread_mutex_unlock(parms->mutex);
		if (bytesSent < 0)
		{
			shutDownClo();
			break;
		}
	}

	return NULL;
}
Ejemplo n.º 3
0
static void	*sendKeepalives(void *parm)
{
	KeepaliveThreadParms	*parms = (KeepaliveThreadParms *) parm;
	int			keepaliveTimer = 0;
	int			bytesSent;
	int			backoffTimer = BACKOFF_TIMER_START;
	int 			backoffTimerCount = 0;
	unsigned char 		*buffer;

	buffer = MTAKE(TCPCLA_BUFSZ);	//To send keepalive bundle
	if (buffer == NULL)
	{
		putErrmsg("No memory for TCP buffer in tcpclo.", NULL);
		return NULL;
	}

	iblock(SIGTERM);
	while (*(parms->cloRunning))
	{
		snooze(1);
		keepaliveTimer++;
		if (keepaliveTimer < *(parms->keepalivePeriod))
		{
			continue;
		}

		// If the negotiated keep alive interval is 0, then
		// keep alives will not be sent.
		if(*(parms->keepalivePeriod) == 0)
		{
			continue;
		}

		/*	Time to send a keepalive.  Note that the
		 *	interval between keepalive attempts will be
		 *	KEEPALIVE_PERIOD plus (if the remote induct
		 *	is not reachable) the length of time taken
		 *	by TCP to determine that the connection
		 *	attempt will not succeed (e.g., 3 seconds).	*/

		keepaliveTimer = 0;
		pthread_mutex_lock(parms->mutex);
		bytesSent = sendBundleByTCPCL(parms->socketName,
				parms->ductSocket, 0, 0, buffer, parms->keepalivePeriod);
		pthread_mutex_unlock(parms->mutex);
		/*	if the node is unable to establish a TCP connection,
 		 * 	the connection should be tried only after some delay.
 		 *								*/
		if(bytesSent == 0)
		{	
			while((backoffTimerCount < backoffTimer) && (*(parms->ductSocket) < 0))
			{
				snooze(1);
				backoffTimerCount++;
				if(!(*(parms->cloRunning)))
				{
					break;
				}
			}
			backoffTimerCount = 0;
			/*	keepaliveTimer keeps track of when the keepalive needs 
			 *	to be sent. This value is set to keepalive period.
			 *	That way at the end of backoff period a 
			 *	keepalive is sent
			 *							*/
			keepaliveTimer = *(parms->keepalivePeriod);

			if(backoffTimer < BACKOFF_TIMER_LIMIT)
			{
				backoffTimer *= 2;
			}
			continue;
		}
		backoffTimer = BACKOFF_TIMER_START;
		if (bytesSent < 0)
		{
			shutDownClo();
			break;
		}
	}
	MRELEASE(buffer);
	return NULL;
}
Ejemplo n.º 4
0
static void	*receiveBundles(void *parm)
{
	/*	Main loop for bundle reception thread	*/

	ReceiveThreadParms	*parms = (ReceiveThreadParms *) parm;
	int			threadRunning = 1;
	AcqWorkArea		*work;
	char			*buffer;

	buffer = MTAKE(TCPCLA_BUFSZ);
	if (buffer == NULL)
	{
		putErrmsg("tcpclo receiver can't get TCP buffer", NULL);
		return NULL;
	}

	work = bpGetAcqArea(parms->vduct);
	if (work == NULL)
	{
		putErrmsg("tcpclo receiver can't get acquisition work area",
				NULL);
		MRELEASE(buffer);
		return NULL;
	}

	iblock(SIGTERM);
	while (threadRunning && *(parms->cloRunning))
	{
		if(*(parms->bundleSocket) < 0)
		{
			snooze(1);
			/*Retry later*/
			continue;
		}

		if (bpBeginAcq(work, 0, NULL) < 0)
		{
			putErrmsg("Can't begin acquisition of bundle.", NULL);
			threadRunning = 0;
			continue;
		}
	
		switch (receiveBundleByTcpCL(*(parms->bundleSocket), work,
					buffer))
		{
		case -1:
			putErrmsg("Can't acquire bundle.", NULL);
			pthread_mutex_lock(parms->mutex);
			closesocket(*(parms->bundleSocket));
			*(parms->bundleSocket) = -1;
			pthread_mutex_unlock(parms->mutex);
			continue;

		case 0:			/*	Shutdown message	*/	
			/*	Go back to the start of the while loop	*/
			pthread_mutex_lock(parms->mutex);
			closesocket(*(parms->bundleSocket));
			*(parms->bundleSocket) = -1;
			pthread_mutex_unlock(parms->mutex);			
			continue;

		default:
			break;			/*	Out of switch.	*/
		}

		if (bpEndAcq(work) < 0)
		{
			putErrmsg("Can't end acquisition of bundle.", NULL);
			threadRunning = 0;
		}

		/*	Make sure other tasks have a chance to run.	*/

		sm_TaskYield();
	}

	/*	End of receiver thread; release resources.		*/

	bpReleaseAcqArea(work);
	MRELEASE(buffer);
	return NULL;
}
Ejemplo n.º 5
0
static int
iblock(struct inodesc *idesc, long ilevel, u_int64_t isize)
{
	ufs_daddr_t *ap, *aplim;
	struct ubuf *bp;
	int i, n, (*func) (struct inodesc *), nif;
	u_int64_t sizepb;
	char pathbuf[MAXPATHLEN + 1], buf[BUFSIZ];
	struct uvnode *devvp, *vp;
	int diddirty = 0;

	if (idesc->id_type == ADDR) {
		func = idesc->id_func;
		n = (*func) (idesc);
		if ((n & KEEPON) == 0)
			return (n);
	} else
		func = dirscan;
	if (chkrange(idesc->id_blkno, fragstofsb(fs, idesc->id_numfrags)))
		return (SKIP);

	devvp = fs->lfs_devvp;
	bread(devvp, fsbtodb(fs, idesc->id_blkno), fs->lfs_bsize,
	    NOCRED, 0, &bp);
	ilevel--;
	for (sizepb = fs->lfs_bsize, i = 0; i < ilevel; i++)
		sizepb *= NINDIR(fs);
	if (isize > sizepb * NINDIR(fs))
		nif = NINDIR(fs);
	else
		nif = howmany(isize, sizepb);
	if (idesc->id_func == pass1check && nif < NINDIR(fs)) {
		aplim = ((ufs_daddr_t *) bp->b_data) + NINDIR(fs);
		for (ap = ((ufs_daddr_t *) bp->b_data) + nif; ap < aplim; ap++) {
			if (*ap == 0)
				continue;
			(void) sprintf(buf, "PARTIALLY TRUNCATED INODE I=%llu",
			    (unsigned long long)idesc->id_number);
			if (dofix(idesc, buf)) {
				*ap = 0;
				++diddirty;
			}
		}
	}
	aplim = ((ufs_daddr_t *) bp->b_data) + nif;
	for (ap = ((ufs_daddr_t *) bp->b_data); ap < aplim; ap++) {
		if (*ap) {
			idesc->id_blkno = *ap;
			if (ilevel == 0) {
				/*
				 * dirscan needs lblkno.
				 */
				idesc->id_lblkno++;
				n = (*func) (idesc);
			} else {
				n = iblock(idesc, ilevel, isize);
			}
			if (n & STOP) {
				if (diddirty)
					VOP_BWRITE(bp);
				else
					brelse(bp, 0);
				return (n);
			}
		} else {
			if (idesc->id_type == DATA && isize > 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, sizeof(pathbuf),
				    idesc->id_number, idesc->id_number);
				pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [3]",
				    pathbuf, (long long)idesc->id_number);
				if (reply("ADJUST LENGTH") == 1) {
					vp = vget(fs, idesc->id_number);
					VTOI(vp)->i_ffs1_size -= isize;
					isize = 0;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
					inodirty(VTOI(vp));
					if (diddirty)
						VOP_BWRITE(bp);
					else
						brelse(bp, 0);
					return (STOP);
				}
			}
		}
		isize -= sizepb;
	}
	if (diddirty)
		VOP_BWRITE(bp);
	else
		brelse(bp, 0);
	return (KEEPON);
}
Ejemplo n.º 6
0
/*
 * Check validity of held blocks in an inode, recursing through all blocks.
 */
int
ckinode(struct ufs1_dinode *dp, struct inodesc *idesc)
{
	ufs_daddr_t *ap, lbn;
	long ret, n, ndb, offset;
	struct ufs1_dinode dino;
	u_int64_t remsize, sizepb;
	mode_t mode;
	char pathbuf[MAXPATHLEN + 1];
	struct uvnode *vp, *thisvp;

	if (idesc->id_fix != IGNORE)
		idesc->id_fix = DONTKNOW;
	idesc->id_entryno = 0;
	idesc->id_filesize = dp->di_size;
	mode = dp->di_mode & IFMT;
	if (mode == IFBLK || mode == IFCHR ||
	    (mode == IFLNK && (dp->di_size < fs->lfs_maxsymlinklen ||
		    (fs->lfs_maxsymlinklen == 0 &&
			dp->di_blocks == 0))))
		return (KEEPON);
	dino = *dp;
	ndb = howmany(dino.di_size, fs->lfs_bsize);

	thisvp = vget(fs, idesc->id_number);
	for (lbn = 0; lbn < NDADDR; lbn++) {
		ap = dino.di_db + lbn;
		if (thisvp)
			idesc->id_numfrags =
				numfrags(fs, VTOI(thisvp)->i_lfs_fragsize[lbn]);
		else {
			if (--ndb == 0 && (offset = blkoff(fs, dino.di_size)) != 0) {
				idesc->id_numfrags =
			    	numfrags(fs, fragroundup(fs, offset));
			} else
				idesc->id_numfrags = fs->lfs_frag;
		}
		if (*ap == 0) {
			if (idesc->id_type == DATA && ndb >= 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, sizeof(pathbuf),
				    idesc->id_number, idesc->id_number);
				pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [1]",
				    pathbuf, (long long)idesc->id_number);
				if (reply("ADJUST LENGTH") == 1) {
					vp = vget(fs, idesc->id_number);
					dp = VTOD(vp);
					dp->di_size = (ap - &dino.di_db[0]) *
					    fs->lfs_bsize;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
					inodirty(VTOI(vp));
				} else
					break;
			}
			continue;
		}
		idesc->id_blkno = *ap;
		idesc->id_lblkno = ap - &dino.di_db[0];
		if (idesc->id_type == ADDR) {
			ret = (*idesc->id_func) (idesc);
		} else
			ret = dirscan(idesc);
		if (ret & STOP)
			return (ret);
	}
	idesc->id_numfrags = fs->lfs_frag;
	remsize = dino.di_size - fs->lfs_bsize * NDADDR;
	sizepb = fs->lfs_bsize;
	for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
		if (*ap) {
			idesc->id_blkno = *ap;
			ret = iblock(idesc, n, remsize);
			if (ret & STOP)
				return (ret);
		} else {
			if (idesc->id_type == DATA && remsize > 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, sizeof(pathbuf),
				    idesc->id_number, idesc->id_number);
				pfatal("DIRECTORY %s INO %lld: CONTAINS EMPTY BLOCKS [2]",
				    pathbuf, (long long)idesc->id_number);
				if (reply("ADJUST LENGTH") == 1) {
					vp = vget(fs, idesc->id_number);
					dp = VTOD(vp);
					dp->di_size -= remsize;
					remsize = 0;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
					inodirty(VTOI(vp));
					break;
				} else
					break;
			}
		}
		sizepb *= NINDIR(fs);
		remsize -= sizepb;
	}
	return (KEEPON);
}
Ejemplo n.º 7
0
int
ckinode(struct ufs1_dinode *dp, struct inodesc *idesc)
{
	ufs_daddr_t *ap;
	int ret;
	long n, ndb, offset;
	struct ufs1_dinode dino;
	quad_t remsize, sizepb;
	mode_t mode;
	char pathbuf[MAXPATHLEN + 1];

	if (idesc->id_fix != IGNORE)
		idesc->id_fix = DONTKNOW;
	idesc->id_entryno = 0;
	idesc->id_filesize = dp->di_size;
	mode = dp->di_mode & IFMT;
	if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
	    dp->di_size < (unsigned)sblock.fs_maxsymlinklen))
		return (KEEPON);
	dino = *dp;
	ndb = howmany(dino.di_size, sblock.fs_bsize);
	for (ap = &dino.di_db[0]; ap < &dino.di_db[NDADDR]; ap++) {
		if (--ndb == 0 && (offset = blkoff(&sblock, dino.di_size)) != 0)
			idesc->id_numfrags =
				numfrags(&sblock, fragroundup(&sblock, offset));
		else
			idesc->id_numfrags = sblock.fs_frag;
		if (*ap == 0) {
			if (idesc->id_type == DATA && ndb >= 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, idesc->id_number,
						idesc->id_number);
                        	pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
					pathbuf);
                        	if (reply("ADJUST LENGTH") == 1) {
					dp = ginode(idesc->id_number);
                                	dp->di_size = (ap - &dino.di_db[0]) *
					    sblock.fs_bsize;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
                                	inodirty();
					
                        	}
			}
			continue;
		}
		idesc->id_blkno = *ap;
		if (idesc->id_type == ADDR)
			ret = (*idesc->id_func)(idesc);
		else
			ret = dirscan(idesc);
		if (ret & STOP)
			return (ret);
	}
	idesc->id_numfrags = sblock.fs_frag;
	remsize = dino.di_size - sblock.fs_bsize * NDADDR;
	sizepb = sblock.fs_bsize;
	for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
		if (*ap) {
			idesc->id_blkno = *ap;
			ret = iblock(idesc, n, remsize);
			if (ret & STOP)
				return (ret);
		} else {
			if (idesc->id_type == DATA && remsize > 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, idesc->id_number,
						idesc->id_number);
                        	pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
					pathbuf);
                        	if (reply("ADJUST LENGTH") == 1) {
					dp = ginode(idesc->id_number);
                                	dp->di_size -= remsize;
					remsize = 0;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
                                	inodirty();
					break;
                        	}
			}
		}
		sizepb *= NINDIR(&sblock);
		remsize -= sizepb;
	}
	return (KEEPON);
}
Ejemplo n.º 8
0
static int
iblock(struct inodesc *idesc, long ilevel, quad_t isize)
{
	ufs_daddr_t *ap;
	ufs_daddr_t *aplim;
	struct bufarea *bp;
	int i, n, (*func)(), nif;
	quad_t sizepb;
	char buf[BUFSIZ];
	char pathbuf[MAXPATHLEN + 1];
	struct ufs1_dinode *dp;

	if (idesc->id_type == ADDR) {
		func = idesc->id_func;
		if (((n = (*func)(idesc)) & KEEPON) == 0)
			return (n);
	} else
		func = dirscan;
	if (chkrange(idesc->id_blkno, idesc->id_numfrags))
		return (SKIP);
	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize);
	ilevel--;
	for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
		sizepb *= NINDIR(&sblock);
	nif = howmany(isize , sizepb);
	if (nif > NINDIR(&sblock))
		nif = NINDIR(&sblock);
	if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
		aplim = &bp->b_un.b_indir[NINDIR(&sblock)];
		for (ap = &bp->b_un.b_indir[nif]; ap < aplim; ap++) {
			if (*ap == 0)
				continue;
			sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
			    (u_long)idesc->id_number);
			if (dofix(idesc, buf)) {
				*ap = 0;
				dirty(bp);
			}
		}
		flush(fswritefd, bp);
	}
	aplim = &bp->b_un.b_indir[nif];
	for (ap = bp->b_un.b_indir; ap < aplim; ap++) {
		if (*ap) {
			idesc->id_blkno = *ap;
			if (ilevel == 0)
				n = (*func)(idesc);
			else
				n = iblock(idesc, ilevel, isize);
			if (n & STOP) {
				bp->b_flags &= ~B_INUSE;
				return (n);
			}
		} else {
			if (idesc->id_type == DATA && isize > 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, idesc->id_number,
						idesc->id_number);
                        	pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
					pathbuf);
                        	if (reply("ADJUST LENGTH") == 1) {
					dp = ginode(idesc->id_number);
                                	dp->di_size -= isize;
					isize = 0;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
                                	inodirty();
					bp->b_flags &= ~B_INUSE;
					return(STOP);
                        	}
			}
		}
		isize -= sizepb;
	}
	bp->b_flags &= ~B_INUSE;
	return (KEEPON);
}
Ejemplo n.º 9
0
int
ckinode(union dinode *dp, struct inodesc *idesc)
{
	off_t remsize, sizepb;
	int i, offset, ret;
	union dinode dino;
	ufs2_daddr_t ndb;
	mode_t mode;
	char pathbuf[MAXPATHLEN + 1];

	if (idesc->id_fix != IGNORE)
		idesc->id_fix = DONTKNOW;
	idesc->id_lbn = -1;
	idesc->id_entryno = 0;
	idesc->id_filesize = DIP(dp, di_size);
	mode = DIP(dp, di_mode) & IFMT;
	if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
	    DIP(dp, di_size) < (unsigned)sblock.fs_maxsymlinklen))
		return (KEEPON);
	if (sblock.fs_magic == FS_UFS1_MAGIC)
		dino.dp1 = dp->dp1;
	else
		dino.dp2 = dp->dp2;
	ndb = howmany(DIP(&dino, di_size), sblock.fs_bsize);
	for (i = 0; i < NDADDR; i++) {
		idesc->id_lbn++;
		if (--ndb == 0 &&
		    (offset = blkoff(&sblock, DIP(&dino, di_size))) != 0)
			idesc->id_numfrags =
				numfrags(&sblock, fragroundup(&sblock, offset));
		else
			idesc->id_numfrags = sblock.fs_frag;
		if (DIP(&dino, di_db[i]) == 0) {
			if (idesc->id_type == DATA && ndb >= 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, idesc->id_number,
						idesc->id_number);
				pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
					pathbuf);
				if (reply("ADJUST LENGTH") == 1) {
					dp = ginode(idesc->id_number);
					DIP_SET(dp, di_size,
					    i * sblock.fs_bsize);
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
					inodirty();

				}
			}
			continue;
		}
		idesc->id_blkno = DIP(&dino, di_db[i]);
		if (idesc->id_type != DATA)
			ret = (*idesc->id_func)(idesc);
		else
			ret = dirscan(idesc);
		if (ret & STOP)
			return (ret);
	}
	idesc->id_numfrags = sblock.fs_frag;
	remsize = DIP(&dino, di_size) - sblock.fs_bsize * NDADDR;
	sizepb = sblock.fs_bsize;
	for (i = 0; i < NIADDR; i++) {
		sizepb *= NINDIR(&sblock);
		if (DIP(&dino, di_ib[i])) {
			idesc->id_blkno = DIP(&dino, di_ib[i]);
			ret = iblock(idesc, i + 1, remsize, BT_LEVEL1 + i);
			if (ret & STOP)
				return (ret);
		} else {
			idesc->id_lbn += sizepb / sblock.fs_bsize;
			if (idesc->id_type == DATA && remsize > 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, idesc->id_number,
						idesc->id_number);
				pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
					pathbuf);
				if (reply("ADJUST LENGTH") == 1) {
					dp = ginode(idesc->id_number);
					DIP_SET(dp, di_size,
					    DIP(dp, di_size) - remsize);
					remsize = 0;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
					inodirty();
					break;
				}
			}
		}
		remsize -= sizepb;
	}
	return (KEEPON);
}
Ejemplo n.º 10
0
static int
iblock(struct inodesc *idesc, long ilevel, off_t isize, int type)
{
	struct bufarea *bp;
	int i, n, (*func)(struct inodesc *), nif;
	off_t sizepb;
	char buf[BUFSIZ];
	char pathbuf[MAXPATHLEN + 1];
	union dinode *dp;

	if (idesc->id_type != DATA) {
		func = idesc->id_func;
		if (((n = (*func)(idesc)) & KEEPON) == 0)
			return (n);
	} else
		func = dirscan;
	if (chkrange(idesc->id_blkno, idesc->id_numfrags))
		return (SKIP);
	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize, type);
	ilevel--;
	for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
		sizepb *= NINDIR(&sblock);
	if (howmany(isize, sizepb) > NINDIR(&sblock))
		nif = NINDIR(&sblock);
	else
		nif = howmany(isize, sizepb);
	if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
		for (i = nif; i < NINDIR(&sblock); i++) {
			if (IBLK(bp, i) == 0)
				continue;
			(void)sprintf(buf, "PARTIALLY TRUNCATED INODE I=%lu",
			    (u_long)idesc->id_number);
			if (preen) {
				pfatal("%s", buf);
			} else if (dofix(idesc, buf)) {
				IBLK_SET(bp, i, 0);
				dirty(bp);
			}
		}
		flush(fswritefd, bp);
	}
	for (i = 0; i < nif; i++) {
		if (ilevel == 0)
			idesc->id_lbn++;
		if (IBLK(bp, i)) {
			idesc->id_blkno = IBLK(bp, i);
			if (ilevel == 0)
				n = (*func)(idesc);
			else
				n = iblock(idesc, ilevel, isize, type);
			if (n & STOP) {
				bp->b_flags &= ~B_INUSE;
				return (n);
			}
		} else {
			if (idesc->id_type == DATA && isize > 0) {
				/* An empty block in a directory XXX */
				getpathname(pathbuf, idesc->id_number,
						idesc->id_number);
				pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
					pathbuf);
				if (reply("ADJUST LENGTH") == 1) {
					dp = ginode(idesc->id_number);
					DIP_SET(dp, di_size,
					    DIP(dp, di_size) - isize);
					isize = 0;
					printf(
					    "YOU MUST RERUN FSCK AFTERWARDS\n");
					rerun = 1;
					inodirty();
					bp->b_flags &= ~B_INUSE;
					return(STOP);
				}
			}
		}
		isize -= sizepb;
	}
	bp->b_flags &= ~B_INUSE;
	return (KEEPON);
}
Ejemplo n.º 11
0
Archivo: brsscla.c Proyecto: b/ION
static void	*sendBundles(void *parm)
{
	/*	Main loop for single bundle transmission thread
	 *	serving all BRS sockets.				*/

	SenderThreadParms	*parms = (SenderThreadParms *) parm;
	unsigned char		*buffer;
	Outduct			outduct;
	Sdr			sdr;
	Outflow			outflows[3];
	int			i;
	Object			bundleZco;
	BpExtendedCOS		extendedCOS;
	char			destDuctName[MAX_CL_DUCT_NAME_LEN + 1];
	unsigned int		bundleLength;
	int			ductNbr;
	int			bytesSent;
	int			failedTransmissions = 0;

	buffer = MTAKE(TCPCLA_BUFSZ);
	if (buffer == NULL)
	{
		putErrmsg("No memory for TCP buffer in brsscla.", NULL);
		return terminateSenderThread(parms);
	}

	sdr = getIonsdr();
	sdr_read(sdr, (char *) &outduct, sdr_list_data(sdr,
			parms->vduct->outductElt), sizeof(Outduct));
	memset((char *) outflows, 0, sizeof outflows);
	outflows[0].outboundBundles = outduct.bulkQueue;
	outflows[1].outboundBundles = outduct.stdQueue;
	outflows[2].outboundBundles = outduct.urgentQueue;
	for (i = 0; i < 3; i++)
	{
		outflows[i].svcFactor = 1 << i;
	}

	/*	Can now begin transmitting to clients.			*/

	iblock(SIGTERM);
	while (!(sm_SemEnded(parms->vduct->semaphore)))
	{
		if (bpDequeue(parms->vduct, outflows, &bundleZco,
				&extendedCOS, destDuctName) < 0)
		{
			break;
		}

		if (bundleZco == 0)		/*	Interrupted.	*/
		{
			continue;
		}

		bundleLength = zco_length(sdr, bundleZco);
		ductNbr = atoi(destDuctName);
		if (ductNbr >= parms->baseDuctNbr
		&& ductNbr <= parms->lastDuctNbr
		&& parms->brsSockets[(i = ductNbr - parms->baseDuctNbr)] != -1)
		{
			bytesSent = sendBundleByTCP(NULL, parms->brsSockets + i,
					bundleLength, bundleZco, buffer);
			if (bytesSent < 0)
			{
				putErrmsg("Can't send bundle.", NULL);
				break;
			}

			if (bytesSent < bundleLength)
			{
				failedTransmissions++;
			}
		}
		else	/*	Can't send it; just discard it.		*/
		{
			sdr_begin_xn(sdr);
			zco_destroy_reference(sdr, bundleZco);
			if (sdr_end_xn(sdr) < 0)
			{
				putErrmsg("Can't destroy ZCO reference.", NULL);
				break;
			}
		}

		/*	Make sure other tasks have a chance to run.	*/

		sm_TaskYield();
	}

	pthread_kill(brssclaMainThread(0), SIGTERM);
	writeMemoNote("[i] brsscla outduct has ended",
			itoa(failedTransmissions));
	MRELEASE(buffer);
	return terminateSenderThread(parms);
}