Re: [PATCH] fix non interruptable hang in svn client when connecting
From: Yun Zheng Hu <yunzheng.hu_at_gmail.com>
Date: 2005-08-25 20:47:07 CEST
Yes I can confirm that Karl.
And if we dont set a timeout it will result as Malcolm Rowe said: a
I have made an proof of concept code for testing it on OS X, which
----
/*
Unkillable process proof of concept code. Tested on Mac OS X 10.4.2.
WARNING: If you run this you will most likely have to manually force a
hard reboot.
*/
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
#include <stdio.h>
int main(void)
{
struct sockaddr_in server;
int sock, rc;
sock = socket( AF_INET, SOCK_STREAM, 0 );
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(12345);
server.sin_addr.s_addr = inet_addr("www.google.com");
printf("Try killing this process..\n");
do {
rc = connect(sock,
(const struct sockaddr *)&server,
sizeof(server));
} while (rc == -1);
return 1;
}
-----
On 24 Aug 2005 22:24:03 -0500, kfogel@collab.net <kfogel@collab.net> wrote:
> Yun Zheng Hu <yunzheng.hu@gmail.com> writes:
> > [[[
> > When you connect to a non existing repository, but the host exists,
> > the apr_socket_connect will loop forever somehow, and is NOT
> > interruptable.
> > On OS X this will result in a inresponsive system, which is very bad.
> >
> > How to reproduce:
> > svn co svn://svn.edgewall.com
> >
> > There is no svn server running on that port, so try a CTRL-C to
> > cancel, but its not possible.. it will loop forever. process is not
> > killable on OS X either.
> >
> > I found out that somebody else was having this problem too, but could
> > not find a bug report and neither the fix. The user that was having
> > this same bug can be read on:
> >
> > http://svn.haxx.se/users/archive-2005-07/1027.shtml
> >
> > The following patch will set a timeout of 10 seconds on apr_socket_connect.
> > So if it cant connect it will timeout safely, 10 seconds should be
> > more than enough I think.
> > The patch will also include the port number in the error message, it
> > might be useful or not..
> > ]]]
>
> Thanks for the patch. I have some technical comments below. Also,
> there's no need to use the "[[[ ... ]]]" convention unless you are
> actually putting a log message inside the braces. (You put the main
> body of your message there instead.)
>
> > The patch is very simple, open up:
> > subversion/libsvn_ra_svn/client.c
> >
> > search for: "apr_socket_connect", and change the code to:
> >
> > status = apr_setsocketopt(*sock, APR_SO_TIMEOUT, 10 * APR_USEC_PER_SEC);
> > if (status)
> > return svn_error_wrap_apr(status, _("Can't set timeout"));
> >
> > status = apr_socket_connect(*sock, sa);
> > if (status)
> > return svn_error_wrap_apr(status, _("Can't connect to host '%s' on
> > port %u"),
> > hostname, port);
> >
>
> I think we shouldn't mix the port-number-in-error-message change with
> the timeout change, as they are two unrelated things.
>
> Also, do you know how to generate a real patch, that is, something
> that can be applied using the 'patch' program? Just make your
> modifications and run 'svn diff'. The result will be a patch, in the
> format expected by all open source projects.
>
> Now the technical notes:
>
> apr_setsocketopt() is deprecated, and recommends the use of
> apr_socket_set_opt() instead. However, if you look at the
> documentation for apr_socket_set_opt(), the APR_SO_TIMEOUT option is
> not listed as one of the valid options. Instead, one should use
> apr_socket_set_timeout()! :-)
>
> So that's what I've done in the patch below.
>
> However, I'm not sure we should apply this patch; at least, I'd like
> other developer's thoughts. There already seems to be a default
> timeout, it's just long. It's around 3 minutes, according to my
> tests:
>
> $ time svn co svn://svn.edgewall.com
> subversion/libsvn_ra_svn/client.c:141: (apr_err=110)
> svn: Can't connect to host 'svn.edgewall.com': Connection timed out
>
> real 3m9.548s
> user 0m0.020s
> sys 0m0.008s
>
> $ time svn co svn://svn.edgewall.com
> subversion/libsvn_ra_svn/client.c:141: (apr_err=110)
> svn: Can't connect to host 'svn.edgewall.com': Connection timed out
>
> real 3m9.056s
> user 0m0.022s
> sys 0m0.005s
>
> $
>
> Now, if we lower that timeout, we're rejecting the default chosen by
> APR, without doing anything to solve the root of the problem, which is
> the lack of interruptability. On the other hand, the lack of
> interruptability is sort of our fault, since we handle signals
> ourselves. We have to run our check-cancellation function to actually
> do anything with a signal, and that means we lose whenever we go into
> an APR function like apr_socket_connect() :-(.
>
> I'm not sure what the right answer is here. Should we lower the
> socket timeout to 10 seconds, since we have made apr_socket_connect()
> uninterruptable? Anyone have any thoughts?
>
> Here's the new patch, anyway:
>
> [[[
> Fix a bug whereby connecting to a non-existent repository can cause
> apr_socket_connect() to hang non-interruptably. To reproduce, try
> 'svn co svn://svn.edgewall.com'.
>
> Patch by: Yun Zheng Hu <yunzheng.hu@gmail.com>
> (Tweaked by me to use apr_socket_set_timeout instead of apr_setsocketopt.)
>
> * subversion/libsvn_ra_svn/client.c
> (make_connection): Set socket timeout to 10 seconds.
>
> Yun Zheng Hu's original message:
>
> http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=104587
> From: Yun Zheng Hu <yunzheng.hu@gmail.com>
> To: dev@subversion.tigris.org
> Subject: [PATCH] fix non interruptable hang in svn client when connecting
> Date: Thu, 25 Aug 2005 00:40:07 +0200
> Message-ID: <df84014e05082415405cdd9b13@mail.gmail.com>
> ]]]
>
> Index: subversion/libsvn_ra_svn/client.c
> ===================================================================
> --- subversion/libsvn_ra_svn/client.c (revision 15898)
> +++ subversion/libsvn_ra_svn/client.c (working copy)
> @@ -136,6 +136,10 @@
> if (status)
> return svn_error_wrap_apr(status, _("Can't create socket"));
>
> + status = apr_socket_timeout_set(*sock, 10 * APR_USEC_PER_SEC);
> + if (status)
> + return svn_error_wrap_apr(status, _("Can't set timeout"));
> +
> status = apr_socket_connect(*sock, sa);
> if (status)
> return svn_error_wrap_apr(status, _("Can't connect to host '%s'"),
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Thu Aug 25 20:49:21 2005
|
This is an archived mail posted to the Subversion Dev mailing list.
This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.