git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: Johannes Sixt <j6t@kdbg.org>,
	Brian Gernhardt <brian@gernhardtsoftware.com>,
	"git@vger.kernel.org List" <git@vger.kernel.org>
Subject: Re: t5541: Bad file descriptor
Date: Thu, 5 May 2011 02:18:45 -0400	[thread overview]
Message-ID: <20110505061845.GC29033@sigill.intra.peff.net> (raw)
In-Reply-To: <20110505054611.GA29033@sigill.intra.peff.net>

[argh, resend, I meant to cc Johannes Sixt]

On Thu, May 05, 2011 at 01:46:11AM -0400, Jeff King wrote:

> On Wed, May 04, 2011 at 10:35:13PM -0700, Junio C Hamano wrote:
> 
> > Brian Gernhardt <brian@gernhardtsoftware.com> writes:
> > 
> > > I haven't had a lot of time to track down it down until today, but I've
> > > been getting failures in t5541-http-push-.sh.  Several tests fail with
> > > the error "fatal: write error: Bad file descriptor".
> > 
> > A wild guess.
> > 
> > Does it help if you cherry-picked 1e41827 (http: clear POSTFIELDS when
> > initializing a slot, 2011-04-26) on top of the faulty commit?
> 
> I think that 09c9957 (send-pack: avoid deadlock when pack-object dies
> early, 2011-04-25) is totally broken.
> 
> Looking back at my tests, I only tested the case where pack-objects
> fails. And it seems we totally broke the case where the push is supposed
> to succeed.
> 
> Still investigating...

OK, embarrassing. 09c9957 completely breaks smart http pushing. My
testing of Johannes' patch was completely focused on the error case, and
I didn't have a single test for the non-error case. And on top of that,
we _have_ nice tests in the test suite to catch this, but obviously
neither I, nor Johannes, nor Junio were running them (because they need
apache installed and GIT_TEST_HTTPD set).

Ugh.

This patch on top of 09c9957 should fix it.

-- >8 --
Subject: [PATCH] send-pack: unbreak push over stateless rpc

Commit 09c9957 (send-pack: avoid deadlock when pack-object
dies early, 2011-04-25) attempted to fix a hang in the
stateless rpc case by closing a file descriptor early, but
we still need that descriptor.

Basically the deadlock can happen when pack-objects fails,
and the descriptor to upstream is left open. We never send
the pack, so the upstream is left waiting for us to say
something, and we are left waiting for upstream to close the
connection.

In the non-rpc case, our descriptor points straight to the
upstream. We hand it off to run-command, which takes
ownership and closes the descriptor after pack-objects
finishes (whether it succeeds or not).

Commit 09c9957 tried to emulate that in the rpc case. That
isn't right, though. We actually have a descriptor going
back to the remote-helper, and we need to keep using it
after pack-objects is finished. Closing it early completely
breaks pushing via smart-http.

We still need to do something on error to signal the
remote-helper that we won't be sending any pack data
(otherwise we get the deadlock).  In an ideal world, we
would send a special packet back that says "Sorry, there was
an error". But the remote-helper doesn't understand any such
packet, so the best we can do is close the descriptor and
let it report that we hung up unexpectedly.

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin-send-pack.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index 6516288..3e70795 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -97,7 +97,6 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
 		free(buf);
 		close(po.out);
 		po.out = -1;
-		close(fd);
 	}
 
 	if (finish_command(&po))
@@ -519,6 +518,8 @@ int send_pack(struct send_pack_args *args,
 		if (pack_objects(out, remote_refs, extra_have, args) < 0) {
 			for (ref = remote_refs; ref; ref = ref->next)
 				ref->status = REF_STATUS_NONE;
+			if (args->stateless_rpc)
+				close(out);
 			if (use_sideband)
 				finish_async(&demux);
 			return -1;
-- 
1.7.5.406.gfbb2


  parent reply	other threads:[~2011-05-05  6:18 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-05  4:49 t5541: Bad file descriptor Brian Gernhardt
2011-05-05  5:35 ` Junio C Hamano
2011-05-05  5:46   ` Jeff King
2011-05-05  6:16     ` Jeff King
2011-05-05 11:18       ` Sverre Rabbelier
2011-05-05 17:59         ` Avery Pennarun
2011-05-05 18:51           ` Sverre Rabbelier
2011-05-09 14:50             ` Jeff King
2011-05-05  6:18     ` Jeff King [this message]
2011-05-05  6:57       ` Brian Gernhardt
2011-05-05 20:42       ` Johannes Sixt

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=20110505061845.GC29033@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=brian@gernhardtsoftware.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j6t@kdbg.org \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).