|
|
|
Re: master: t5800-remote-helpers.sh hangs on test "pulling from remote remote" | |
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] |
|
stefano.lattarini@xxxxxxxxx wrote on Fri, 20 Apr 2012 13:16 +0200:
> On 04/20/2012 01:34 AM, Pete Wyckoff wrote:
> > drizzd@xxxxxx wrote on Sun, 15 Apr 2012 14:51 +0200:
> >> The 'pushing to local repo' test of t5800 which pushes using
> >> git-remote-testgit.py results in a deadlock for Stefano. Invoking
> >> fast-export/fast-import manually seems to work, however. I don't know
> >> what else to try at this point.
> >>
> >> I am pasting some relevant results below.
> >>
> >>> expecting success:
> >>> (cd localclone &&
> >>> echo content >>file &&
> >>> git commit -a -m three &&
> >>> GIT_TRACE=1 GIT_TRANSPORT_HELPER_DEBUG=1 GIT_DEBUG_TESTGIT=1 git push) &&
> >>> compare_refs localclone HEAD server HEAD
> >
> > fast-export should say to fd 1 "feature done\nblob\n..."
> >
> > fast-import is probably blocked on reading fd 0, hoping to find a
> > sequence of commands
> >
> > I too cannot reproduce the problem. Stefano, can you try this
> > bigger hammer? We'll see if anything sticks out.
> >
> > GIT_TRACE=1 GIT_TRANSPORT_HELPER_DEBUG=1 GIT_DEBUG_TESTGIT=1 strace -vf -s 2000 -o /tmp/strace.out git push
> >
> > Then "bzip2 /tmp/strace.out" and attach /tmp/strace.out.bz2, please.
> >
> > -- Pete
> >
> Here it is. Details of the git version I've used to do this test:
>
> $ git describe
> v1.7.10-207-g0bb2ee1
>
> $ git diff
> diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-helpers.sh
> index 1c62001..770cda6 100755
> --- a/t/t5800-remote-helpers.sh
> +++ b/t/t5800-remote-helpers.sh
> @@ -68,7 +68,10 @@ test_expect_success 'pushing to local repo' '
> (cd localclone &&
> echo content >>file &&
> git commit -a -m three &&
> - git push) &&
> + GIT_TRACE=1 \
> + GIT_TRANSPORT_HELPER_DEBUG=1 \
> + GIT_DEBUG_TESTGIT=1 \
> + strace -vf -s 2000 -o /tmp/strace.out git push) &&
> compare_refs localclone HEAD server HEAD
> '
Thank you. Adding the strace made that test work, and a later
one hung with the same race condition. Here's a patch that
describes the race, and adds a strategic sleep to make it easily
reproducible.
Not sure yet what is the right way to fix this. And I don't know
if it's just git-remote-testgit that has the problem because it
forks an importer, or if other remote helpers would be similarly
affected.
The easiest fix is to invoke "python -u" in
git-remote-testgit.py, or do
sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0)
But I'm not sure if this works on all systems. We could also
consider adding a handshake after "export", to give the helper
time to get ready.
-- Pete
--8<--
>From 4179e326d86b6ab9f9c7f79a9dbd03b8d81b6a6a Mon Sep 17 00:00:00 2001
From: Pete Wyckoff <pw@xxxxxxxx>
Date: Sat, 21 Apr 2012 14:57:31 -0400
Subject: [PATCH] demonstrate git-remote-testgit race
Test t5800-remote-helpers "pushing to local repo" can hang
in a race condition between git push and git-remote-testgit.
On the writer side, "git push" invokes push_refs_with_export(),
which sends to stdout the command "export\n" and immediately
starts up "git fast-export". The latter writes its output stream
to the same stdout.
On the reader side, remote helper "git-remote-testgit" reads from
stdin to get its next command. It uses getc() to read characters
from libc up until \n. Libc has buffered a potentially much
larger chunk of stdin. When it sees the "export\n" command, it
forks "git fast-import" to read the stream.
If fast-export is faster than git-remote-testgit + git
fast-import, the fast-export output can end up in libc's buffer,
rather than in git fast-import. The latter blocks on a now-empty
stdin.
This patch demonstates the problem.
Signed-off-by: Pete Wyckoff <pw@xxxxxxxx>
---
git-remote-testgit.py | 7 +++++++
t/t5800-remote-helpers.sh | 17 +++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/git-remote-testgit.py b/git-remote-testgit.py
index 3dc4851..616e772 100644
--- a/git-remote-testgit.py
+++ b/git-remote-testgit.py
@@ -22,6 +22,7 @@ except ImportError:
_digest = sha.new
import sys
import os
+import time
sys.path.insert(0, os.getenv("GITPYTHONLIB","."))
from git_remote_helpers.util import die, debug, warn
@@ -204,6 +205,12 @@ def read_one_line(repo):
"""Reads and processes one command.
"""
+ sleepy = os.environ.get("GIT_REMOTE_TESTGIT_SLEEPY")
+ if sleepy:
+ debug("Sleeping %d sec before readline" % int(sleepy))
+ time.sleep(int(sleepy))
+ debug("Awake, to readline")
+
line = sys.stdin.readline()
cmdline = line
diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-helpers.sh
index 1c62001..7555be6 100755
--- a/t/t5800-remote-helpers.sh
+++ b/t/t5800-remote-helpers.sh
@@ -72,6 +72,23 @@ test_expect_success 'pushing to local repo' '
compare_refs localclone HEAD server HEAD
'
+test_expect_failure 'racily pushing to local repo' '
+ cp -a server server2 &&
+ git clone "testgit::${PWD}/server2" localclone2 &&
+ test_when_finished "rm -rf server2 localclone2" &&
+ (cd localclone2 &&
+ echo content >>file &&
+ git commit -a -m three &&
+ GIT_TRANSPORT_HELPER_DEBUG=1 GIT_REMOTE_TESTGIT_SLEEPY=2 timeout 10 strace -o trace.out -f git push
+ ret=$? &&
+ if [ $ret -eq 124 ]; then
+ echo "Check for too much input in export line" &&
+ grep "read(0, .export" trace.out ; true
+ fi &&
+ exit $ret) &&
+ compare_refs localclone2 HEAD server2 HEAD
+'
+
test_expect_success 'synch with changes from localclone' '
(cd clone &&
git pull)
--
1.7.10.57.g7fa2a.dirty
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Newbies FAQ] [Linux Kernel Development] [Free Online Dating] [Gcc Help] [IETF Annouce] [DCCP] [Netdev] [Networking] [Security] [V4L] [Bugtraq] [Free Online Dating] [Photo] [Yosemite] [MIPS Linux] [ARM Linux] [Linux Security] [Linux RAID] [Linux SCSI] [Fedora Users] [Linux Resources]