home *** CD-ROM | disk | FTP | other *** search
-
-
-
- Re: ssh often hangs where pserver succeeds
- To: gcc at gcc dot gnu dot org
- Subject: Re: ssh often hangs where pserver succeeds
- From: thospel at mail dot dma dot be (Ton Hospel)
- Date: 5 May 2000 02:20:48 GMT
- Organization: lunix confusion services
- References: <200005030930.CAA04062@gkm-dsl-194.ascend.com> <20000503081408.A22257@lucon.org>
- Xref: Home.Lunix mail.ecgs:34644
-
-
- In article <20000503081408.A22257@lucon.org>, "H . J . Lu" <hjl@lucon.org> writes:
-
- > On Wed, May 03, 2000 at 02:30:55AM -0700, Greg McGary wrote:
- >> FYI...
- >>
- >> I have noticed that cvs over ssh often hangs, especially for
- >> long-running diffs and updates. Running without locks via `cvs -n'
- >> helps for diffs, but doesn't work correctly for updates. On a whim I
- >> reverted to pserver and so far it has succeeded every time where ssh
- >> had been hanging.
- >>
- >> Has anyone else experienced hangs with cvs over ssh?
- >
- > I heard rsync hangs over ssh.
- >
-
- I had the same problem on an rsync where I had extended the protocol a
- bit. (not sure if standard rsync can also trigger it). I traced back the
- rare (happened about 1 in a hundred times) errors to a classic deadlock
- were rsync was blocked trying to write to ssh, and ssh was blocked trying
- to write to rsync. The deadlock is very sensitive to your exact network
- speeds and buffer settings.
-
- Rsync is a pure read then write then read protocol, but ssh does in fact do
- a clean select on stdin/stdout and buffering of pending data. But it forgets
- to put the filedescriptors in non blocking mode. So I tend to call ssh the
- cause (though there's no reason for rsync to not put it's pipes in non-block
- to give the slave program an extra chance).
-
- I never contributed my patch to ssh since I stopped helping them after they
- unfreed their copyright (thereby stealing the code of mine already in it).
-
- Compile the following wrapper, and put it in the same directary as you have
- ssh. Tell your rsync to use this unblock_ssh program. If it solves your
- problem, then you were running into this same deadlock.
-
- ---------------------------
- /* Written by Ton Hospel */
- /* Hereby put under GNU copyleft */
-
- #include <stdio.h>
- #include <string.h>
- #include <strings.h>
- #include <stdlib.h>
- #include <errno.h>
- #ifndef HAVE_NO_UNISTD_H
- # include <unistd.h>
- #endif /* HAVE_NO_UNISTD_H */
- #include <fcntl.h>
-
- static char ssh[] = "ssh";
-
- int main(int argc, char **argv) {
- int rc;
- char *ptr, *work;
-
- rc = fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
- if (rc < 0) {
- fprintf(stderr, "Could not unblock stdin: %s\n", strerror(errno));
- return 1;
- }
- rc = fcntl(fileno(stdout), F_SETFL, O_NONBLOCK);
- if (rc < 0) {
- fprintf(stderr, "Could not unblock stdout: %s\n", strerror(errno));
- return 1;
- }
- rc = fcntl(fileno(stderr), F_SETFL, O_NONBLOCK);
- if (rc < 0) {
- fprintf(stderr, "Could not unblock stderr: %s\n", strerror(errno));
- return 1;
- }
-
- ptr = rindex(argv[0], '/');
- if (ptr == NULL) ptr = argv[0];
- else ptr++;
- work = malloc(ptr-argv[0]+sizeof(ssh));
- if (!work) {
- fprintf(stderr, "Out of memory. Buy more ?\n");
- return 1;
- }
- memcpy(work, argv[0], ptr-argv[0]);
- memcpy(work+(ptr-argv[0]), ssh, sizeof(ssh));
- argv[0] = work;
- rc = execvp(work, argv);
- fprintf(stderr, "Could not exec %.300s: %s\n", work, strerror(errno));
- return rc;
- }
-
-