git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: "Kirill A. Shutemov" <kirill@shutemov.name>
Cc: git@vger.kernel.org,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Konstantin Ryabitsev <konstantin@linuxfoundation.org>
Subject: Re: Problem accessing git.kernel.org with git v2.33 plus gitproxy
Date: Mon, 30 Aug 2021 16:37:50 -0400	[thread overview]
Message-ID: <YS1Bni+QuZBOgkUI@coredump.intra.peff.net> (raw)
In-Reply-To: <20210830182845.pnv7ywnc364jnblt@box>

On Mon, Aug 30, 2021 at 09:28:45PM +0300, Kirill A. Shutemov wrote:

> > I can't reproduce the problem here, using core.gitproxy with a script
> > identical to what you showed above. I tried both cloning, and fetching
> > via both git-fetch and git-fetch-pack.
> 
> Could you try with a kernel repo?
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
> 
> I found that not all repos on kernel.org trigger the issue.

Thanks, I was able to reproduce there (but not with git.git). That makes
me wonder if it's a race condition of some sort. My reproduction was
just:

  git init
  git config core.gitproxy /path/to/proxy/script
  git fetch-pack \
    git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git \
    refs/heads/master

In the meantime, a workaround is:

  git -c protocol.version=0 fetch-pack ...

> > If you can reproduce it at will and it fails on 2.33 but not earlier,
> > then bisecting might be helpful.
> 
> I did. See my other mail.

Yeah, looks like you found ae1a7eefff (fetch-pack: signal v2 server that
we are done making requests, 2021-05-19). I suspected that might be the
case.

I strace'd the underlying socat, and it does this (numbers on the left
are my annotations):

     select(6, [0 5], [1], [], NULL)         = 2 (in [0], out [1])
     recvfrom(3, 0x7ffee69f1f50, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
     recvfrom(3, 0x7ffee69f19d0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
[0]  read(0, "", 8192)                       = 0
     recvfrom(3, 0x7ffee69f19d0, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
[1]  shutdown(5, SHUT_WR)                    = 0
     recvfrom(3, 0x7ffee69f1f50, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
[2]  select(6, [5], [], [], {tv_sec=0, tv_usec=500000}) = 0 (Timeout)
     recvfrom(3, 0x7ffee69f1f50, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
[3]  shutdown(5, SHUT_RDWR)                  = 0
     recvfrom(3, 0x7ffee69f2240, 519, MSG_DONTWAIT, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
     exit_group(0)                           = ?

Here descriptors 0/1 are the pipes from/to Git, and 5 is the TCP socket
connected to the server. The recvfrom() is just noise, I think; socat
opens a dgram socketpair(), but doesn't seem to do anything with it.

So in [0] we see that Git has hung up half of the pipe, due to the new
code in ae1a7eefff. socat then correctly relays the half-duplex shutdown
to the server in [1]. At this point it should wait for the server to
send the data, and relay it to stdout. And indeed, it does call select()
in [2]. But then when it hits the half-second timeout, it shuts down
completely!

I'm not that familiar with socat, but I've seen the same thing with
older versions of netcat: it wants to quit after seeing EOF on stdin.
This is useful to prevent deadlock if the server doesn't respond to a
half-duplex shutdown. But it's quite the wrong thing to do for a more
intelligent protocol.

That explains why you see the problem sometimes but not others. It
depends how long the server takes before it produces any output, which
in turn may depend on things like repo size. You said you didn't see it
when fetching from GitHub, but I suspect it is simply that GitHub's
server responds a little bit more quickly.

In netcat, the fix is to use "-q" (though at least some versions of
netcat will wait forever by default these days, so it's not a problem).
In socat, it looks like "-t" does the same thing. And indeed, switching
the proxy to:

  socat -t 10 - "TCP:$1:$2"

makes the problem go away for me. The 10-second timeout might seem
arbitrary, but it should be reliable. Git's server-side has a keep-alive
mechanism that sends a packet every 5 seconds, even if no output has
been produced yet. So even if the request takes a long time to generate
any output, it should be plenty to tell socat that the connection is
still live.

I am sympathetic that this used to work, and now doesn't. But this proxy
case is affected by the problem that ae1a7eefff was solving. The root of
the issue is just that "socat" in its default form is not doing the
right thing. So I'd prefer not to try to make any change to Git's
behavior here. But one option would be to limit it only to ssh, and not
git:// proxies (we already don't do that half-duplex shutdown for raw
TCP git://, for reasons discussed in that commit message).

-Peff

  reply	other threads:[~2021-08-30 20:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-30 16:11 Kirill A. Shutemov
2021-08-30 16:35 ` Konstantin Ryabitsev
2021-08-30 17:46 ` Pratyush Yadav
2021-08-30 18:04 ` Kirill A. Shutemov
2021-08-30 18:29   ` Andy Shevchenko
2021-08-30 18:30     ` Andy Shevchenko
2021-08-30 18:16 ` Jeff King
2021-08-30 18:28   ` Kirill A. Shutemov
2021-08-30 20:37     ` Jeff King [this message]
2021-08-30 22:42       ` Kirill A. Shutemov
2021-08-31  6:03         ` Jeff King
2021-08-31  8:46           ` Andy Shevchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YS1Bni+QuZBOgkUI@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=git@vger.kernel.org \
    --cc=kirill@shutemov.name \
    --cc=konstantin@linuxfoundation.org \
    --subject='Re: Problem accessing git.kernel.org with git v2.33 plus gitproxy' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).