portal open is uninterruptible, ^C, etc, ignored. Fix: =================================================================== RCS file: /cvs/src/sys/miscfs/portal/portal_vnops.c,v retrieving revision 1.35 How-To-Repeat: mkfifo /tmp/fifo mount_portal /tmp /mnt cat /mnt/fs/tmp/fifo ^C^C^C^C^C
>@@ -287,7 +289,16 @@ > splx(s); > goto bad; > } >- (void) tsleep((caddr_t) &so->so_timeo, PSOCK, "portalcon", 5 * hz); >+ (void) tsleep((caddr_t) &so->so_timeo, PCATCH|PSOCK, "portalcon", 5 * hz); >+ /* >+ * check for pending signals, return EINTR if hit. >+ */ >+ if ((signo = CURSIG(curproc)) != 0) { >+ splx(s); >+ error = EINTR; >+ postsig(signo); >+ goto bad; >+ } > } > splx(s); > Why not just check the value returned by tsleep()? >@@ -301,7 +312,7 @@ > */ > so->so_rcv.sb_timeo = 0; > so->so_snd.sb_timeo = 0; >- so->so_rcv.sb_flags |= SB_NOINTR; >+ /*so->so_rcv.sb_flags |= SB_NOINTR;*/ /* we want signals for read */ > so->so_snd.sb_flags |= SB_NOINTR; > > Don't comment out wrong code; remove it. >@@ -334,6 +345,16 @@ > &m, &cm, &flags); > if (error) > goto bad; >+ /* >+ * check for pending signals, return EINTR if hit. >+ * don't need to worry about the portal daemon b/c >+ * we close the socket on our way out. >+ */ >+ if ((signo = CURSIG(curproc)) != 0) { >+ error = EINTR; >+ postsig(signo); >+ goto bad; >+ } > > /* > * Grab an error code from the mbuf. I think this should do what tsleep() would do, which is to return either EINTR or ERESTART immediately. Calling postsig() is unnecessary. I'm not sure about the ERESTART handling. Perhaps the problem should be passed to tsleep(): if (CURSIG(curproc) != 0) { error = tsleep(... PCATCH ...); if (error != 0) goto bad; } Bruce
incorporating Bruce's suggestions cleans things up and still works: RCS file: /cvs/src/sys/miscfs/portal/portal_vnops.c,v retrieving revision 1.35 diff -u -r1.35 portal_vnops.c --- portal_vnops.c 1999/01/12 11:49:30 1.35 +++ portal_vnops.c 1999/01/26 21:17:34 @@ -61,6 +61,7 @@ #include <sys/socketvar.h> #include <sys/un.h> #include <sys/unpcb.h> +#include <sys/signalvar.h> #include <miscfs/portal/portal.h> static int portal_fileid = PORTAL_ROOTFILEID+1; @@ -287,7 +288,11 @@ splx(s); goto bad; } - (void) tsleep((caddr_t) &so->so_timeo, PSOCK, "portalcon", 5 * hz); + error = tsleep((caddr_t) &so->so_timeo, PCATCH|PSOCK, "portalcon", 5 * hz); + if (error) { + splx(s); + goto bad; + } } splx(s); @@ -301,7 +306,6 @@ */ so->so_rcv.sb_timeo = 0; so->so_snd.sb_timeo = 0; - so->so_rcv.sb_flags |= SB_NOINTR; so->so_snd.sb_flags |= SB_NOINTR; @@ -334,6 +338,17 @@ &m, &cm, &flags); if (error) goto bad; + /* + * if there's a signal pending, call tsleep to set the + * proper process state and give us the EINTR error. + * don't need to worry about the portal daemon b/c + * we close the socket on our way out. + */ + if (CURSIG(curproc) != 0) { + error = tsleep((caddr_t)vp, PCATCH, "portalcon", 0); + if (error) + goto bad; + } /* * Grab an error code from the mbuf.
State Changed From-To: open->feedback Does this problem still exist?
Add to the audit trail a reply I had forgotten about. In message <200201211942.OAA16709@curly.cs.duke.edu>, Darrell Anderson writes: >iedowse@FreeBSD.org wrote: >> >> Synopsis: fix for uninterruptible open in portal file system >> >> State-Changed-From-To: open->feedback >> State-Changed-By: iedowse >> State-Changed-When: Sat Jan 19 14:52:19 PST 2002 >> State-Changed-Why: >> >> Does this problem still exist? >> >> http://www.FreeBSD.org/cgi/query-pr.cgi?pr=9679 > >Yes. I haven't used portal in quite some time, but looking at the source >code shows the pre-fix code is still in use. > >-Darrell > >-- >Department of Computer Science, Duke University, Durham, NC 27708-0129 >Darrell Anderson, anderson-at-cs.duke.edu, http://www.cs.duke.edu/~anderson
State Changed From-To: feedback->open Feedback was requested and received; throw this back open. http://www.freebsd.org/cgi/query-pr.cgi?pr=9679 Adding to audit trail manually: the directory is now src/sys/fs/portalfs/.