I wrote this greatly simplified skeleton of the failing Git test, and
found that I can reproduce what looks like the same problem, fairly
reliably:
$ rm -f fifo
$ mkfifo fifo
$ dash -c 'while echo -n .; do : < fifo & : > fifo; wait $!; done'
...............................dash: 1: cannot create fifo: Interrupted
system call
After running this through strace, it seems clear what went wrong. The
parent’s open("fifo", O_WRONLY) is what causes the child’s open("fifo",
O_RDONLY) to return. If the child exits immediately, the parent may
receive a SIGCHLD before its own open() returns. Then when its SIGCHLD
handler exits, open() returns EINTR.
That also explains why the SA_RESTART and restart-on-EINTR patches only
turned it into a deadlock. If the open() were restarted now, it would
just block to wait for a _second_ reader of the FIFO, which will never
arrive.
But if that’s what happened, it seems like a kernel bug to me!
Shouldn’t an open() call only be restarted or return EINTR in the case
that it hasn’t had any side effects yet and can safely be restarted?
Anders
--
To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html