Re: Bug report: Git pull hang occasionally
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Dec 21, 2016, 20:59 UTC
- Message-ID
- <xmqq8tr9huc0.fsf@gitster.mtv.corp.google.com>
- In-Reply-To
- <9B7DCFB3-73A4-40DE-8FC6-867C5016EF95@netskope.com>
Kai Zhang <kai@netskope.com> writes:
> 2016/12/20 20:38:10 [error] 9957#0: *687703 FastCGI sent in stderr: "fatal: 'HEAD' is a symref but it is not?" while reading response header from upstream, client: 10.1.0.11, server: server, request: "POST /git/repo_name/.git/git-upload-pack HTTP/1.1", upstream: "fastcgi://unix:/var/run/fcgiwrap.socket:", host: "server"
(Not a solution)
In order to tell the client if HEAD is a symbolic ref and to what underlying ref it points at if it is a symbolic ref, at the very beginning of upload-pack, there is a call to head_ref_namespaced() that uses find_symref(). find_symref() gets "HEAD" and a boolean that says if it is a symbolic ref, but it does not get where the symbolic ref points at, so it does resolve_ref_unsafe() to learn that information.
Between the time head_ref_namespaced() checks the refs database and finds that HEAD is a symbolic ref, and the time find_symref() calls resolve_ref_unsafe() to find out where it leads to, if somebody else updates HEAD, resolve_ref_unsafe() can give an unexpected result, as all of these read-only operations are performed without any locking.
And the unexpected discrepancy is reported by find_symref() as fatal. The server side dies, and somehow that fact is lost between the upload-pack process and the client and somebody in the middle (e.g. fastcgi interface or nginx webserver on the server side, or the remote-curl helper on the client side) keeps the "git fetch" process waiting.
So there seem to be two issues.
- Because of the unlocked read, find_symref() can observe an inconsistent state. Perhaps it should be updated not to die but to retry, expecting that transient inconsistency will go away.
- A fatal error in upload-pack is not reported back to the client to cause it exit is an obvious one, and even if we find a way to make this fatal error in find_symref() not to trigger, fatal errors in other places in the code can trigger the same symptom.