Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Feb 1999 16:58:40 -0800
From:      John Plevyak <jplevyak@inktomi.com>
To:        hackers@freebsd.org
Subject:   lockf and kernel threads
Message-ID:  <19990224165840.A19033@proxydev.inktomi.com>

next in thread | raw e-mail | index | archive | help

Ok, I found the problem with using kernel threads and fcntl( .. F_SETLK ..).
The issue is two fold.  

 1. the locks are keyed off pid, and if the first thread to exit and close
    them is not the one that took out the lock the close will occur without
    the lock being removed.

 2. the P_ADVLOCK flag is set in p_flags on a per processes basis, so
    we don't even check to see if locks need to be removed if the
    closing (struct proc*) is not the locking (struct proc*).

I have a simple patch, but it requires removing two lines with a
comment indicating that they are needed (however, inspection and
simple testing indicate that this may not be the case):

in kern_exit.c the function exit1() has the lines:

			/*
			 * orphan the threads so we don't mess up
			 * when they call exit
			 */
			nq->p_peers = 0;
			nq->p_leader = nq;

These lines serve to disassociate the peers from the leader, making
it difficult to get the leaders pid or p_flags for use in kern_descrip.c.

Does anyone know what the comment refers to?

See contenxt diff patch at end.

john
-- 
John Bradley Plevyak,    PhD,    jplevyak@inktomi.com,     PGP KeyID: 051130BD
Inktomi Corporation,  1900 S. Norfolk Street,  Suite 110,  San Mateo, CA 94403
W:(415)653-2830 F:(415)653-2801 P:(888)491-1332/5103192436.4911332@pagenet.net

============================== CUT HERE =============================

Index: kern_descrip.c
===================================================================
RCS file: /usr/cvsroot/src/sys/kern/kern_descrip.c,v
retrieving revision 1.58
diff -c -r1.58 kern_descrip.c
*** kern_descrip.c	1999/01/08 17:31:08	1.58
--- kern_descrip.c	1999/02/24 15:52:22
***************
*** 286,298 ****
  		case F_RDLCK:
  			if ((fp->f_flag & FREAD) == 0)
  				return (EBADF);
! 			p->p_flag |= P_ADVLOCK;
  			return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg));
  
  		case F_WRLCK:
  			if ((fp->f_flag & FWRITE) == 0)
  				return (EBADF);
! 			p->p_flag |= P_ADVLOCK;
  			return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg));
  
  		case F_UNLCK:
--- 286,298 ----
  		case F_RDLCK:
  			if ((fp->f_flag & FREAD) == 0)
  				return (EBADF);
! 			p->p_leader->p_flag |= P_ADVLOCK;
  			return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg));
  
  		case F_WRLCK:
  			if ((fp->f_flag & FWRITE) == 0)
  				return (EBADF);
! 			p->p_leader->p_flag |= P_ADVLOCK;
  			return (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &fl, flg));
  
  		case F_UNLCK:
***************
*** 1041,1053 ****
  	 * If the descriptor was in a message, POSIX-style locks
  	 * aren't passed with the descriptor.
  	 */
! 	if (p && (p->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) {
  		lf.l_whence = SEEK_SET;
  		lf.l_start = 0;
  		lf.l_len = 0;
  		lf.l_type = F_UNLCK;
  		vp = (struct vnode *)fp->f_data;
! 		(void) VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_POSIX);
  	}
  	if (--fp->f_count > 0)
  		return (0);
--- 1041,1053 ----
  	 * If the descriptor was in a message, POSIX-style locks
  	 * aren't passed with the descriptor.
  	 */
! 	if (p && (p->p_leader->p_flag & P_ADVLOCK) && fp->f_type == DTYPE_VNODE) {
  		lf.l_whence = SEEK_SET;
  		lf.l_start = 0;
  		lf.l_len = 0;
  		lf.l_type = F_UNLCK;
  		vp = (struct vnode *)fp->f_data;
! 		(void) VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_UNLCK, &lf, F_POSIX);
  	}
  	if (--fp->f_count > 0)
  		return (0);
Index: kern_exit.c
===================================================================
RCS file: /usr/cvsroot/src/sys/kern/kern_exit.c,v
retrieving revision 1.71.2.1
diff -c -r1.71.2.1 kern_exit.c
*** kern_exit.c	1999/01/27 20:51:41	1.71.2.1
--- kern_exit.c	1999/02/24 15:51:38
***************
*** 141,152 ****
--- 141,155 ----
  			kill(p, &killArgs);
  			nq = q;
  			q = q->p_peers;
+ 			/* messes up signals */
+ #if 0
  			/*
  			 * orphan the threads so we don't mess up
  			 * when they call exit
  			 */
  			nq->p_peers = 0;
  			nq->p_leader = nq;
+ #endif
  		}
  
  	/* otherwise are we a peer? */



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990224165840.A19033>