Re: Git pull stuck when Trace2 target set to Unix Stream Socket
- From
Jeff King <peff@peff.net>
- Date
- Apr 13, 2020, 17:18 UTC
- Message-ID
- <20200413171812.GA8183@coredump.intra.peff.net>
- In-Reply-To
- <CAL3xRKceuniEOq+PqN15FC4-mxsWJd4+e2fu1Ku9q_+8JmR9pw@mail.gmail.com>
On Mon, Apr 13, 2020 at 02:05:00PM +0200, Son Luong Ngoc wrote:
Show 14 quoted lines
> I am trying to write a simple git trace2 event collector and I notice > that when git doing git pull with trace events being sent to a unix > stream socket, the entire operation halted. > > Reproduce as follow: > ``` > cd git/git > git config trace2.eventTarget af_unix:stream:/tmp/git_trace.sock > git config trace2.eventBrief false > (rm /tmp/git_trace.sock | ) && nc -lkU /tmp/git_trace.sock > > # In a different terminal > git pull # Pull stuck and never complete > ```
I think the issue is the use of netcat as the server side.
Your git-pull involves multiple simultaneously-running Git processes. But "nc -k" will only accept() a new client once the old one has disconnected. So we'd deadlock any time we have this situation:
- process A opens a stream to the socket, and keeps it open
- process A spawns process B and waits for it to finish
- process B tries to open a stream to the socket, which will block
waiting for netcat to accept()Now A cannot make forward progress until B finishes, but B will not make forward progress until A closes the socket.
I was able to reproduce the issue locally, and process "A" was git-pull and process "B" was git-merge.
Switching to using datagrams ("nc -u" and "af_unix:dgram") makes the problem go away, because the connections are able to interleave their packets.
> This does not happen when you set eventBrief to true > ``` > git config trace2.eventBrief true > ```
I don't know why this would matter (and it didn't seem to in my tests).
> Worth to note that if eventTarget is a file instead of a socket, > everything works fine.
That makes sense, since their file writes can be interleaved.
-Peff