aboutsummaryrefslogtreecommitdiff
path: root/IkiWiki
diff options
context:
space:
mode:
authorJoey Hess <joey@kitenet.net>2011-12-05 15:17:01 -0400
committerJoey Hess <joey@kitenet.net>2011-12-05 15:17:01 -0400
commitaa226bbb6ba913db0ce428641d4fde733b63f0a8 (patch)
tree738977b0f28be4b2e59aa80bce263647ec1919df /IkiWiki
parent0dcb6f6539ad62d78214265e585b2516a3afe588 (diff)
downloadikiwiki-aa226bbb6ba913db0ce428641d4fde733b63f0a8.tar
ikiwiki-aa226bbb6ba913db0ce428641d4fde733b63f0a8.tar.gz
Consume all stdin when rcs_receive short-circuits, to avoid git SIPIPE race.
We had a weird problem where, after moving to a new, faster server, "git push" would sometimes fail like this: Unpacking objects: 100% (3/3), done. fatal: The remote end hung up unexpectedly fatal: The remote end hung up unexpectedly What turned out to be going on was that git-receive-pack was dying due to an uncaught SIGPIPE. The SIGPIPE occurred when it tried to write to the pre-receive hook's stdin. The pre-receive hook, in this case, was able to do all the checks it needed to do without the input, and so did exit(0) without consuming it. Apparently that causes a race. Most of the time, git forks the hook, writes output to the hook, and then the hook runs, ignores it, and exits. But sometimes, on our new faster server, git forked the hook, and it ran, and exited, before git got around to writing to it, resulting in the SIGPIPE. write(7, "c9f98c67d70a1cfeba382ec27d87644a"..., 100) = -1 EPIPE (Broken pipe) --- SIGPIPE (Broken pipe) @ 0 (0) --- I think git should ignore SIGPIPE when writing to hooks. Otherwise, hooks may have to go out of their way to consume all input, and as I've seen, the races when they fail to do this can lurk undiscovered. I have written to the git mailing list about this. As a workaround, consume all stdin before exiting.
Diffstat (limited to 'IkiWiki')
-rw-r--r--IkiWiki/Receive.pm9
1 files changed, 8 insertions, 1 deletions
diff --git a/IkiWiki/Receive.pm b/IkiWiki/Receive.pm
index c73adfbbb..5908e09f9 100644
--- a/IkiWiki/Receive.pm
+++ b/IkiWiki/Receive.pm
@@ -35,10 +35,17 @@ EOF
}
"u != $uid";
} @{$config{untrusted_committers}}).
- ") exit(0);\n";
+ ") {\n";
$ret.=<<"EOF";
+ /* Trusted user.
+ * Consume all stdin before exiting, as git may
+ * otherwise be unhappy. */
+ char buf[256];
+ while (read(0, &buf, 256) != 0) {}
+ exit(0);
+ }
asprintf(&s, "CALLER_UID=%i", u);
newenviron[i++]=s;
}