Date: Sun, 29 Jul 2012 13:13:54 -0700 From: Garrett Cooper <yanegomi@gmail.com> To: davidxu@freebsd.org Cc: freebsd-bugs@freebsd.org Subject: Re: kern/170203: [kern] piped dd' s don' t behave sanely when dealing with a fifo Message-ID: <CAGH67wR_Wq-iH6psNX69qEkL8YG1kQuTxQ-0s6PxW3bXwda4Vw@mail.gmail.com> In-Reply-To: <5014A64A.3010106@gmail.com> References: <201207272150.q6RLo9ew012879@freefall.freebsd.org> <501482CD.6050708@gmail.com> <CAGH67wQYCf6N0hF4Hru63snCxVoPjBmLgjyPkVBRT7q7%2BgcqbQ@mail.gmail.com> <50148F42.20105@gmail.com> <5014A64A.3010106@gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] On Sat, Jul 28, 2012 at 7:56 PM, David Xu <listlog2011@gmail.com> wrote: ... > I have updated patch, the patch fixed lost-notification bug for select(): > http://people.freebsd.org/~davidxu/patch/fifopipe/kernel_pipe2.diff This patch prevents the hang from occurring on CURRENT / r238870 (it was missing a header definition in sys/pipe.h). Now all that remains is chasing down why dd's records accounting is bogus. The attached patch makes the output somewhat more meaningful with dd if it receives a SIGPIPE. Thanks! -Garrett PS Fedora 17 does what I expect by reporting the actual number of records transferred across the fifo. [-- Attachment #2 --] --- //depot/user/gcooper/atf-head/src/sys/fs/fifofs/fifo_vnops.c 2012-05-20 04:37:04.000000000 0000 +++ /scratch/p4/user/gcooper/atf-head/src/sys/fs/fifofs/fifo_vnops.c 2012-05-20 04:37:04.000000000 0000 --- /tmp/tmp.47847.94 2012-07-29 12:44:08.083384996 -0700 +++ /scratch/p4/user/gcooper/atf-head/src/sys/fs/fifofs/fifo_vnops.c 2012-07-29 12:00:03.501340141 -0700 @@ -283,8 +283,11 @@ if (fip->fi_readers == 0) { PIPE_LOCK(cpipe); cpipe->pipe_state |= PIPE_EOF; - if (cpipe->pipe_state & PIPE_WANTW) + if ((cpipe->pipe_state & PIPE_WANTW)) { + cpipe->pipe_state &= ~PIPE_WANTW; wakeup(cpipe); + } + pipeselwakeup(cpipe); PIPE_UNLOCK(cpipe); } } @@ -293,10 +296,13 @@ if (fip->fi_writers == 0) { PIPE_LOCK(cpipe); cpipe->pipe_state |= PIPE_EOF; - if (cpipe->pipe_state & PIPE_WANTR) + if ((cpipe->pipe_state & PIPE_WANTR)) { + cpipe->pipe_state &= ~PIPE_WANTR; wakeup(cpipe); + } fip->fi_wgen++; FIFO_UPDWGEN(fip, cpipe); + pipeselwakeup(cpipe); PIPE_UNLOCK(cpipe); } } --- //depot/user/gcooper/atf-head/src/sys/kern/sys_pipe.c 2012-05-20 04:37:04.000000000 0000 +++ /scratch/p4/user/gcooper/atf-head/src/sys/kern/sys_pipe.c 2012-05-20 04:37:04.000000000 0000 --- /tmp/tmp.47847.169 2012-07-29 12:44:08.157343208 -0700 +++ /scratch/p4/user/gcooper/atf-head/src/sys/kern/sys_pipe.c 2012-07-29 12:00:03.515338359 -0700 @@ -227,7 +227,6 @@ static int pipe_paircreate(struct thread *td, struct pipepair **p_pp); static __inline int pipelock(struct pipe *cpipe, int catch); static __inline void pipeunlock(struct pipe *cpipe); -static __inline void pipeselwakeup(struct pipe *cpipe); #ifndef PIPE_NODIRECT static int pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio); static void pipe_destroy_write_buffer(struct pipe *wpipe); @@ -607,7 +606,7 @@ } } -static __inline void +void pipeselwakeup(cpipe) struct pipe *cpipe; { @@ -738,7 +737,7 @@ rpipe->pipe_map.pos += size; rpipe->pipe_map.cnt -= size; if (rpipe->pipe_map.cnt == 0) { - rpipe->pipe_state &= ~PIPE_DIRECTW; + rpipe->pipe_state &= ~(PIPE_DIRECTW|PIPE_WANTW); wakeup(rpipe); } #endif @@ -1001,6 +1000,7 @@ wakeup(wpipe); } pipeselwakeup(wpipe); + wpipe->pipe_state |= PIPE_WANTW; pipeunlock(wpipe); error = msleep(wpipe, PIPE_MTX(wpipe), PRIBIO | PCATCH, "pipdwt", 0); --- //depot/user/gcooper/atf-head/src/sys/sys/pipe.h 2012-05-20 04:37:04.000000000 0000 +++ /scratch/p4/user/gcooper/atf-head/src/sys/sys/pipe.h 2012-05-20 04:37:04.000000000 0000 --- /tmp/tmp.47847.207 2012-07-29 12:44:08.176339128 -0700 +++ /scratch/p4/user/gcooper/atf-head/src/sys/sys/pipe.h 2012-07-29 12:17:53.592393892 -0700 @@ -143,5 +143,6 @@ void pipe_dtor(struct pipe *dpipe); int pipe_named_ctor(struct pipe **ppipe, struct thread *td); +void pipeselwakeup(struct pipe *cpipe); #endif /* !_SYS_PIPE_H_ */ [-- Attachment #3 --] --- //depot/user/gcooper/atf-head/src/bin/dd/dd.c 2012-05-20 04:37:04.000000000 0000 +++ /scratch/p4/user/gcooper/atf-head/src/bin/dd/dd.c 2012-05-20 04:37:04.000000000 0000 @@ -91,6 +91,7 @@ (void)signal(SIGINFO, summaryx); (void)signal(SIGINT, terminate); + (void)signal(SIGPIPE, SIG_IGN); atexit(summary); @@ -116,6 +117,7 @@ { u_int cnt; struct timeval tv; + struct stat sb; if (in.name == NULL) { in.name = "stdin"; @@ -138,7 +140,11 @@ } else { #define OFLAGS \ (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC)) - out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE); + + if (stat(out.name, &sb) != 0 || !S_ISFIFO(sb.st_mode)) + out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE); + else + out.fd = -1; /* * May not have read access, so try again with write only. * Without read we may have a problem if output also does
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGH67wR_Wq-iH6psNX69qEkL8YG1kQuTxQ-0s6PxW3bXwda4Vw>
