NNTPC: Problems with multiuser handling/locking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As I've mentioned before, I believe there are still problems with the
multiuser handling in nntpcached. For instance, there are several places
where lockex is called without the return status being checked. I added
such a check, and found that it could indeed fail. From my log:

Feb 13 23:26:53 newscache nntpcached[6389]: xover.c:646:Bad file descriptor: unable to lockex 'doffen.uninett.no/no/amiga/8192_xover'
Feb 15 05:20:14 newscache nntpcached[8081]: xover.c:646:Bad file descriptor: unable to lockex 'doffen.uninett.no/comp/sys/hp/hpux/60928_xover'
Feb 15 21:50:12 newscache nntpcached[9038]: xover.c:646:Bad file descriptor: unable to lockex 'doffen.uninett.no/comp/security/misc/37888_xover'

Below is a patch which adds a check on the return status from lockex,
and logs failures. Note that in the cases where the lock is not granted,
it still sets

	xf->locked = TRUE

which is obviously wrong. Just so you don't believe I have *solved* the
problem yet :-)

The patch also tries to make the error messages which log a file name a
bit more uniform.

Steinar Haug, Nethelp consulting, sthaug@nethelp.no
----------------------------------------------------------------------
*** xover.c.orig	Tue Oct 15 10:43:06 1996
--- xover.c	Sat Feb 15 22:30:05 1997
***************
*** 405,411 ****
  			    lseek (xf->fd, 0, SEEK_END) < 4 * MI ||
  			    write (xf->fd, xf->outbuf, xf->outbuf_used) != xf->outbuf_used)
  			{
! 				log (("unable to write/lseek '%s/%s' correctly (...unlinking)", CurrentDir, xf->dir, xf->name));
  				unlink (xf->name);
  			}
  			xf_release_writer (xf);
--- 405,411 ----
  			    lseek (xf->fd, 0, SEEK_END) < 4 * MI ||
  			    write (xf->fd, xf->outbuf, xf->outbuf_used) != xf->outbuf_used)
  			{
! 				loge (("unable to write/lseek '%s/%s' correctly (...unlinking)", xf->dir, xf->name));
  				unlink (xf->name);
  			}
  			xf_release_writer (xf);
***************
*** 581,590 ****
  		fd = open (fn, O_RDWR | O_CREAT, 0664);
  		if (fd < 0 || fstat (fd, &st) < 0)
  		{
! 			loge (("unable to open/create/fstat %s/%s", CurrentDir, fn));
  			goto auth_xover;
  		}
! 		lockex (fd);
  		xf = xf_add (t);
  		xf->fd = fd;
  		xf->name = Sstrdup (fn);
--- 581,593 ----
  		fd = open (fn, O_RDWR | O_CREAT, 0664);
  		if (fd < 0 || fstat (fd, &st) < 0)
  		{
! 			loge (("unable to open/create/fstat '%s/%s'", CurrentDir, fn));
  			goto auth_xover;
  		}
! 		if (lockex (fd) < 0)
! 		{
! 			loge (("unable to lockex '%s/%s'", CurrentDir, fn));
! 		}
  		xf = xf_add (t);
  		xf->fd = fd;
  		xf->name = Sstrdup (fn);
