From: Jeff King <peff@peff.net>
To: Jan Smets <jan.smets@nokia.com>
Cc: git@vger.kernel.org, Stephen Morton <stephen.morton@nokia.com>
Subject: Re: Client exit whilst running pre-receive hook : commit accepted but no post-receive hook ran
Date: Mon, 25 Jul 2016 18:22:02 -0400 [thread overview]
Message-ID: <20160725222201.GC13589@sigill.intra.peff.net> (raw)
In-Reply-To: <5795EB1C.1080102@nokia.com>
On Mon, Jul 25, 2016 at 12:34:04PM +0200, Jan Smets wrote:
> I have always assumed the post-receive hook to be executed whenever a commit
> is "accepted" by the (gitolite) server. That does not seem to be true any
> more.
Generally, yeah, I would expect that to be the case, too.
> Since 9658846 is appears that, when a client bails out, the pre-receive hook
> continues to run and the commit is written to the repository, but no
> post-receive hook is executed. No signal of any kind is received in the
> hook, not even a sig pipe when the post- hook is writing to stdout whilst
> the client has disconnected.
I see. The problem is that cmd_receive_pack() does this:
execute_commands(commands, unpack_status, &si);
if (pack_lockfile)
unlink_or_warn(pack_lockfile);
if (report_status)
report(commands, unpack_status);
run_receive_hook(commands, "post-receive", 1);
run_update_post_hook(commands);
It reports the status to the client, and _then_ runs the post-receive
hook. But if that reporting fails (either because of an error, or if we
just get SIGPIPE because the client hung up), then we don't actually run
the hooks.
Leaving 9658846 out of it entirely, it is always going to be racy
whether we notice that the client hung up during the pre-receive step.
E.g.:
- your pre-receive might not write any output, so the muxer has
nothing to write to the other side, and we never notice that the
connection closed until we write the status out in report()
- if NO_PTHREADS is set, the sideband muxer runs in a sub-process, not
a sub-thread. And thus we don't know of a hangup except by checking
the result of finish_async(), which we never do.
- the client could hang up just _after_ we've written the pre-receive
output, but before report() is called, so there's nothing to notice
until we're in report()
So I think 9658846 just made that race a bit longer, because it means
that a write error in the sideband muxer during the pre-receive hook
means we return an error via finish_async() rather than unceremoniously
calling exit() from a sub-thread. So we have a longer period during
which we might actually finish off execute_commands() but not make it
out of report().
And the real solution is to make cmd_receive_pack() more robust, and try
harder to run the hooks even when the client hangs up or we have some
other reporting error (because getting data back to the user is only one
use of post-receive hooks; they are also used to queue jobs or do
maintenance).
But that's a bit tricky, as it requires report() to ignore SIGPIPE, and
to stop using write_or_die() or any other functions that can exit (some
of which happen at a lower level). Plus if a client does hangup, we
don't want our hook to die with SIGPIPE either, so we'd want to proxy
the data into /dev/null.
-Peff
next prev parent reply other threads:[~2016-07-25 22:22 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-25 10:34 Client exit whilst running pre-receive hook : commit accepted but no post-receive hook ran Jan Smets
2016-07-25 22:22 ` Jeff King [this message]
2016-08-02 16:01 ` Stephen Morton
2016-08-03 19:30 ` Jeff King
2016-08-03 19:54 ` Junio C Hamano
2016-08-04 0:35 ` Stephen Morton
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=20160725222201.GC13589@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=jan.smets@nokia.com \
--cc=stephen.morton@nokia.com \
/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).