***************
*** 638,644 ****
  	{
  		if (!xf->locked) /* size can't change if we have locked it */
  		{
! 			lockex (xf->fd);
  			xf->locked = TRUE;
  			if (fstat (xf->fd, &st) < 0)
  			{
--- 641,650 ----
  	{
  		if (!xf->locked) /* size can't change if we have locked it */
  		{
! 			if (lockex (xf->fd) < 0)
! 			{
! 				loge (("unable to lockex '%s/%s'", xf->dir, xf->name));
! 			}
  			xf->locked = TRUE;
  			if (fstat (xf->fd, &st) < 0)
  			{
***************
*** 768,781 ****
  		        xf_cached = TRUE;
  		if (fstat (xf->fd, &st) < 0)
  		{
! 			loge (("couldn't fstat(\"%s/%s\") (...unlinked)", xf->dir, xf->name));
  			goto bad;
  		}
  		if (st.st_size <= MI * 4)
  		{
  			if (!xf_cached)
  			{
! 				loge (("short file, %d bytes %s/%s (...unlinked)", st.st_size, xf->dir, xf->name));
  				goto bad;
  			}
                          xf_release_reader (xf);
--- 774,787 ----
  		        xf_cached = TRUE;
  		if (fstat (xf->fd, &st) < 0)
  		{
! 			loge (("unable to fstat '%s/%s' (...unlinked)", xf->dir, xf->name));
  			goto bad;
  		}
  		if (st.st_size <= MI * 4)
  		{
  			if (!xf_cached)
  			{
! 				loge (("short file, %d bytes '%s/%s' cwd %s (...unlinked)", st.st_size, xf->dir, xf->name, CurrentDir));
  				goto bad;
  			}
                          xf_release_reader (xf);
***************
*** 799,805 ****
  				xf->buf = Smalloc (MI * 4);
  				if (read (xf->fd, xf->buf, MI * 4) != MI * 4)
  				{
! 					loge (("couldn't read all %d bytes from %s/%s) (...unlinked)", MI * 4, xf->dir, xf->name));
  					goto bad;
  				}
  			}
--- 805,811 ----
  				xf->buf = Smalloc (MI * 4);
  				if (read (xf->fd, xf->buf, MI * 4) != MI * 4)
  				{
! 					loge (("couldn't read all %d bytes from '%s/%s' (...unlinked)", MI * 4, xf->dir, xf->name));
  					goto bad;
  				}
  			}
***************
*** 810,816 ****
                          {
  				if (lseek (xf->fd, 4 * MI, SEEK_SET) != 4 * MI)
                                  {
! 					loge (("couldn't lseek to %d in %s/%s (...unlinked)", MI * 4, xf->dir, xf->name));
                                          goto bad;
                                  }
  				xf->buf = Srealloc (xf->buf, xf->size);
--- 816,822 ----
                          {
  				if (lseek (xf->fd, 4 * MI, SEEK_SET) != 4 * MI)
                                  {
! 					loge (("couldn't lseek to %d in '%s/%s' (...unlinked)", MI * 4, xf->dir, xf->name));
                                          goto bad;
                                  }
  				xf->buf = Srealloc (xf->buf, xf->size);
***************
*** 820,826 ****
  			rb = xf_cached? xf->size - 4*MI: xf->size;
  			if (read (xf->fd, xf_cached? xf->buf + 4*MI: xf->buf, rb) != rb)
  			{
! 				loge (("couldn't read all of %d bytes from %s/%s (...unlinked)", rb, xf->dir, xf->name));
  				goto bad;
  			}
  			xover_buf = xf->buf + 4 * MI;
--- 826,832 ----
  			rb = xf_cached? xf->size - 4*MI: xf->size;
  			if (read (xf->fd, xf_cached? xf->buf + 4*MI: xf->buf, rb) != rb)
  			{
! 				loge (("couldn't read all of %d bytes from '%s/%s' (...unlinked)", rb, xf->dir, xf->name));
  				goto bad;
  			}
  			xover_buf = xf->buf + 4 * MI;
***************
*** 866,872 ****
  			{
  				if (offset >= xf->size)
  				{
! 					loge (("bad xover offset in %s/%s (%d >= %d) (...unlinked)", xf->dir, xf->name, offset, xf->size));
  					goto bad;
  				}
  				xov = xover_buf + offset - 4 * MI;
--- 872,878 ----
  			{
  				if (offset >= xf->size)
  				{
! 					loge (("bad xover offset in '%s/%s' (%d >= %d) (...unlinked)", xf->dir, xf->name, offset, xf->size));
  					goto bad;
  				}
  				xov = xover_buf + offset - 4 * MI;
***************
*** 874,885 ****
  			{
  				if (lseek (xf->fd, offset, SEEK_SET) != offset)
  				{
! 					loge (("lseek failed for %s/%s (...unlinked)", xf->dir, xf->name));
  					goto bad;
  				}
  				if (read (xf->fd, xover, len) != len)
  				{
! 					loge (("only read part of %s/%s (...unlinked)", xf->dir, xf->name));
  					goto bad;
  				}
  				xov = xover;
--- 880,891 ----
  			{
  				if (lseek (xf->fd, offset, SEEK_SET) != offset)
  				{
! 					loge (("lseek failed for '%s/%s' (...unlinked)", xf->dir, xf->name));
  					goto bad;
  				}
  				if (read (xf->fd, xover, len) != len)
  				{
! 					loge (("only read part of '%s/%s' (...unlinked)", xf->dir, xf->name));
  					goto bad;
  				}
  				xov = xover;
***************
*** 888,894 ****
  			char *blocker;
  			if (FILT && (blocker = xover_filter(xov, overviewFmt)))
  			{
! 				logd (("content filter %s blocked xover of %s/%d", blocker, CurrentDir, xn));
  			} else
  			{
  				if (xhdr)
--- 894,900 ----
  			char *blocker;
  			if (FILT && (blocker = xover_filter(xov, overviewFmt)))
  			{
! 				logd (("content filter %s blocked xover of '%s/%d'", blocker, CurrentDir, xn));
  			} else
  			{
  				if (xhdr)
***************
*** 905,910 ****
--- 911,917 ----
  		continue;
  	      bad:
  		xf_close (xf);
+ 		logt (("unlinking %s dir %s cwd %s", xf->name, xf->dir, CurrentDir));
  		unlink (xf->name);
  		continue;
  	}


[Index of Archives]     [Yosemite]     [Yosemite Campsites]     [Bugtraq]     [Linux]     [Trn]

Powered by Linux