Re: [RFC][PATCHES] seamless reload
Hi William, On Sat, May 27, 2017 at 12:08:38AM +0200, William Lallemand wrote: > The attached patches provide the "expose-fd listeners" stats socket option and > remove the "no-unused-socket" global option. > > It behaves exactly has Willy explain above minus the master process :-) > > ps: Master Worker patches are coming soon! Cool, thanks! I'm applying them right now. Willy
Re: [RFC][PATCHES] seamless reload
Hi guys, On Fri, May 12, 2017 at 04:26:01PM +0200, Willy Tarreau wrote: > In fact William is currently working on the master-worker model to get rid > of the systemd-wrapper and found some corner cases between this and your > patchset. Nothing particularly difficult, just the fact that he'll need > to pass the path to the previous socket to the new processes during reloads. > > During this investigation it was found that we'd need to be able to say > that a process possibly has no stats socket and that the next one will not > be able to retrieve the FDs. Such information cannot be passed from the > command line since it's a consequence of the config parsing. Thus we thought > it would make sense to have a per-socket option to say whether or not it > would be usable for offering the listening file descriptors, just like we > currently have an administrative level on them (I even seem to remember > that Olivier first asked if we wouldn't need to do this). And suddenly a > few benefits appear when doing this : > - security freaks not willing to expose FDs over the socket would simply > not enable them ; > > - we could restrict the number of processes susceptible of exposing the > FDs simply by playing with the "process" directive on the socket ; that > could also save some system-wide FDs ; > > - the master process could reliably find the socket's path in the conf > (the first one with this new directive enabled), even if it's changed > between reloads ; > > - in the default case (no specific option) we wouldn't change the existing > behaviour so it would not make existing reloads worse. > The attached patches provide the "expose-fd listeners" stats socket option and remove the "no-unused-socket" global option. It behaves exactly has Willy explain above minus the master process :-) ps: Master Worker patches are coming soon! -- William Lallemand >From 5567d977f722e862c6ba56d65118e094ac28735c Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Wed, 24 May 2017 00:57:40 +0200 Subject: [PATCH 1/3] cli: add ACCESS_LVL_MASK to store the access level The current level variable use only 2 bits for storing the 3 access level (user, oper and admin). This patch add a bitmask which allows to use the remaining bits for other usage. --- include/types/global.h | 2 ++ src/cli.c | 32 ++-- src/stats.c| 2 +- src/stick_table.c | 4 ++-- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/include/types/global.h b/include/types/global.h index 57b969d..cd5fda3 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -69,6 +69,8 @@ #define ACCESS_LVL_USER 1 #define ACCESS_LVL_OPER 2 #define ACCESS_LVL_ADMIN3 +#define ACCESS_LVL_MASK 0x3 + /* SSL server verify mode */ enum { diff --git a/src/cli.c b/src/cli.c index 55baee3..cdbaf2b 100644 --- a/src/cli.c +++ b/src/cli.c @@ -217,7 +217,8 @@ static int stats_parse_global(char **args, int section_type, struct proxy *curpx } bind_conf = bind_conf_alloc(global.stats_fe, file, line, args[2], xprt_get(XPRT_RAW)); - bind_conf->level = ACCESS_LVL_OPER; /* default access level */ + bind_conf->level &= ~ACCESS_LVL_MASK; + bind_conf->level |= ACCESS_LVL_OPER; /* default access level */ if (!str2listener(args[2], global.stats_fe, bind_conf, file, line, err)) { memprintf(err, "parsing [%s:%d] : '%s %s' : %s\n", @@ -383,7 +384,7 @@ int cli_has_level(struct appctx *appctx, int level) struct stream_interface *si = appctx->owner; struct stream *s = si_strm(si); - if (strm_li(s)->bind_conf->level < level) { + if ((strm_li(s)->bind_conf->level & ACCESS_LVL_MASK) < level) { appctx->ctx.cli.msg = stats_permission_denied_msg; appctx->st0 = CLI_ST_PRINT; return 0; @@ -790,12 +791,12 @@ static int cli_io_handler_show_cli_sock(struct appctx *appctx) } else continue; - if (bind_conf->level == ACCESS_LVL_USER) - chunk_appendf(&trash, "user "); - else if (bind_conf->level == ACCESS_LVL_OPER) - chunk_appendf(&trash, "operator "); - else if (bind_conf->level == ACCESS_LVL_ADMIN) + if ((bind_conf->level & ACCESS_LVL_MASK) == ACCESS_LVL_ADMIN) chunk_appendf(&trash, "admin "); + else if ((bind_conf->level & ACCESS_LVL_MASK) == ACCESS_LVL_OPER) + chunk_appendf(&trash, "operator "); + else if ((bind_conf->level & ACCESS_LVL_MASK) == ACCESS_LVL_USER) + chunk_appendf(&trash, "user "); else chunk_appendf(&trash, " "); @@ -1000,13 +1001,16 @@ static int bind_parse_level(char **args, int cur_arg, struct proxy *px, struct b return ERR_ALERT | ERR_FATAL; } - if (!strcmp(args[cur_arg+1], "user")) - conf->level = ACCESS_LVL_USER; - else if (!strcmp(args[cur_arg+1], "operator")) - conf->level = ACCESS_LVL_OPER; - else if (!strcmp(args[cur_arg+1], "admin")) - conf->level = ACCESS_LVL_ADMIN; - else { + if (!strcmp(args[cur_arg+1], "
Re: [RFC][PATCHES] seamless reload
Hi Pavlos, Olivier, On Mon, May 08, 2017 at 02:34:05PM +0200, Olivier Houchard wrote: > Hi Pavlos, > > On Sun, May 07, 2017 at 12:05:28AM +0200, Pavlos Parissis wrote: > [...] > > Ignore ignore what I wrote, I am an idiot I am an idiot as I forgot the most > > important bit of the test, to enable the seamless reload by suppling the > > HAPROXY_STATS_SOCKET environment variable:-( > > > > I added to the systemd overwrite file: > > [Service] > > Environment=CONFIG="/etc/lb_engine/haproxy.cfg" > > "HAPROXY_STATS_SOCKET=/run/lb_engine/process-1.sock" > > > > and wrk2 reports ZERO errors where with HAPEE reports ~49. > > > > I am terrible sorry for this stupid mistake. > > > > But, this mistake revealed something interesting. The fact that with the > > latest > > code we have more errors during reload. > > > > @Olivier, great work dude. I am waiting for this to be back-ported to > > HAPEE-1.7r1. > > > > Once again I am sorry for my mistake, > > Pavlos > > > > Thanks a lot for testing ! > This is interesting indeed. My patch may make it worse when not passing > fds via the unix socket, as all processes now keep all sockets opened, even > the one they're not using, maybe it make the window between the last > accept and the close bigger. That's very interesting indeed. In fact it's the window between the last accept and the *last* close, due to processes holding the socket while not being willing to do accept anything on it. > If that is so, then the global option "no-unused-socket" should provide > a comparable error rate. In fact William is currently working on the master-worker model to get rid of the systemd-wrapper and found some corner cases between this and your patchset. Nothing particularly difficult, just the fact that he'll need to pass the path to the previous socket to the new processes during reloads. During this investigation it was found that we'd need to be able to say that a process possibly has no stats socket and that the next one will not be able to retrieve the FDs. Such information cannot be passed from the command line since it's a consequence of the config parsing. Thus we thought it would make sense to have a per-socket option to say whether or not it would be usable for offering the listening file descriptors, just like we currently have an administrative level on them (I even seem to remember that Olivier first asked if we wouldn't need to do this). And suddenly a few benefits appear when doing this : - security freaks not willing to expose FDs over the socket would simply not enable them ; - we could restrict the number of processes susceptible of exposing the FDs simply by playing with the "process" directive on the socket ; that could also save some system-wide FDs ; - the master process could reliably find the socket's path in the conf (the first one with this new directive enabled), even if it's changed between reloads ; - in the default case (no specific option) we wouldn't change the existing behaviour so it would not make existing reloads worse. Pavlos, regarding the backport to your beloved version, that's planned, but as you can see, while the main technical issues have already been sorted out, there will still be a few small integration-specific changes to come, which is why for now it's still on hold until all these details are sorted out once for all. Best regards, Willy
Re: [RFC][PATCHES] seamless reload
Hi Pavlos, On Sun, May 07, 2017 at 12:05:28AM +0200, Pavlos Parissis wrote: [...] > Ignore ignore what I wrote, I am an idiot I am an idiot as I forgot the most > important bit of the test, to enable the seamless reload by suppling the > HAPROXY_STATS_SOCKET environment variable:-( > > I added to the systemd overwrite file: > [Service] > Environment=CONFIG="/etc/lb_engine/haproxy.cfg" > "HAPROXY_STATS_SOCKET=/run/lb_engine/process-1.sock" > > and wrk2 reports ZERO errors where with HAPEE reports ~49. > > I am terrible sorry for this stupid mistake. > > But, this mistake revealed something interesting. The fact that with the > latest > code we have more errors during reload. > > @Olivier, great work dude. I am waiting for this to be back-ported to > HAPEE-1.7r1. > > Once again I am sorry for my mistake, > Pavlos > Thanks a lot for testing ! This is interesting indeed. My patch may make it worse when not passing fds via the unix socket, as all processes now keep all sockets opened, even the one they're not using, maybe it make the window between the last accept and the close bigger. If that is so, then the global option "no-unused-socket" should provide a comparable error rate. Regards, Olivier
Re: [RFC][PATCHES] seamless reload
On 06/05/2017 11:15 μμ, Pavlos Parissis wrote: > On 04/05/2017 01:16 μμ, Olivier Houchard wrote: >> On Thu, May 04, 2017 at 10:03:07AM +, Pierre Cheynier wrote: >>> Hi Olivier, >>> >>> Many thanks for that ! As you know, we are very interested on this topic. >>> We'll test your patches soon for sure. >>> >>> Pierre >> >> Hi Pierre :) >> >> Thanks ! I'm very interested in knowing how well it works for you. >> Maybe we can talk about that around a beer sometime. >> >> Olivier >> > > Hi, > > I finally managed to find time to perform some testing. > > Fristly, let me explain environment. > > Server and generator are on different servers (bare medal) with the same spec, > network interrupts are pinned to all CPUs and irqbalancer daemon is disabled. > Both nodes have 10GbE network interfaces. > > I compared HAPEE with HAProxy using the following versions: > > ### HAProxy > The git SHA isn't mentioned in the output because I created the tarball > with: > > git archive --format=tar --prefix="haproxy-1.8.0/" HEAD | gzip -9 > > haproxy-1.8.0.tar.gz > > as I had to build the rpm using a tar ball, but I used the latest haproxy > at f494977bc1a361c26f8cc0516366ef2662ac9502 commit. > > /usr/sbin/haproxy -vv > HA-Proxy version 1.8-dev1 2017/04/03 > Copyright 2000-2017 Willy Tarreau > > Build options : > TARGET = linux2628 > CPU = generic > CC = gcc > CFLAGS = -DMAX_HOSTNAME_LEN=42 > OPTIONS = USE_LINUX_TPROXY=1 USE_CPU_AFFINITY=1 USE_REGPARM=1 USE_OPENSSL=1 > USE_PCRE=1 USE_PCRE_JIT=1 > > Default settings : > maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200 > > Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 > Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 > OpenSSL library supports TLS extensions : yes > OpenSSL library supports SNI : yes > Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT > IP_FREEBIND > Built with network namespace support. > Built without compression support (neither USE_ZLIB nor USE_SLZ are set). > Compression algorithms supported : identity("identity") > Encrypted password support via crypt(3): yes > Built with PCRE version : 8.32 2012-11-30 > Running on PCRE version : 8.32 2012-11-30 > PCRE library supports JIT : yes > > Available polling systems : > epoll : pref=300, test result OK >poll : pref=200, test result OK > select : pref=150, test result OK > Total: 3 (3 usable), will use epoll. > > Available filters : > [SPOE] spoe > [COMP] compression > [TRACE] trace > > ### HAPEE version > /opt/hapee-1.7/sbin/hapee-lb -vv > HA-Proxy version 1.7.0-1.0.0-163.180 2017/04/10 > Copyright 2000-2016 Willy Tarreau > > Build options : > TARGET = linux2628 > CPU = generic > CC = gcc > CFLAGS = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement > -DMAX_SESS_STKCTR=10 -DSTKTABLE_EXTRA_DATA_TYPES=10 > OPTIONS = USE_MODULES=1 USE_LINUX_SPLICE=1 USE_LINUX_TPROXY=1 USE_SLZ=1 > USE_CPU_AFFINITY=1 USE_REGPARM=1 USE_OPENSSL=1 USE_LUA=1 USE_PCRE= > USE_PCRE_JIT=1 > USE_NS=1 > > Default settings : > maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200 > > Encrypted password support via crypt(3): yes > Built with libslz for stateless compression. > Compression algorithms supported : identity("identity"), deflate("deflate"), > raw-deflate("deflate"), gzip("gzip") > Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 > Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 > OpenSSL library supports TLS extensions : yes > OpenSSL library supports SNI : yes > OpenSSL library supports prefer-server-ciphers : yes > Built with PCRE version : 8.32 2012-11-30 > Running on PCRE version : 8.32 2012-11-30 > PCRE library supports JIT : yes > Built with Lua version : Lua 5.3.3 > Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT > IP_FREEBIND > Built with network namespace support > > Available polling systems : > epoll : pref=300, test result OK >poll : pref=200, test result OK > select : pref=150, test result OK > Total: 3 (3 usable), will use epoll. > > Available filters : > [COMP] compression > [TRACE] trace > [SPOE] spoe > > > The configuration is the same and it is attached. As you can use I use nbproc > >1 > and each process is pinned to different CPU. We have 12 real CPUs as Intel > hyper > threading is disabled, but we only use 10 CPUs for haproxy, the remaining two > CPUs > are left for other daemons to use. > > I experimented with wrk2 and httpress stress tools and decided to use wrk2 for > these tests. I didn't want to use the inject and other tools provided by > haproxy > as I believe using different clients provides higher chances to spot problems. > > In my tests I see that wrk2 reports higher read errors with HAProxy (3890) > than > HAPEE (36). I don't know the meaning of the read error and it could be some >
Re: [RFC][PATCHES] seamless reload
On 04/05/2017 01:16 μμ, Olivier Houchard wrote: > On Thu, May 04, 2017 at 10:03:07AM +, Pierre Cheynier wrote: >> Hi Olivier, >> >> Many thanks for that ! As you know, we are very interested on this topic. >> We'll test your patches soon for sure. >> >> Pierre > > Hi Pierre :) > > Thanks ! I'm very interested in knowing how well it works for you. > Maybe we can talk about that around a beer sometime. > > Olivier > Hi, I finally managed to find time to perform some testing. Fristly, let me explain environment. Server and generator are on different servers (bare medal) with the same spec, network interrupts are pinned to all CPUs and irqbalancer daemon is disabled. Both nodes have 10GbE network interfaces. I compared HAPEE with HAProxy using the following versions: ### HAProxy The git SHA isn't mentioned in the output because I created the tarball with: git archive --format=tar --prefix="haproxy-1.8.0/" HEAD | gzip -9 > haproxy-1.8.0.tar.gz as I had to build the rpm using a tar ball, but I used the latest haproxy at f494977bc1a361c26f8cc0516366ef2662ac9502 commit. /usr/sbin/haproxy -vv HA-Proxy version 1.8-dev1 2017/04/03 Copyright 2000-2017 Willy Tarreau Build options : TARGET = linux2628 CPU = generic CC = gcc CFLAGS = -DMAX_HOSTNAME_LEN=42 OPTIONS = USE_LINUX_TPROXY=1 USE_CPU_AFFINITY=1 USE_REGPARM=1 USE_OPENSSL=1 USE_PCRE=1 USE_PCRE_JIT=1 Default settings : maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200 Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 OpenSSL library supports TLS extensions : yes OpenSSL library supports SNI : yes Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND Built with network namespace support. Built without compression support (neither USE_ZLIB nor USE_SLZ are set). Compression algorithms supported : identity("identity") Encrypted password support via crypt(3): yes Built with PCRE version : 8.32 2012-11-30 Running on PCRE version : 8.32 2012-11-30 PCRE library supports JIT : yes Available polling systems : epoll : pref=300, test result OK poll : pref=200, test result OK select : pref=150, test result OK Total: 3 (3 usable), will use epoll. Available filters : [SPOE] spoe [COMP] compression [TRACE] trace ### HAPEE version /opt/hapee-1.7/sbin/hapee-lb -vv HA-Proxy version 1.7.0-1.0.0-163.180 2017/04/10 Copyright 2000-2016 Willy Tarreau Build options : TARGET = linux2628 CPU = generic CC = gcc CFLAGS = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement -DMAX_SESS_STKCTR=10 -DSTKTABLE_EXTRA_DATA_TYPES=10 OPTIONS = USE_MODULES=1 USE_LINUX_SPLICE=1 USE_LINUX_TPROXY=1 USE_SLZ=1 USE_CPU_AFFINITY=1 USE_REGPARM=1 USE_OPENSSL=1 USE_LUA=1 USE_PCRE= USE_PCRE_JIT=1 USE_NS=1 Default settings : maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200 Encrypted password support via crypt(3): yes Built with libslz for stateless compression. Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip") Built with OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 Running on OpenSSL version : OpenSSL 1.0.1e-fips 11 Feb 2013 OpenSSL library supports TLS extensions : yes OpenSSL library supports SNI : yes OpenSSL library supports prefer-server-ciphers : yes Built with PCRE version : 8.32 2012-11-30 Running on PCRE version : 8.32 2012-11-30 PCRE library supports JIT : yes Built with Lua version : Lua 5.3.3 Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND Built with network namespace support Available polling systems : epoll : pref=300, test result OK poll : pref=200, test result OK select : pref=150, test result OK Total: 3 (3 usable), will use epoll. Available filters : [COMP] compression [TRACE] trace [SPOE] spoe The configuration is the same and it is attached. As you can use I use nbproc >1 and each process is pinned to different CPU. We have 12 real CPUs as Intel hyper threading is disabled, but we only use 10 CPUs for haproxy, the remaining two CPUs are left for other daemons to use. I experimented with wrk2 and httpress stress tools and decided to use wrk2 for these tests. I didn't want to use the inject and other tools provided by haproxy as I believe using different clients provides higher chances to spot problems. In my tests I see that wrk2 reports higher read errors with HAProxy (3890) than HAPEE (36). I don't know the meaning of the read error and it could be some stupidity in the code of wrk2. I am saying this because two years ago we spent four weeks stress testing HAPEE and found out that all open source http stress tool sucks and some of the errors they report are client errors rather server. But, in this case wrk2 was always reporting higher read errors with HAProxy. Below
Re: [RFC][PATCHES] seamless reload
On Thu, May 04, 2017 at 10:03:07AM +, Pierre Cheynier wrote: > Hi Olivier, > > Many thanks for that ! As you know, we are very interested on this topic. > We'll test your patches soon for sure. > > Pierre Hi Pierre :) Thanks ! I'm very interested in knowing how well it works for you. Maybe we can talk about that around a beer sometime. Olivier
RE: [RFC][PATCHES] seamless reload
Hi Olivier, Many thanks for that ! As you know, we are very interested on this topic. We'll test your patches soon for sure. Pierre
Re: [RFC][PATCHES] seamless reload
On 04/19/2017 11:22 AM, Olivier Houchard wrote: very long conversation >> Joining this again a bit late, do you still want me to test it? >> I would like to know if there are any performance impact, but I see that >> Conrad Hoffmann has done all the hard work on this. So, we can conclude that >> we >> don't expect any performance impact. >> >> Once again thanks a lot for your hard work on this. >> @Conrad Hoffmann, thanks a lot for testing this and checking if there is any >> performance impact. >> > > > Hi Pavlos, > > More testing is always appreciated :) > I don't expect any performance impact, but that wouldn't be the first time > I say that and am proven wrong, though as you said with all the testing > Conrad did, I'm fairly confident it should be OK. > > Thanks ! > > Olivier I also think more testing is always very welcome, especially as there are so many different configurations that certain code paths might for example never be executed with the configuration we are running here! Cheers, Conrad -- Conrad Hoffmann Traffic Engineer SoundCloud Ltd. | Rheinsberger Str. 76/77, 10115 Berlin, Germany Managing Director: Alexander Ljung | Incorporated in England & Wales with Company No. 6343600 | Local Branch Office | AG Charlottenburg | HRB 110657B
Re: [RFC][PATCHES] seamless reload
On Wed, Apr 19, 2017 at 09:58:27AM +0200, Pavlos Parissis wrote: > On 13/04/2017 06:18 μμ, Olivier Houchard wrote: > > On Thu, Apr 13, 2017 at 06:00:59PM +0200, Conrad Hoffmann wrote: > >> On 04/13/2017 05:10 PM, Olivier Houchard wrote: > >>> On Thu, Apr 13, 2017 at 04:59:26PM +0200, Conrad Hoffmann wrote: > Sure, here it is ;P > > I now get a segfault (on reload): > > *** Error in `/usr/sbin/haproxy': corrupted double-linked list: > 0x05b511e0 *** > > Here is the backtrace, retrieved from the core file: > > (gdb) bt > #0 0x7f4c92801067 in __GI_raise (sig=sig@entry=6) at > ../nptl/sysdeps/unix/sysv/linux/raise.c:56 > #1 0x7f4c92802448 in __GI_abort () at abort.c:89 > #2 0x7f4c9283f1b4 in __libc_message (do_abort=do_abort@entry=1, > fmt=fmt@entry=0x7f4c92934210 "*** Error in `%s': %s: 0x%s ***\n") at > ../sysdeps/posix/libc_fatal.c:175 > #3 0x7f4c9284498e in malloc_printerr (action=1, str=0x7f4c929302ec > "corrupted double-linked list", ptr=) at malloc.c:4996 > #4 0x7f4c92845923 in _int_free (av=0x7f4c92b71620 , > p=, have_lock=0) at malloc.c:3996 > #5 0x00485850 in tcp_find_compatible_fd (l=0xaaed20) at > src/proto_tcp.c:812 > #6 tcp_bind_listener (listener=0xaaed20, errmsg=0x7ffccc774e10 "", > errlen=100) at src/proto_tcp.c:878 > #7 0x00493ce1 in start_proxies (verbose=0) at src/proxy.c:793 > #8 0x004091ec in main (argc=21, argv=0x7ffccc775168) at > src/haproxy.c:1942 > >>> > >>> Ok, yet another stupid mistake, hopefully the attached patch fixes this :) > >>> > >>> Thanks ! > >>> > >>> Olivier > >> > >> > >> It does indeed! Not only does it work now, the result is impressive! Not a > >> single dropped request even when aggressively reloading under substantial > >> load! > >> > >> You certainly gave me an unexpected early easter present here :) > >> > >> I will now head out, but I am planning on installing a 1.8 version with > >> your patches on our canary pool (which receives a small amount of > >> production traffic to test changes) after the holidays. I will happily test > >> anything else that might be helpful for you. I will also set up a proper > >> load test inside our data center then, but I expect no surprises there (my > >> current tests were done over a VPN link, somewhat limiting the achievable > >> throughput). > >> > >> Once more, thank you so much! This will greatly simplify much of our > >> operations. If there is anything else we can help test, let me know :) > > > > Pfew, at least :) Thanks a lot for your patience, and doing all that > > testing ! > > > > Olivier > > > > > Joining this again a bit late, do you still want me to test it? > I would like to know if there are any performance impact, but I see that > Conrad Hoffmann has done all the hard work on this. So, we can conclude that > we > don't expect any performance impact. > > Once again thanks a lot for your hard work on this. > @Conrad Hoffmann, thanks a lot for testing this and checking if there is any > performance impact. > Hi Pavlos, More testing is always appreciated :) I don't expect any performance impact, but that wouldn't be the first time I say that and am proven wrong, though as you said with all the testing Conrad did, I'm fairly confident it should be OK. Thanks ! Olivier
Re: [RFC][PATCHES] seamless reload
On 13/04/2017 06:18 μμ, Olivier Houchard wrote: > On Thu, Apr 13, 2017 at 06:00:59PM +0200, Conrad Hoffmann wrote: >> On 04/13/2017 05:10 PM, Olivier Houchard wrote: >>> On Thu, Apr 13, 2017 at 04:59:26PM +0200, Conrad Hoffmann wrote: Sure, here it is ;P I now get a segfault (on reload): *** Error in `/usr/sbin/haproxy': corrupted double-linked list: 0x05b511e0 *** Here is the backtrace, retrieved from the core file: (gdb) bt #0 0x7f4c92801067 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 #1 0x7f4c92802448 in __GI_abort () at abort.c:89 #2 0x7f4c9283f1b4 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7f4c92934210 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 #3 0x7f4c9284498e in malloc_printerr (action=1, str=0x7f4c929302ec "corrupted double-linked list", ptr=) at malloc.c:4996 #4 0x7f4c92845923 in _int_free (av=0x7f4c92b71620 , p=, have_lock=0) at malloc.c:3996 #5 0x00485850 in tcp_find_compatible_fd (l=0xaaed20) at src/proto_tcp.c:812 #6 tcp_bind_listener (listener=0xaaed20, errmsg=0x7ffccc774e10 "", errlen=100) at src/proto_tcp.c:878 #7 0x00493ce1 in start_proxies (verbose=0) at src/proxy.c:793 #8 0x004091ec in main (argc=21, argv=0x7ffccc775168) at src/haproxy.c:1942 >>> >>> Ok, yet another stupid mistake, hopefully the attached patch fixes this :) >>> >>> Thanks ! >>> >>> Olivier >> >> >> It does indeed! Not only does it work now, the result is impressive! Not a >> single dropped request even when aggressively reloading under substantial >> load! >> >> You certainly gave me an unexpected early easter present here :) >> >> I will now head out, but I am planning on installing a 1.8 version with >> your patches on our canary pool (which receives a small amount of >> production traffic to test changes) after the holidays. I will happily test >> anything else that might be helpful for you. I will also set up a proper >> load test inside our data center then, but I expect no surprises there (my >> current tests were done over a VPN link, somewhat limiting the achievable >> throughput). >> >> Once more, thank you so much! This will greatly simplify much of our >> operations. If there is anything else we can help test, let me know :) > > Pfew, at least :) Thanks a lot for your patience, and doing all that testing ! > > Olivier > Joining this again a bit late, do you still want me to test it? I would like to know if there are any performance impact, but I see that Conrad Hoffmann has done all the hard work on this. So, we can conclude that we don't expect any performance impact. Once again thanks a lot for your hard work on this. @Conrad Hoffmann, thanks a lot for testing this and checking if there is any performance impact. Cheers, Pavlos signature.asc Description: OpenPGP digital signature
Re: [RFC][PATCHES] seamless reload
On Thu, Apr 13, 2017 at 06:18:59PM +0200, Olivier Houchard wrote: > > Once more, thank you so much! This will greatly simplify much of our > > operations. If there is anything else we can help test, let me know :) > > Pfew, at least :) Thanks a lot for your patience, and doing all that testing ! Yep thanks for the testing and feedback, that's much appreciated. I was also impressed by the efficiency of this change. We've been talking about it for years, having had a few attempts at it in the past and this one was the good one. I've merged the patches already. Great job, thanks guys! Willy
Re: [RFC][PATCHES] seamless reload
On Thu, Apr 13, 2017 at 06:00:59PM +0200, Conrad Hoffmann wrote: > On 04/13/2017 05:10 PM, Olivier Houchard wrote: > > On Thu, Apr 13, 2017 at 04:59:26PM +0200, Conrad Hoffmann wrote: > >> Sure, here it is ;P > >> > >> I now get a segfault (on reload): > >> > >> *** Error in `/usr/sbin/haproxy': corrupted double-linked list: > >> 0x05b511e0 *** > >> > >> Here is the backtrace, retrieved from the core file: > >> > >> (gdb) bt > >> #0 0x7f4c92801067 in __GI_raise (sig=sig@entry=6) at > >> ../nptl/sysdeps/unix/sysv/linux/raise.c:56 > >> #1 0x7f4c92802448 in __GI_abort () at abort.c:89 > >> #2 0x7f4c9283f1b4 in __libc_message (do_abort=do_abort@entry=1, > >> fmt=fmt@entry=0x7f4c92934210 "*** Error in `%s': %s: 0x%s ***\n") at > >> ../sysdeps/posix/libc_fatal.c:175 > >> #3 0x7f4c9284498e in malloc_printerr (action=1, str=0x7f4c929302ec > >> "corrupted double-linked list", ptr=) at malloc.c:4996 > >> #4 0x7f4c92845923 in _int_free (av=0x7f4c92b71620 , > >> p=, have_lock=0) at malloc.c:3996 > >> #5 0x00485850 in tcp_find_compatible_fd (l=0xaaed20) at > >> src/proto_tcp.c:812 > >> #6 tcp_bind_listener (listener=0xaaed20, errmsg=0x7ffccc774e10 "", > >> errlen=100) at src/proto_tcp.c:878 > >> #7 0x00493ce1 in start_proxies (verbose=0) at src/proxy.c:793 > >> #8 0x004091ec in main (argc=21, argv=0x7ffccc775168) at > >> src/haproxy.c:1942 > > > > Ok, yet another stupid mistake, hopefully the attached patch fixes this :) > > > > Thanks ! > > > > Olivier > > > It does indeed! Not only does it work now, the result is impressive! Not a > single dropped request even when aggressively reloading under substantial > load! > > You certainly gave me an unexpected early easter present here :) > > I will now head out, but I am planning on installing a 1.8 version with > your patches on our canary pool (which receives a small amount of > production traffic to test changes) after the holidays. I will happily test > anything else that might be helpful for you. I will also set up a proper > load test inside our data center then, but I expect no surprises there (my > current tests were done over a VPN link, somewhat limiting the achievable > throughput). > > Once more, thank you so much! This will greatly simplify much of our > operations. If there is anything else we can help test, let me know :) Pfew, at least :) Thanks a lot for your patience, and doing all that testing ! Olivier
Re: [RFC][PATCHES] seamless reload
On 04/13/2017 05:10 PM, Olivier Houchard wrote: > On Thu, Apr 13, 2017 at 04:59:26PM +0200, Conrad Hoffmann wrote: >> Sure, here it is ;P >> >> I now get a segfault (on reload): >> >> *** Error in `/usr/sbin/haproxy': corrupted double-linked list: >> 0x05b511e0 *** >> >> Here is the backtrace, retrieved from the core file: >> >> (gdb) bt >> #0 0x7f4c92801067 in __GI_raise (sig=sig@entry=6) at >> ../nptl/sysdeps/unix/sysv/linux/raise.c:56 >> #1 0x7f4c92802448 in __GI_abort () at abort.c:89 >> #2 0x7f4c9283f1b4 in __libc_message (do_abort=do_abort@entry=1, >> fmt=fmt@entry=0x7f4c92934210 "*** Error in `%s': %s: 0x%s ***\n") at >> ../sysdeps/posix/libc_fatal.c:175 >> #3 0x7f4c9284498e in malloc_printerr (action=1, str=0x7f4c929302ec >> "corrupted double-linked list", ptr=) at malloc.c:4996 >> #4 0x7f4c92845923 in _int_free (av=0x7f4c92b71620 , >> p=, have_lock=0) at malloc.c:3996 >> #5 0x00485850 in tcp_find_compatible_fd (l=0xaaed20) at >> src/proto_tcp.c:812 >> #6 tcp_bind_listener (listener=0xaaed20, errmsg=0x7ffccc774e10 "", >> errlen=100) at src/proto_tcp.c:878 >> #7 0x00493ce1 in start_proxies (verbose=0) at src/proxy.c:793 >> #8 0x004091ec in main (argc=21, argv=0x7ffccc775168) at >> src/haproxy.c:1942 > > Ok, yet another stupid mistake, hopefully the attached patch fixes this :) > > Thanks ! > > Olivier It does indeed! Not only does it work now, the result is impressive! Not a single dropped request even when aggressively reloading under substantial load! You certainly gave me an unexpected early easter present here :) I will now head out, but I am planning on installing a 1.8 version with your patches on our canary pool (which receives a small amount of production traffic to test changes) after the holidays. I will happily test anything else that might be helpful for you. I will also set up a proper load test inside our data center then, but I expect no surprises there (my current tests were done over a VPN link, somewhat limiting the achievable throughput). Once more, thank you so much! This will greatly simplify much of our operations. If there is anything else we can help test, let me know :) Cheers, Conrad -- Conrad Hoffmann Traffic Engineer SoundCloud Ltd. | Rheinsberger Str. 76/77, 10115 Berlin, Germany Managing Director: Alexander Ljung | Incorporated in England & Wales with Company No. 6343600 | Local Branch Office | AG Charlottenburg | HRB 110657B
Re: [RFC][PATCHES] seamless reload
On Thu, Apr 13, 2017 at 04:59:26PM +0200, Conrad Hoffmann wrote: > Sure, here it is ;P > > I now get a segfault (on reload): > > *** Error in `/usr/sbin/haproxy': corrupted double-linked list: > 0x05b511e0 *** > > Here is the backtrace, retrieved from the core file: > > (gdb) bt > #0 0x7f4c92801067 in __GI_raise (sig=sig@entry=6) at > ../nptl/sysdeps/unix/sysv/linux/raise.c:56 > #1 0x7f4c92802448 in __GI_abort () at abort.c:89 > #2 0x7f4c9283f1b4 in __libc_message (do_abort=do_abort@entry=1, > fmt=fmt@entry=0x7f4c92934210 "*** Error in `%s': %s: 0x%s ***\n") at > ../sysdeps/posix/libc_fatal.c:175 > #3 0x7f4c9284498e in malloc_printerr (action=1, str=0x7f4c929302ec > "corrupted double-linked list", ptr=) at malloc.c:4996 > #4 0x7f4c92845923 in _int_free (av=0x7f4c92b71620 , > p=, have_lock=0) at malloc.c:3996 > #5 0x00485850 in tcp_find_compatible_fd (l=0xaaed20) at > src/proto_tcp.c:812 > #6 tcp_bind_listener (listener=0xaaed20, errmsg=0x7ffccc774e10 "", > errlen=100) at src/proto_tcp.c:878 > #7 0x00493ce1 in start_proxies (verbose=0) at src/proxy.c:793 > #8 0x004091ec in main (argc=21, argv=0x7ffccc775168) at > src/haproxy.c:1942 Ok, yet another stupid mistake, hopefully the attached patch fixes this :) Thanks ! Olivier >From 7c7fe0c00129d60617cba786cbec7bbdd9ce08f8 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Thu, 13 Apr 2017 17:06:53 +0200 Subject: [PATCH 12/12] BUG/MINOR: Properly remove the xfer_sock from the linked list. Doubly linked list are hard to get right. --- src/proto_tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/proto_tcp.c b/src/proto_tcp.c index f558f00..57d6fc1 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -806,7 +806,7 @@ static int tcp_find_compatible_fd(struct listener *l) if (xfer_sock->prev) xfer_sock->prev->next = xfer_sock->next; if (xfer_sock->next) - xfer_sock->next->prev = xfer_sock->next->prev; + xfer_sock->next->prev = xfer_sock->prev; free(xfer_sock->iface); free(xfer_sock->namespace); free(xfer_sock); -- 2.9.3
Re: [RFC][PATCHES] seamless reload
On 04/13/2017 03:50 PM, Olivier Houchard wrote: > On Thu, Apr 13, 2017 at 03:06:47PM +0200, Conrad Hoffmann wrote: >> >> >> On 04/13/2017 02:28 PM, Olivier Houchard wrote: >>> On Thu, Apr 13, 2017 at 12:59:38PM +0200, Conrad Hoffmann wrote: On 04/13/2017 11:31 AM, Olivier Houchard wrote: > On Thu, Apr 13, 2017 at 11:17:45AM +0200, Conrad Hoffmann wrote: >> Hi Olivier, >> >> On 04/12/2017 06:09 PM, Olivier Houchard wrote: >>> On Wed, Apr 12, 2017 at 05:50:54PM +0200, Olivier Houchard wrote: On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: > Hi again, > > so I tried to get this to work, but didn't manage yet. I also don't > quite > understand how this is supposed to work. The first haproxy process is > started _without_ the -x option, is that correct? Where does that > instance > ever create the socket for transfer to later instances? > > I have it working now insofar that on reload, subsequent instances are > spawned with the -x option, but they'll just complain that they can't > get > anything from the unix socket (because, for all I can tell, it's not > there?). I also can't see the relevant code path where this socket > gets > created, but I didn't have time to read all of it yet. > > Am I doing something wrong? Did anyone get this to work with the > systemd-wrapper so far? > > Also, but this might be a coincidence, my test setup takes a huge > performance penalty just by applying your patches (without any > reloading > whatsoever). Did this happen to anybody else? I'll send some numbers > and > more details tomorrow. > Ok I can confirm the performance issues, I'm investigating. >>> >>> Found it, I was messing with SO_LINGER when I shouldn't have been. >> >> >> >> thanks a lot, I can confirm that the performance regression seems to be >> gone! >> >> I am still having the other (conceptual) problem, though. Sorry if this >> is >> just me holding it wrong or something, it's been a while since I dug >> through the internals of haproxy. >> >> So, as I mentioned before, we use nbproc (12) and the systemd-wrapper, >> which in turn starts haproxy in daemon mode, giving us a process tree >> like >> this (path and file names shortened for brevity): >> >> \_ /u/s/haproxy-systemd-wrapper -f ./hap.cfg -p /v/r/hap.pid >> \_ /u/s/haproxy-master >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> >> Now, in our config file, we have something like this: >> >> # expose admin socket for each process >> stats socket ${STATS_ADDR} level admin process 1 >> stats socket ${STATS_ADDR}-2 level admin process 2 >> stats socket ${STATS_ADDR}-3 level admin process 3 >> stats socket ${STATS_ADDR}-4 level admin process 4 >> stats socket ${STATS_ADDR}-5 level admin process 5 >> stats socket ${STATS_ADDR}-6 level admin process 6 >> stats socket ${STATS_ADDR}-7 level admin process 7 >> stats socket ${STATS_ADDR}-8 level admin process 8 >> stats socket ${STATS_ADDR}-9 level admin process 9 >> stats socket ${STATS_ADDR}-10 level admin process 10 >> stats socket ${STATS_ADDR}-11 level admin process 11 >> stats socket ${STATS_ADDR}-12 level admin process 12 >> >> Basically, we have a dedicate admin socket for each ("real") process, as >> we >> need to be able to talk to each process individually. So I was wondering: >> which admin socket should I pass as HAPROXY_STATS_SOCKET? I initially >> thought it would have to be a special stats socket in the haproxy-master >> process (which we currently don't have), but as far as I can tell from >> the >> output of `lsof` the haproxy-master process doesn't even hold any FDs >> anymore. Will this setup currently work with your patches at all? Do I >> need >> to add a stats socket to the master process? Or would this require a list >> of stats sockets to be passed, similar t
Re: [RFC][PATCHES] seamless reload
On Thu, Apr 13, 2017 at 03:06:47PM +0200, Conrad Hoffmann wrote: > > > On 04/13/2017 02:28 PM, Olivier Houchard wrote: > > On Thu, Apr 13, 2017 at 12:59:38PM +0200, Conrad Hoffmann wrote: > >> On 04/13/2017 11:31 AM, Olivier Houchard wrote: > >>> On Thu, Apr 13, 2017 at 11:17:45AM +0200, Conrad Hoffmann wrote: > Hi Olivier, > > On 04/12/2017 06:09 PM, Olivier Houchard wrote: > > On Wed, Apr 12, 2017 at 05:50:54PM +0200, Olivier Houchard wrote: > >> On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: > >>> Hi again, > >>> > >>> so I tried to get this to work, but didn't manage yet. I also don't > >>> quite > >>> understand how this is supposed to work. The first haproxy process is > >>> started _without_ the -x option, is that correct? Where does that > >>> instance > >>> ever create the socket for transfer to later instances? > >>> > >>> I have it working now insofar that on reload, subsequent instances are > >>> spawned with the -x option, but they'll just complain that they can't > >>> get > >>> anything from the unix socket (because, for all I can tell, it's not > >>> there?). I also can't see the relevant code path where this socket > >>> gets > >>> created, but I didn't have time to read all of it yet. > >>> > >>> Am I doing something wrong? Did anyone get this to work with the > >>> systemd-wrapper so far? > >>> > >>> Also, but this might be a coincidence, my test setup takes a huge > >>> performance penalty just by applying your patches (without any > >>> reloading > >>> whatsoever). Did this happen to anybody else? I'll send some numbers > >>> and > >>> more details tomorrow. > >>> > >> > >> Ok I can confirm the performance issues, I'm investigating. > >> > > > > Found it, I was messing with SO_LINGER when I shouldn't have been. > > > > thanks a lot, I can confirm that the performance regression seems to be > gone! > > I am still having the other (conceptual) problem, though. Sorry if this > is > just me holding it wrong or something, it's been a while since I dug > through the internals of haproxy. > > So, as I mentioned before, we use nbproc (12) and the systemd-wrapper, > which in turn starts haproxy in daemon mode, giving us a process tree > like > this (path and file names shortened for brevity): > > \_ /u/s/haproxy-systemd-wrapper -f ./hap.cfg -p /v/r/hap.pid > \_ /u/s/haproxy-master > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > > Now, in our config file, we have something like this: > > # expose admin socket for each process > stats socket ${STATS_ADDR} level admin process 1 > stats socket ${STATS_ADDR}-2 level admin process 2 > stats socket ${STATS_ADDR}-3 level admin process 3 > stats socket ${STATS_ADDR}-4 level admin process 4 > stats socket ${STATS_ADDR}-5 level admin process 5 > stats socket ${STATS_ADDR}-6 level admin process 6 > stats socket ${STATS_ADDR}-7 level admin process 7 > stats socket ${STATS_ADDR}-8 level admin process 8 > stats socket ${STATS_ADDR}-9 level admin process 9 > stats socket ${STATS_ADDR}-10 level admin process 10 > stats socket ${STATS_ADDR}-11 level admin process 11 > stats socket ${STATS_ADDR}-12 level admin process 12 > > Basically, we have a dedicate admin socket for each ("real") process, as > we > need to be able to talk to each process individually. So I was wondering: > which admin socket should I pass as HAPROXY_STATS_SOCKET? I initially > thought it would have to be a special stats socket in the haproxy-master > process (which we currently don't have), but as far as I can tell from > the > output of `lsof` the haproxy-master process doesn't even hold any FDs > anymore. Will this setup currently work with your patches at all? Do I > need > to add a stats socket to the master process? Or would this require a list > of stats sockets to be passed, similar to the list of PIDs that gets > passed > to
Re: [RFC][PATCHES] seamless reload
On 04/13/2017 02:28 PM, Olivier Houchard wrote: > On Thu, Apr 13, 2017 at 12:59:38PM +0200, Conrad Hoffmann wrote: >> On 04/13/2017 11:31 AM, Olivier Houchard wrote: >>> On Thu, Apr 13, 2017 at 11:17:45AM +0200, Conrad Hoffmann wrote: Hi Olivier, On 04/12/2017 06:09 PM, Olivier Houchard wrote: > On Wed, Apr 12, 2017 at 05:50:54PM +0200, Olivier Houchard wrote: >> On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: >>> Hi again, >>> >>> so I tried to get this to work, but didn't manage yet. I also don't >>> quite >>> understand how this is supposed to work. The first haproxy process is >>> started _without_ the -x option, is that correct? Where does that >>> instance >>> ever create the socket for transfer to later instances? >>> >>> I have it working now insofar that on reload, subsequent instances are >>> spawned with the -x option, but they'll just complain that they can't >>> get >>> anything from the unix socket (because, for all I can tell, it's not >>> there?). I also can't see the relevant code path where this socket gets >>> created, but I didn't have time to read all of it yet. >>> >>> Am I doing something wrong? Did anyone get this to work with the >>> systemd-wrapper so far? >>> >>> Also, but this might be a coincidence, my test setup takes a huge >>> performance penalty just by applying your patches (without any reloading >>> whatsoever). Did this happen to anybody else? I'll send some numbers and >>> more details tomorrow. >>> >> >> Ok I can confirm the performance issues, I'm investigating. >> > > Found it, I was messing with SO_LINGER when I shouldn't have been. thanks a lot, I can confirm that the performance regression seems to be gone! I am still having the other (conceptual) problem, though. Sorry if this is just me holding it wrong or something, it's been a while since I dug through the internals of haproxy. So, as I mentioned before, we use nbproc (12) and the systemd-wrapper, which in turn starts haproxy in daemon mode, giving us a process tree like this (path and file names shortened for brevity): \_ /u/s/haproxy-systemd-wrapper -f ./hap.cfg -p /v/r/hap.pid \_ /u/s/haproxy-master \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds Now, in our config file, we have something like this: # expose admin socket for each process stats socket ${STATS_ADDR} level admin process 1 stats socket ${STATS_ADDR}-2 level admin process 2 stats socket ${STATS_ADDR}-3 level admin process 3 stats socket ${STATS_ADDR}-4 level admin process 4 stats socket ${STATS_ADDR}-5 level admin process 5 stats socket ${STATS_ADDR}-6 level admin process 6 stats socket ${STATS_ADDR}-7 level admin process 7 stats socket ${STATS_ADDR}-8 level admin process 8 stats socket ${STATS_ADDR}-9 level admin process 9 stats socket ${STATS_ADDR}-10 level admin process 10 stats socket ${STATS_ADDR}-11 level admin process 11 stats socket ${STATS_ADDR}-12 level admin process 12 Basically, we have a dedicate admin socket for each ("real") process, as we need to be able to talk to each process individually. So I was wondering: which admin socket should I pass as HAPROXY_STATS_SOCKET? I initially thought it would have to be a special stats socket in the haproxy-master process (which we currently don't have), but as far as I can tell from the output of `lsof` the haproxy-master process doesn't even hold any FDs anymore. Will this setup currently work with your patches at all? Do I need to add a stats socket to the master process? Or would this require a list of stats sockets to be passed, similar to the list of PIDs that gets passed to new haproxy instances, so that each process can talk to the one from which it is taking over the socket(s)? In case I need a stats socket for the master process, what would be the directive to create it? >>> >>> Hi Conrad, >>> >>> Any of those sockets will do. Each process are made to keep all the >>> listening socket
Re: [RFC][PATCHES] seamless reload
On Thu, Apr 13, 2017 at 12:59:38PM +0200, Conrad Hoffmann wrote: > On 04/13/2017 11:31 AM, Olivier Houchard wrote: > > On Thu, Apr 13, 2017 at 11:17:45AM +0200, Conrad Hoffmann wrote: > >> Hi Olivier, > >> > >> On 04/12/2017 06:09 PM, Olivier Houchard wrote: > >>> On Wed, Apr 12, 2017 at 05:50:54PM +0200, Olivier Houchard wrote: > On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: > > Hi again, > > > > so I tried to get this to work, but didn't manage yet. I also don't > > quite > > understand how this is supposed to work. The first haproxy process is > > started _without_ the -x option, is that correct? Where does that > > instance > > ever create the socket for transfer to later instances? > > > > I have it working now insofar that on reload, subsequent instances are > > spawned with the -x option, but they'll just complain that they can't > > get > > anything from the unix socket (because, for all I can tell, it's not > > there?). I also can't see the relevant code path where this socket gets > > created, but I didn't have time to read all of it yet. > > > > Am I doing something wrong? Did anyone get this to work with the > > systemd-wrapper so far? > > > > Also, but this might be a coincidence, my test setup takes a huge > > performance penalty just by applying your patches (without any reloading > > whatsoever). Did this happen to anybody else? I'll send some numbers and > > more details tomorrow. > > > > Ok I can confirm the performance issues, I'm investigating. > > >>> > >>> Found it, I was messing with SO_LINGER when I shouldn't have been. > >> > >> > >> > >> thanks a lot, I can confirm that the performance regression seems to be > >> gone! > >> > >> I am still having the other (conceptual) problem, though. Sorry if this is > >> just me holding it wrong or something, it's been a while since I dug > >> through the internals of haproxy. > >> > >> So, as I mentioned before, we use nbproc (12) and the systemd-wrapper, > >> which in turn starts haproxy in daemon mode, giving us a process tree like > >> this (path and file names shortened for brevity): > >> > >> \_ /u/s/haproxy-systemd-wrapper -f ./hap.cfg -p /v/r/hap.pid > >> \_ /u/s/haproxy-master > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > >> > >> Now, in our config file, we have something like this: > >> > >> # expose admin socket for each process > >> stats socket ${STATS_ADDR} level admin process 1 > >> stats socket ${STATS_ADDR}-2 level admin process 2 > >> stats socket ${STATS_ADDR}-3 level admin process 3 > >> stats socket ${STATS_ADDR}-4 level admin process 4 > >> stats socket ${STATS_ADDR}-5 level admin process 5 > >> stats socket ${STATS_ADDR}-6 level admin process 6 > >> stats socket ${STATS_ADDR}-7 level admin process 7 > >> stats socket ${STATS_ADDR}-8 level admin process 8 > >> stats socket ${STATS_ADDR}-9 level admin process 9 > >> stats socket ${STATS_ADDR}-10 level admin process 10 > >> stats socket ${STATS_ADDR}-11 level admin process 11 > >> stats socket ${STATS_ADDR}-12 level admin process 12 > >> > >> Basically, we have a dedicate admin socket for each ("real") process, as we > >> need to be able to talk to each process individually. So I was wondering: > >> which admin socket should I pass as HAPROXY_STATS_SOCKET? I initially > >> thought it would have to be a special stats socket in the haproxy-master > >> process (which we currently don't have), but as far as I can tell from the > >> output of `lsof` the haproxy-master process doesn't even hold any FDs > >> anymore. Will this setup currently work with your patches at all? Do I need > >> to add a stats socket to the master process? Or would this require a list > >> of stats sockets to be passed, similar to the list of PIDs that gets passed > >> to new haproxy instances, so that each process can talk to the one from > >> which it is taking over the socket(s)? In case I need a stats socket for > >> the master process, what would be the directive to create it? > >> > > > > Hi Conrad, > > > > Any of those sockets will do. Each process are made to keep all the > > listening sockets opened, even if the proxy is not bound to that sp
Re: [RFC][PATCHES] seamless reload
On 04/13/2017 11:31 AM, Olivier Houchard wrote: > On Thu, Apr 13, 2017 at 11:17:45AM +0200, Conrad Hoffmann wrote: >> Hi Olivier, >> >> On 04/12/2017 06:09 PM, Olivier Houchard wrote: >>> On Wed, Apr 12, 2017 at 05:50:54PM +0200, Olivier Houchard wrote: On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: > Hi again, > > so I tried to get this to work, but didn't manage yet. I also don't quite > understand how this is supposed to work. The first haproxy process is > started _without_ the -x option, is that correct? Where does that instance > ever create the socket for transfer to later instances? > > I have it working now insofar that on reload, subsequent instances are > spawned with the -x option, but they'll just complain that they can't get > anything from the unix socket (because, for all I can tell, it's not > there?). I also can't see the relevant code path where this socket gets > created, but I didn't have time to read all of it yet. > > Am I doing something wrong? Did anyone get this to work with the > systemd-wrapper so far? > > Also, but this might be a coincidence, my test setup takes a huge > performance penalty just by applying your patches (without any reloading > whatsoever). Did this happen to anybody else? I'll send some numbers and > more details tomorrow. > Ok I can confirm the performance issues, I'm investigating. >>> >>> Found it, I was messing with SO_LINGER when I shouldn't have been. >> >> >> >> thanks a lot, I can confirm that the performance regression seems to be gone! >> >> I am still having the other (conceptual) problem, though. Sorry if this is >> just me holding it wrong or something, it's been a while since I dug >> through the internals of haproxy. >> >> So, as I mentioned before, we use nbproc (12) and the systemd-wrapper, >> which in turn starts haproxy in daemon mode, giving us a process tree like >> this (path and file names shortened for brevity): >> >> \_ /u/s/haproxy-systemd-wrapper -f ./hap.cfg -p /v/r/hap.pid >> \_ /u/s/haproxy-master >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds >> >> Now, in our config file, we have something like this: >> >> # expose admin socket for each process >> stats socket ${STATS_ADDR} level admin process 1 >> stats socket ${STATS_ADDR}-2 level admin process 2 >> stats socket ${STATS_ADDR}-3 level admin process 3 >> stats socket ${STATS_ADDR}-4 level admin process 4 >> stats socket ${STATS_ADDR}-5 level admin process 5 >> stats socket ${STATS_ADDR}-6 level admin process 6 >> stats socket ${STATS_ADDR}-7 level admin process 7 >> stats socket ${STATS_ADDR}-8 level admin process 8 >> stats socket ${STATS_ADDR}-9 level admin process 9 >> stats socket ${STATS_ADDR}-10 level admin process 10 >> stats socket ${STATS_ADDR}-11 level admin process 11 >> stats socket ${STATS_ADDR}-12 level admin process 12 >> >> Basically, we have a dedicate admin socket for each ("real") process, as we >> need to be able to talk to each process individually. So I was wondering: >> which admin socket should I pass as HAPROXY_STATS_SOCKET? I initially >> thought it would have to be a special stats socket in the haproxy-master >> process (which we currently don't have), but as far as I can tell from the >> output of `lsof` the haproxy-master process doesn't even hold any FDs >> anymore. Will this setup currently work with your patches at all? Do I need >> to add a stats socket to the master process? Or would this require a list >> of stats sockets to be passed, similar to the list of PIDs that gets passed >> to new haproxy instances, so that each process can talk to the one from >> which it is taking over the socket(s)? In case I need a stats socket for >> the master process, what would be the directive to create it? >> > > Hi Conrad, > > Any of those sockets will do. Each process are made to keep all the > listening sockets opened, even if the proxy is not bound to that specific > process, justly so that it can be transferred via the unix socket. > > Regards, > > Olivier Thanks, I am finally starting to understand, but I think there still might be a problem. I didn't see that initially, but when I use one of the processes existing admin sockets it sti
Re: [RFC][PATCHES] seamless reload
On Thu, Apr 13, 2017 at 11:17:45AM +0200, Conrad Hoffmann wrote: > Hi Olivier, > > On 04/12/2017 06:09 PM, Olivier Houchard wrote: > > On Wed, Apr 12, 2017 at 05:50:54PM +0200, Olivier Houchard wrote: > >> On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: > >>> Hi again, > >>> > >>> so I tried to get this to work, but didn't manage yet. I also don't quite > >>> understand how this is supposed to work. The first haproxy process is > >>> started _without_ the -x option, is that correct? Where does that instance > >>> ever create the socket for transfer to later instances? > >>> > >>> I have it working now insofar that on reload, subsequent instances are > >>> spawned with the -x option, but they'll just complain that they can't get > >>> anything from the unix socket (because, for all I can tell, it's not > >>> there?). I also can't see the relevant code path where this socket gets > >>> created, but I didn't have time to read all of it yet. > >>> > >>> Am I doing something wrong? Did anyone get this to work with the > >>> systemd-wrapper so far? > >>> > >>> Also, but this might be a coincidence, my test setup takes a huge > >>> performance penalty just by applying your patches (without any reloading > >>> whatsoever). Did this happen to anybody else? I'll send some numbers and > >>> more details tomorrow. > >>> > >> > >> Ok I can confirm the performance issues, I'm investigating. > >> > > > > Found it, I was messing with SO_LINGER when I shouldn't have been. > > > > thanks a lot, I can confirm that the performance regression seems to be gone! > > I am still having the other (conceptual) problem, though. Sorry if this is > just me holding it wrong or something, it's been a while since I dug > through the internals of haproxy. > > So, as I mentioned before, we use nbproc (12) and the systemd-wrapper, > which in turn starts haproxy in daemon mode, giving us a process tree like > this (path and file names shortened for brevity): > > \_ /u/s/haproxy-systemd-wrapper -f ./hap.cfg -p /v/r/hap.pid > \_ /u/s/haproxy-master > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds > > Now, in our config file, we have something like this: > > # expose admin socket for each process > stats socket ${STATS_ADDR} level admin process 1 > stats socket ${STATS_ADDR}-2 level admin process 2 > stats socket ${STATS_ADDR}-3 level admin process 3 > stats socket ${STATS_ADDR}-4 level admin process 4 > stats socket ${STATS_ADDR}-5 level admin process 5 > stats socket ${STATS_ADDR}-6 level admin process 6 > stats socket ${STATS_ADDR}-7 level admin process 7 > stats socket ${STATS_ADDR}-8 level admin process 8 > stats socket ${STATS_ADDR}-9 level admin process 9 > stats socket ${STATS_ADDR}-10 level admin process 10 > stats socket ${STATS_ADDR}-11 level admin process 11 > stats socket ${STATS_ADDR}-12 level admin process 12 > > Basically, we have a dedicate admin socket for each ("real") process, as we > need to be able to talk to each process individually. So I was wondering: > which admin socket should I pass as HAPROXY_STATS_SOCKET? I initially > thought it would have to be a special stats socket in the haproxy-master > process (which we currently don't have), but as far as I can tell from the > output of `lsof` the haproxy-master process doesn't even hold any FDs > anymore. Will this setup currently work with your patches at all? Do I need > to add a stats socket to the master process? Or would this require a list > of stats sockets to be passed, similar to the list of PIDs that gets passed > to new haproxy instances, so that each process can talk to the one from > which it is taking over the socket(s)? In case I need a stats socket for > the master process, what would be the directive to create it? > Hi Conrad, Any of those sockets will do. Each process are made to keep all the listening sockets opened, even if the proxy is not bound to that specific process, justly so that it can be transferred via the unix socket. Regards, Olivier
Re: [RFC][PATCHES] seamless reload
Hi Olivier, On 04/12/2017 06:09 PM, Olivier Houchard wrote: > On Wed, Apr 12, 2017 at 05:50:54PM +0200, Olivier Houchard wrote: >> On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: >>> Hi again, >>> >>> so I tried to get this to work, but didn't manage yet. I also don't quite >>> understand how this is supposed to work. The first haproxy process is >>> started _without_ the -x option, is that correct? Where does that instance >>> ever create the socket for transfer to later instances? >>> >>> I have it working now insofar that on reload, subsequent instances are >>> spawned with the -x option, but they'll just complain that they can't get >>> anything from the unix socket (because, for all I can tell, it's not >>> there?). I also can't see the relevant code path where this socket gets >>> created, but I didn't have time to read all of it yet. >>> >>> Am I doing something wrong? Did anyone get this to work with the >>> systemd-wrapper so far? >>> >>> Also, but this might be a coincidence, my test setup takes a huge >>> performance penalty just by applying your patches (without any reloading >>> whatsoever). Did this happen to anybody else? I'll send some numbers and >>> more details tomorrow. >>> >> >> Ok I can confirm the performance issues, I'm investigating. >> > > Found it, I was messing with SO_LINGER when I shouldn't have been. thanks a lot, I can confirm that the performance regression seems to be gone! I am still having the other (conceptual) problem, though. Sorry if this is just me holding it wrong or something, it's been a while since I dug through the internals of haproxy. So, as I mentioned before, we use nbproc (12) and the systemd-wrapper, which in turn starts haproxy in daemon mode, giving us a process tree like this (path and file names shortened for brevity): \_ /u/s/haproxy-systemd-wrapper -f ./hap.cfg -p /v/r/hap.pid \_ /u/s/haproxy-master \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds \_ /u/s/haproxy -f ./hap.cfg -p /v/r/hap.pid -Ds Now, in our config file, we have something like this: # expose admin socket for each process stats socket ${STATS_ADDR} level admin process 1 stats socket ${STATS_ADDR}-2 level admin process 2 stats socket ${STATS_ADDR}-3 level admin process 3 stats socket ${STATS_ADDR}-4 level admin process 4 stats socket ${STATS_ADDR}-5 level admin process 5 stats socket ${STATS_ADDR}-6 level admin process 6 stats socket ${STATS_ADDR}-7 level admin process 7 stats socket ${STATS_ADDR}-8 level admin process 8 stats socket ${STATS_ADDR}-9 level admin process 9 stats socket ${STATS_ADDR}-10 level admin process 10 stats socket ${STATS_ADDR}-11 level admin process 11 stats socket ${STATS_ADDR}-12 level admin process 12 Basically, we have a dedicate admin socket for each ("real") process, as we need to be able to talk to each process individually. So I was wondering: which admin socket should I pass as HAPROXY_STATS_SOCKET? I initially thought it would have to be a special stats socket in the haproxy-master process (which we currently don't have), but as far as I can tell from the output of `lsof` the haproxy-master process doesn't even hold any FDs anymore. Will this setup currently work with your patches at all? Do I need to add a stats socket to the master process? Or would this require a list of stats sockets to be passed, similar to the list of PIDs that gets passed to new haproxy instances, so that each process can talk to the one from which it is taking over the socket(s)? In case I need a stats socket for the master process, what would be the directive to create it? Thanks a lot, Conrad -- Conrad Hoffmann Traffic Engineer SoundCloud Ltd. | Rheinsberger Str. 76/77, 10115 Berlin, Germany Managing Director: Alexander Ljung | Incorporated in England & Wales with Company No. 6343600 | Local Branch Office | AG Charlottenburg | HRB 110657B
Re: [RFC][PATCHES] seamless reload
On Wed, Apr 12, 2017 at 07:41:43PM +0200, Olivier Houchard wrote: > + if (default_tcp_maxseg == -1) { > + default_tcp_maxseg = -2; > + fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); > + if (fd < 0) > + Warning("Failed to create a temporary socket!\n"); > + else { > + if (getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, > &default_tcp_maxseg, > + &ready_len) == -1) > + Warning("Failed to get the default value of > TCP_MAXSEG\n"); Olivier, you're missing a close(fd) here, it'll leak this fd. > + } > + } > + if (default_tcp6_maxseg == -1) { > + default_tcp6_maxseg = -2; > + fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); > + if (fd >= 0) { > + if (getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, > &default_tcp6_maxseg, > + &ready_len) == -1) > + Warning("Failed ot get the default value of > TCP_MAXSEG for IPv6\n"); > + close(fd); > + } > + } > +#endif > + > (...) > + getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &tmpmaxseg, &len); > + if (tmpmaxseg != defaultmss && > + setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, > + &defaultmss, sizeof(defaultmss)) == -1) { Please fix the alignment for the argument here, it's a bit confusing :-) Otherwise looks good. I think it was a good idea to create temporary sockets to retrieve some default settings. That may be something we could generalize to guess other parameters or capabilities if needed in the future. For example we could use this to detect whether or not IPv6 is supported and emit errors only once instead of every bind line. Another use case is to always know the MSS applied to a listening socket in order to automatically adjust the SSL maxrecord instead of assuming 1460 by default. Over time we might find other use cases. Cheers, Willy
Re: [RFC][PATCHES] seamless reload
On Wed, Apr 12, 2017 at 11:19:37AM -0700, Steven Davidovitz wrote: > I had a problem testing it on Mac OS X, because cmsghdr is aligned to 4 > bytes. I changed the CMSG_ALIGN(sizeof(struct cmsghdr)) call to CMSG_LEN(0) > to fix it. > Oh right, I'll change that. Thanks a lot ! Olivier
Re: [RFC][PATCHES] seamless reload
I had a problem testing it on Mac OS X, because cmsghdr is aligned to 4 bytes. I changed the CMSG_ALIGN(sizeof(struct cmsghdr)) call to CMSG_LEN(0) to fix it. On Wed, Apr 12, 2017 at 10:41 AM, Olivier Houchard wrote: > Yet another patch, on top of the previous ones. > This one tries to get the default value of TCP_MAXSEG by creating a > temporary > TCP socket, so that one can remove the "mss" entry from its configuration > file, > and reset the mss value for any transferred socket from the old process. > > Olivier >
Re: [RFC][PATCHES] seamless reload
Yet another patch, on top of the previous ones. This one tries to get the default value of TCP_MAXSEG by creating a temporary TCP socket, so that one can remove the "mss" entry from its configuration file, and reset the mss value for any transferred socket from the old process. Olivier >From 7dc2432f3a7c4a9e9531adafa4524a199e394f90 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Wed, 12 Apr 2017 19:32:15 +0200 Subject: [PATCH 10/10] MINOR: tcp: Attempt to reset TCP_MAXSEG when reusing a socket. Guess the default value for TCP_MAXSEG by binding a temporary TCP socket and getting it, and use that in case the we're reusing a socket from the old process, and its TCP_MAXSEG is different. That way one can reset the TCP_MAXSEG value to the default one when reusing sockets. --- src/proto_tcp.c | 55 --- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/src/proto_tcp.c b/src/proto_tcp.c index ea6b8f7..8050f3e 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -110,6 +110,12 @@ static struct protocol proto_tcpv6 = { .nb_listeners = 0, }; +/* Default TCP parameters, got by opening a temporary TCP socket. */ +#ifdef TCP_MAXSEG +static int default_tcp_maxseg = -1; +static int default_tcp6_maxseg = -1; +#endif + /* Binds ipv4/ipv6 address to socket , unless is set, in which * case we try to bind . is a 2-bit field consisting of : * - 0 : ignore remote address (may even be a NULL pointer) @@ -829,6 +835,35 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) int ext, ready; socklen_t ready_len; const char *msg = NULL; +#ifdef TCP_MAXSEG + + /* Create a temporary TCP socket to get default parameters we can't +* guess. +* */ + ready_len = sizeof(default_tcp_maxseg); + if (default_tcp_maxseg == -1) { + default_tcp_maxseg = -2; + fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (fd < 0) + Warning("Failed to create a temporary socket!\n"); + else { + if (getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &default_tcp_maxseg, + &ready_len) == -1) + Warning("Failed to get the default value of TCP_MAXSEG\n"); + } + } + if (default_tcp6_maxseg == -1) { + default_tcp6_maxseg = -2; + fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + if (fd >= 0) { + if (getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &default_tcp6_maxseg, + &ready_len) == -1) + Warning("Failed ot get the default value of TCP_MAXSEG for IPv6\n"); + close(fd); + } + } +#endif + /* ensure we never return garbage */ if (errlen) @@ -960,10 +995,24 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen) msg = "cannot set MSS"; err |= ERR_WARN; } + } else if (ext) { + int tmpmaxseg = -1; + int defaultmss; + socklen_t len = sizeof(tmpmaxseg); + + if (listener->addr.ss_family == AF_INET) + defaultmss = default_tcp_maxseg; + else + defaultmss = default_tcp6_maxseg; + + getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &tmpmaxseg, &len); + if (tmpmaxseg != defaultmss && + setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, + &defaultmss, sizeof(defaultmss)) == -1) { + msg = "cannot set MSS"; + err |= ERR_WARN; + } } - /* XXX: No else, the way to get the default MSS will vary from system -* to system. -*/ #endif #if defined(TCP_USER_TIMEOUT) if (listener->tcp_ut) { -- 2.9.3
Re: [RFC][PATCHES] seamless reload
On Wed, Apr 12, 2017 at 05:50:54PM +0200, Olivier Houchard wrote: > On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: > > Hi again, > > > > so I tried to get this to work, but didn't manage yet. I also don't quite > > understand how this is supposed to work. The first haproxy process is > > started _without_ the -x option, is that correct? Where does that instance > > ever create the socket for transfer to later instances? > > > > I have it working now insofar that on reload, subsequent instances are > > spawned with the -x option, but they'll just complain that they can't get > > anything from the unix socket (because, for all I can tell, it's not > > there?). I also can't see the relevant code path where this socket gets > > created, but I didn't have time to read all of it yet. > > > > Am I doing something wrong? Did anyone get this to work with the > > systemd-wrapper so far? > > > > Also, but this might be a coincidence, my test setup takes a huge > > performance penalty just by applying your patches (without any reloading > > whatsoever). Did this happen to anybody else? I'll send some numbers and > > more details tomorrow. > > > > Ok I can confirm the performance issues, I'm investigating. > Found it, I was messing with SO_LINGER when I shouldn't have been. Can you try the new version of 0003-MINOR-tcp-When-binding-socket-attempt-to-reuse-one-f.patch or replace, in src/proto_tcp.c : if (getsockopt(fd, SOL_SOCKET, SO_LINGER, &tmplinger, &len) == 0 && (tmplinger.l_onoff == 0 || tmplinger.l_linger == 0)) { /* Attempt to activate SO_LINGER, not sure what a sane * value is, using the default BSD value of 120s. */ tmplinger.l_onoff = 1; tmplinger.l_linger = 120; setsockopt(fd, SOL_SOCKET, SO_LINGER, &tmplinger, sizeof(tmplinger)); } by : if (getsockopt(fd, SOL_SOCKET, SO_LINGER, &tmplinger, &len) == 0 && (tmplinger.l_onoff == 1 || tmplinger.l_linger == 0)) { tmplinger.l_onoff = 0; tmplinger.l_linger = 0; setsockopt(fd, SOL_SOCKET, SO_LINGER, &tmplinger, sizeof(tmplinger)); } } Thanks ! Olivier >From 1bf2b9c550285b434c865adeb175277ce00c842b Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Wed, 5 Apr 2017 22:39:56 +0200 Subject: [PATCH 3/9] MINOR: tcp: When binding socket, attempt to reuse one from the old proc. Try to reuse any socket from the old process, provided by the "-x" flag, before binding a new one, assuming it is compatible. "Compatible" here means same address and port, same namspace if any, same interface if any, and that the following flags are the same : LI_O_FOREIGN, LI_O_V6ONLY and LI_O_V4V6. Also change tcp_bind_listener() to always enable/disable socket options, instead of just doing so if it is in the configuration file, as the option may have been removed, ie TCP_FASTOPEN may have been set in the old process, and removed from the new configuration, so we have to disable it. --- src/proto_tcp.c | 119 +++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 5e12b99..ea6b8f7 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -731,6 +731,83 @@ int tcp_connect_probe(struct connection *conn) return 0; } +/* XXX: Should probably be elsewhere */ +static int compare_sockaddr(struct sockaddr_storage *a, struct sockaddr_storage *b) +{ + if (a->ss_family != b->ss_family) { + return (-1); + } + switch (a->ss_family) { + case AF_INET: + { + struct sockaddr_in *a4 = (void *)a, *b4 = (void *)b; + if (a4->sin_port != b4->sin_port) + return (-1); + return (memcmp(&a4->sin_addr, &b4->sin_addr, + sizeof(a4->sin_addr))); + } + case AF_INET6: + { + struct sockaddr_in6 *a6 = (void *)a, *b6 = (void *)b; + if (a6->sin6_port != b6->sin6_port) + return (-1); + return (memcmp(&a6->sin6_addr, &b6->sin6_addr, + sizeof(a6->sin6_addr))); + } + default: + return (-1); + } + +} + +#define LI_MANDATORY_FLAGS (LI_O_FOREIGN | LI_O_V6ONLY | LI_O_V4V6) +/* When binding the listeners, check if a socket has been sent to us by the + * previous process that we could reuse, instead of creating a new one. + */ +static int tcp_find_compatible_fd(struct listener *l) +{ + struct xfer_sock_list *xfer_sock = xfer_sock_list; + int ret = -1; + +
Re: [RFC][PATCHES] seamless reload
On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: > Hi again, > > so I tried to get this to work, but didn't manage yet. I also don't quite > understand how this is supposed to work. The first haproxy process is > started _without_ the -x option, is that correct? Where does that instance > ever create the socket for transfer to later instances? > > I have it working now insofar that on reload, subsequent instances are > spawned with the -x option, but they'll just complain that they can't get > anything from the unix socket (because, for all I can tell, it's not > there?). I also can't see the relevant code path where this socket gets > created, but I didn't have time to read all of it yet. > > Am I doing something wrong? Did anyone get this to work with the > systemd-wrapper so far? > > Also, but this might be a coincidence, my test setup takes a huge > performance penalty just by applying your patches (without any reloading > whatsoever). Did this happen to anybody else? I'll send some numbers and > more details tomorrow. > Ok I can confirm the performance issues, I'm investigating. Olivier
Re: [RFC][PATCHES] seamless reload
On Wed, Apr 12, 2017 at 05:30:17PM +0200, Conrad Hoffmann wrote: > Hi again, > > so I tried to get this to work, but didn't manage yet. I also don't quite > understand how this is supposed to work. The first haproxy process is > started _without_ the -x option, is that correct? Where does that instance > ever create the socket for transfer to later instances? > > I have it working now insofar that on reload, subsequent instances are > spawned with the -x option, but they'll just complain that they can't get > anything from the unix socket (because, for all I can tell, it's not > there?). I also can't see the relevant code path where this socket gets > created, but I didn't have time to read all of it yet. > > Am I doing something wrong? Did anyone get this to work with the > systemd-wrapper so far? > You're right, the first one runs without -x. The socket used is just any stats socket. > Also, but this might be a coincidence, my test setup takes a huge > performance penalty just by applying your patches (without any reloading > whatsoever). Did this happen to anybody else? I'll send some numbers and > more details tomorrow. > Ah this is news to me, I did not expect a performances impact, can you share your configuration file ? Thanks ! Olivier
Re: [RFC][PATCHES] seamless reload
Hi again, so I tried to get this to work, but didn't manage yet. I also don't quite understand how this is supposed to work. The first haproxy process is started _without_ the -x option, is that correct? Where does that instance ever create the socket for transfer to later instances? I have it working now insofar that on reload, subsequent instances are spawned with the -x option, but they'll just complain that they can't get anything from the unix socket (because, for all I can tell, it's not there?). I also can't see the relevant code path where this socket gets created, but I didn't have time to read all of it yet. Am I doing something wrong? Did anyone get this to work with the systemd-wrapper so far? Also, but this might be a coincidence, my test setup takes a huge performance penalty just by applying your patches (without any reloading whatsoever). Did this happen to anybody else? I'll send some numbers and more details tomorrow. Thanks a lot, Conrad On 04/12/2017 03:47 PM, Conrad Hoffmann wrote: > On 04/12/2017 03:37 PM, Olivier Houchard wrote: >> On Wed, Apr 12, 2017 at 03:16:31PM +0200, Conrad Hoffmann wrote: >>> Hi Olivier, >>> >>> I was very eager to try out your patch set, thanks a lot! However, after >>> applying all of them (including the last three), it seems that using >>> environment variables in the config is broken (i.e. ${VARNAME} does not get >>> replaced with the value of the environment variable anymore). I am using >>> the systemd-wrapper, but not systemd. >>> >>> Just from looking at the patches I couldn't make out what exactly might be >>> the problem. I guess it could be either the wrapper not passing on its >>> environment properly or haproxy not using it properly anymore. If you have >>> any immediate ideas, let me know. I'll try to fully debug this when I can >>> spare the time. >>> >>> Thanks a lot, >>> Conrad >>> >> >> Hi Conrad, >> >> You're right, that was just me being an idiot :) >> Please replace >> 0007-MINOR-systemd-wrapper-add-support-for-passing-the-x-.patch >> with the one attached, or just replace in src/haproxy-systemd-wrapper.c : >> >> argv = calloc(4 + main_argc + nb_pid + 1 + >> stats_socket != NULL ? 2 : 0, sizeof(char *)); >> by : >> argv = calloc(4 + main_argc + nb_pid + 1 + >> (stats_socket != NULL ? 2 : 0), sizeof(char *)); >> >> Regards, >> >> Olivier > > > Works indeed, hard to spot :) > > Thanks a lot, I'll now get back to testing the actual reloads! > > Conrad > -- Conrad Hoffmann Traffic Engineer SoundCloud Ltd. | Rheinsberger Str. 76/77, 10115 Berlin, Germany Managing Director: Alexander Ljung | Incorporated in England & Wales with Company No. 6343600 | Local Branch Office | AG Charlottenburg | HRB 110657B
Re: [RFC][PATCHES] seamless reload
On 04/12/2017 03:37 PM, Olivier Houchard wrote: > On Wed, Apr 12, 2017 at 03:16:31PM +0200, Conrad Hoffmann wrote: >> Hi Olivier, >> >> I was very eager to try out your patch set, thanks a lot! However, after >> applying all of them (including the last three), it seems that using >> environment variables in the config is broken (i.e. ${VARNAME} does not get >> replaced with the value of the environment variable anymore). I am using >> the systemd-wrapper, but not systemd. >> >> Just from looking at the patches I couldn't make out what exactly might be >> the problem. I guess it could be either the wrapper not passing on its >> environment properly or haproxy not using it properly anymore. If you have >> any immediate ideas, let me know. I'll try to fully debug this when I can >> spare the time. >> >> Thanks a lot, >> Conrad >> > > Hi Conrad, > > You're right, that was just me being an idiot :) > Please replace 0007-MINOR-systemd-wrapper-add-support-for-passing-the-x-.patch > with the one attached, or just replace in src/haproxy-systemd-wrapper.c : > > argv = calloc(4 + main_argc + nb_pid + 1 + > stats_socket != NULL ? 2 : 0, sizeof(char *)); > by : > argv = calloc(4 + main_argc + nb_pid + 1 + > (stats_socket != NULL ? 2 : 0), sizeof(char *)); > > Regards, > > Olivier Works indeed, hard to spot :) Thanks a lot, I'll now get back to testing the actual reloads! Conrad -- Conrad Hoffmann Traffic Engineer SoundCloud Ltd. | Rheinsberger Str. 76/77, 10115 Berlin, Germany Managing Director: Alexander Ljung | Incorporated in England & Wales with Company No. 6343600 | Local Branch Office | AG Charlottenburg | HRB 110657B
Re: [RFC][PATCHES] seamless reload
On Wed, Apr 12, 2017 at 03:16:31PM +0200, Conrad Hoffmann wrote: > Hi Olivier, > > I was very eager to try out your patch set, thanks a lot! However, after > applying all of them (including the last three), it seems that using > environment variables in the config is broken (i.e. ${VARNAME} does not get > replaced with the value of the environment variable anymore). I am using > the systemd-wrapper, but not systemd. > > Just from looking at the patches I couldn't make out what exactly might be > the problem. I guess it could be either the wrapper not passing on its > environment properly or haproxy not using it properly anymore. If you have > any immediate ideas, let me know. I'll try to fully debug this when I can > spare the time. > > Thanks a lot, > Conrad > Hi Conrad, You're right, that was just me being an idiot :) Please replace 0007-MINOR-systemd-wrapper-add-support-for-passing-the-x-.patch with the one attached, or just replace in src/haproxy-systemd-wrapper.c : argv = calloc(4 + main_argc + nb_pid + 1 + stats_socket != NULL ? 2 : 0, sizeof(char *)); by : argv = calloc(4 + main_argc + nb_pid + 1 + (stats_socket != NULL ? 2 : 0), sizeof(char *)); Regards, Olivier >From 526dca943b9cc89732c54bc43a6ce36e17b67890 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Sun, 9 Apr 2017 16:28:10 +0200 Subject: [PATCH 7/9] MINOR: systemd wrapper: add support for passing the -x option. Make the systemd wrapper chech if HAPROXY_STATS_SOCKET if set. If set, it will use it as an argument to the "-x" option, which makes haproxy asks for any listening socket, on the stats socket, in order to achieve reloads with no new connection lost. --- contrib/systemd/haproxy.service.in | 2 ++ src/haproxy-systemd-wrapper.c | 10 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/contrib/systemd/haproxy.service.in b/contrib/systemd/haproxy.service.in index dca81a2..05bb716 100644 --- a/contrib/systemd/haproxy.service.in +++ b/contrib/systemd/haproxy.service.in @@ -3,6 +3,8 @@ Description=HAProxy Load Balancer After=network.target [Service] +# You can point the environment variable HAPROXY_STATS_SOCKET to a stats +# socket if you want seamless reloads. Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" ExecStartPre=@SBINDIR@/haproxy -f $CONFIG -c -q ExecStart=@SBINDIR@/haproxy-systemd-wrapper -f $CONFIG -p $PIDFILE diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c index f6a9c85..457f5bd 100644 --- a/src/haproxy-systemd-wrapper.c +++ b/src/haproxy-systemd-wrapper.c @@ -92,11 +92,15 @@ static void spawn_haproxy(char **pid_strv, int nb_pid) pid = fork(); if (!pid) { char **argv; + char *stats_socket = NULL; int i; int argno = 0; /* 3 for "haproxy -Ds -sf" */ - argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *)); + if (nb_pid > 0) + stats_socket = getenv("HAPROXY_STATS_SOCKET"); + argv = calloc(4 + main_argc + nb_pid + 1 + + (stats_socket != NULL ? 2 : 0), sizeof(char *)); if (!argv) { fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to calloc(), please try again later.\n"); exit(1); @@ -121,6 +125,10 @@ static void spawn_haproxy(char **pid_strv, int nb_pid) argv[argno++] = "-sf"; for (i = 0; i < nb_pid; ++i) argv[argno++] = pid_strv[i]; + if (stats_socket != NULL) { + argv[argno++] = "-x"; + argv[argno++] = stats_socket; + } } argv[argno] = NULL; -- 2.9.3
Re: [RFC][PATCHES] seamless reload
Hi Olivier, I was very eager to try out your patch set, thanks a lot! However, after applying all of them (including the last three), it seems that using environment variables in the config is broken (i.e. ${VARNAME} does not get replaced with the value of the environment variable anymore). I am using the systemd-wrapper, but not systemd. Just from looking at the patches I couldn't make out what exactly might be the problem. I guess it could be either the wrapper not passing on its environment properly or haproxy not using it properly anymore. If you have any immediate ideas, let me know. I'll try to fully debug this when I can spare the time. Thanks a lot, Conrad On 04/10/2017 08:09 PM, Olivier Houchard wrote: > > Hi, > > On top of those patches, here a 3 more patches. > The first one makes the systemd wrapper check for a HAPROXY_STATS_SOCKET > environment variable. If set, it will use that as an argument to -x, when > reloading the process. > The second one sends listening unix sockets, as well as IPv4/v6 sockets. > I see no reason not to, and that means we no longer have to wait until > the old process close the socket before being able to accept new connections > on it. > The third one adds a new global optoin, nosockettransfer, if set, we assume > we will never try to transfer listening sockets through the stats socket, > and close any socket nout bound to our process, to save a few file > descriptors. > > Regards, > > Olivier > -- Conrad Hoffmann Traffic Engineer SoundCloud Ltd. | Rheinsberger Str. 76/77, 10115 Berlin, Germany Managing Director: Alexander Ljung | Incorporated in England & Wales with Company No. 6343600 | Local Branch Office | AG Charlottenburg | HRB 110657B
Re: [RFC][PATCHES] seamless reload
On Tue, Apr 11, 2017 at 08:16:48PM +0200, Willy Tarreau wrote: > Hi guys, > > On Mon, Apr 10, 2017 at 11:08:56PM +0200, Pavlos Parissis wrote: > > IMHO: a better name would be 'stats nounsedsockets', as it is referring to a > > generic functionality of UNIX stats socket, rather to a very specific > > functionality. > > Just two things on this : > - it's not directly related to the stats socket but it's a global > behaviour of the process so it should not be under "stats" ; > > - please guys, don't stick words without a '-' as a delimitor > anymore, we've made this mistake in the past with "forceclose", > "httpclose" or "dontlognull" or whatever and some of them are > really hard to read. That's why we now split the words using > dashes, so that would be "no-unused-sockets" or I don't remember > the other name Olivier proposed, but please use the same principle > which leaves no ambiguity on how to parse it. Fine, just beacuse it's you, I'll change that. Olivier
Re: [RFC][PATCHES] seamless reload
Hi guys, On Mon, Apr 10, 2017 at 11:08:56PM +0200, Pavlos Parissis wrote: > IMHO: a better name would be 'stats nounsedsockets', as it is referring to a > generic functionality of UNIX stats socket, rather to a very specific > functionality. Just two things on this : - it's not directly related to the stats socket but it's a global behaviour of the process so it should not be under "stats" ; - please guys, don't stick words without a '-' as a delimitor anymore, we've made this mistake in the past with "forceclose", "httpclose" or "dontlognull" or whatever and some of them are really hard to read. That's why we now split the words using dashes, so that would be "no-unused-sockets" or I don't remember the other name Olivier proposed, but please use the same principle which leaves no ambiguity on how to parse it. Thanks! Willy
Re: [RFC][PATCHES] seamless reload
On Tue, Apr 11, 2017 at 01:23:42PM +0200, Pavlos Parissis wrote: > On 10/04/2017 11:52 μμ, Olivier Houchard wrote: > > On Mon, Apr 10, 2017 at 11:08:56PM +0200, Pavlos Parissis wrote: > >> On 10/04/2017 08:09 , Olivier Houchard wrote: > >>> > >>> Hi, > >>> > >>> On top of those patches, here a 3 more patches. > >>> The first one makes the systemd wrapper check for a HAPROXY_STATS_SOCKET > >>> environment variable. If set, it will use that as an argument to -x, when > >>> reloading the process. > >> > >> I see you want to introduce a specific environment variable for this > >> functionality > >> and then fetched in the code with getenv(). This is a way to do it. > >> > >> IMHO: I prefer to pass a value to an argument, for instance -x. It is also > >> consistent with haproxy binary where someone uses -x argument as well. > >> > > > > I'm not sure what you mean by this ? > > It is supposed to be directly the value given to -x as an argument. > > > > Ignore what I wrote above as I was under the wrong impression that we need to > pass -x to systemd wrapper during the reload, but the systemd wrapper is not > invoked during the reload. > > > >>> The second one sends listening unix sockets, as well as IPv4/v6 sockets. > >>> I see no reason not to, and that means we no longer have to wait until > >>> the old process close the socket before being able to accept new > >>> connections > >>> on it. > >> > >>> The third one adds a new global optoin, nosockettransfer, if set, we > >>> assume > >>> we will never try to transfer listening sockets through the stats socket, > >>> and close any socket nout bound to our process, to save a few file > >>> descriptors. > >>> > >> > >> IMHO: a better name would be 'stats nounsedsockets', as it is referring to > >> a > >> generic functionality of UNIX stats socket, rather to a very specific > >> functionality. > >> > > > > Well really it is a global setting, maybe my wording isn't great, but it > > makes haproxy close all sockets not bound to this process, as it used to, > > instead of keeping them around in case somebody asks for them. > > > >> I hope tomorrow I will find some time to test your patches. > >> > > > > Thanks a lot ! This is greatly appreciated. > > > > Do you have a certain way to test it? > My plan is to have a stress environment where I fire-up X thousands of TCP > connections and produce a graph, which contain number of TCP RST received from > the client during a soft-reload of haproxy. I'll run this test against haproxy > 1.8 with and without your patches. So, I will have a clear indication if your > patches solved the issue. > That sounds good to me. My testing involved an haproxy running with 4 processes, 2 listeners, 1000 ports for each, and 2 processes bound to each listener, 2 injectors doing http requests (that merely got a redirect as an answer from haproxy), one on each listener, and reloading haproxy in a loop. Regards, Olivier
Re: [RFC][PATCHES] seamless reload
On 10/04/2017 11:52 μμ, Olivier Houchard wrote: > On Mon, Apr 10, 2017 at 11:08:56PM +0200, Pavlos Parissis wrote: >> On 10/04/2017 08:09 , Olivier Houchard wrote: >>> >>> Hi, >>> >>> On top of those patches, here a 3 more patches. >>> The first one makes the systemd wrapper check for a HAPROXY_STATS_SOCKET >>> environment variable. If set, it will use that as an argument to -x, when >>> reloading the process. >> >> I see you want to introduce a specific environment variable for this >> functionality >> and then fetched in the code with getenv(). This is a way to do it. >> >> IMHO: I prefer to pass a value to an argument, for instance -x. It is also >> consistent with haproxy binary where someone uses -x argument as well. >> > > I'm not sure what you mean by this ? > It is supposed to be directly the value given to -x as an argument. > Ignore what I wrote above as I was under the wrong impression that we need to pass -x to systemd wrapper during the reload, but the systemd wrapper is not invoked during the reload. >>> The second one sends listening unix sockets, as well as IPv4/v6 sockets. >>> I see no reason not to, and that means we no longer have to wait until >>> the old process close the socket before being able to accept new connections >>> on it. >> >>> The third one adds a new global optoin, nosockettransfer, if set, we assume >>> we will never try to transfer listening sockets through the stats socket, >>> and close any socket nout bound to our process, to save a few file >>> descriptors. >>> >> >> IMHO: a better name would be 'stats nounsedsockets', as it is referring to a >> generic functionality of UNIX stats socket, rather to a very specific >> functionality. >> > > Well really it is a global setting, maybe my wording isn't great, but it > makes haproxy close all sockets not bound to this process, as it used to, > instead of keeping them around in case somebody asks for them. > >> I hope tomorrow I will find some time to test your patches. >> > > Thanks a lot ! This is greatly appreciated. > Do you have a certain way to test it? My plan is to have a stress environment where I fire-up X thousands of TCP connections and produce a graph, which contain number of TCP RST received from the client during a soft-reload of haproxy. I'll run this test against haproxy 1.8 with and without your patches. So, I will have a clear indication if your patches solved the issue. Any ideas? Cheers, Pavlos signature.asc Description: OpenPGP digital signature
Re: [RFC][PATCHES] seamless reload
On 10/04/2017 11:48 μμ, Olivier Houchard wrote: > On Mon, Apr 10, 2017 at 10:49:21PM +0200, Pavlos Parissis wrote: >> On 07/04/2017 11:17 , Olivier Houchard wrote: >>> On Fri, Apr 07, 2017 at 09:58:57PM +0200, Pavlos Parissis wrote: On 06/04/2017 04:57 , Olivier Houchard wrote: > On Thu, Apr 06, 2017 at 04:56:47PM +0200, Pavlos Parissis wrote: >> On 06/04/2017 04:25 , Olivier Houchard wrote: >>> Hi, >>> >>> The attached patchset is the first cut at an attempt to work around the >>> linux issues with SOREUSEPORT that makes haproxy refuse a few new >>> connections >>> under heavy load. >>> This works by transferring the existing sockets to the new process via >>> the >>> stats socket. A new command-line flag has been added, -x, that takes the >>> path to the unix socket as an argument, and if set, will attempt to >>> retrieve >>> all the listening sockets; >>> Right now, any error, either while connecting to the socket, or >>> retrieving >>> the file descriptors, is fatal, but maybe it'd be better to just fall >>> back >>> to the previous behavior instead of opening any missing socket ? I'm >>> still >>> undecided about that. >>> >>> Any testing, comments, etc would be greatly appreciated. >>> >> >> Does this patch set support HAProxy in multiprocess mode (nbproc > 1) ? >> > > Hi Pavlos, > > If it does not, it's a bug :) > In my few tests, it seemed to work. > > Olivier > I run systems with systemd and I can't see how I can test the seamless reload functionality ( thanks for that) without a proper support for the UNIX socket file argument (-x) in the haproxy-systemd-wrapper. I believe you need to modify the wrapper to accept -x argument for a single UNIX socket file or -X for a directory path with multiple UNIX socket files, when HAProxy runs in multi-process mode. What do you think? Cheers, Pavlos >>> >>> >>> Hi Pavlos, >>> >>> I didn't consider systemd, so it may be I have to investigate there. >>> You don't need to talk to all the processes to get the sockets, in the new >>> world order, each process does have all the sockets, although it will accept >>> connections only for those for which it is configured to do so (I plan to >>> add >>> a configuration option to restore the old behavior, for those who don't >>> need >>> that, and want to save file descriptors). >>> Reading the haproxy-systemd-wrapper code, it should be trivial. >>> I just need to figure out how to properly provide the socket path to the >>> wrapper. >>> I see that you already made use of a few environment variables in >>> haproxy.service. Would that be reasonnable to add a new one, that could >>> be set in haproxy.service.d/overwrite.conf ? I'm not super-used to systemd, >>> and I'm not sure of how people are doing that kind of things. >>> >> >> I believe you are referring to $CONFIG and PIDFILE environment variables. >> Those >> two variables are passed to the two arguments, which were present but >> impossible >> to adjust their input, switching to variables allowed people to overwrite >> their input. >> >> In this case, we are talking about a new functionality I guess the best >> approach >> would be to have ExecStart using EXTRAOPTS: >> ExecStart=/usr/sbin/haproxy-systemd-wrapper -f $CONFIG -p $PIDFILE $EXTRAOPTS >> >> This will allow users to set a value to the new argument and any other >> argument >> they want >> cat /etc/systemd/system/haproxy.service.d/overwrite.conf >> [Service] >> Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" >> "EXTRAOPTS=-x /foobar" >> >> or using default configuration file /etc/default/haproxy >> >> [Service] >> Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" >> EnvironmentFile=-/etc/default/haproxy >> ExecStart=/usr/sbin/haproxy-systemd-wrapper -f $CONFIG -p $PIDFILE $EXTRAOPTS >> >> cat /etc/default/haproxy >> EXTRAOPTS="-x /foobar" >> >> I hope it helps, >> Cheers, >> > > > > Hi Pavlos, > > Yeah I see what you mean, it is certainly doable, though -x is a bit special, > because you don't use it the first time you run haproxy, only for reloading, > so that would mean the wrapper has special knowledge about it, and remove it > from the user-supplied command line the first time it's called. I'm a bit > uneasy about that, but if it's felt the best way to do it, I'll go ahead. > I see, I forgot that the -x argument has only a meaning for the reload phase and ExecReload uses haproxy and not the haproxy-systemd-wrapper. So, it makes sense to pass the environment variable and let haproxy-systemd-wrapper do its thing only on the reload. Please ignore what I wrote above for EXTRAOPTS, sorry for the confusion. Cheers, Pavlos signature.asc Description: OpenPGP digital signature
Re: [RFC][PATCHES] seamless reload
On Mon, Apr 10, 2017 at 11:08:56PM +0200, Pavlos Parissis wrote: > On 10/04/2017 08:09 , Olivier Houchard wrote: > > > > Hi, > > > > On top of those patches, here a 3 more patches. > > The first one makes the systemd wrapper check for a HAPROXY_STATS_SOCKET > > environment variable. If set, it will use that as an argument to -x, when > > reloading the process. > > I see you want to introduce a specific environment variable for this > functionality > and then fetched in the code with getenv(). This is a way to do it. > > IMHO: I prefer to pass a value to an argument, for instance -x. It is also > consistent with haproxy binary where someone uses -x argument as well. > I'm not sure what you mean by this ? It is supposed to be directly the value given to -x as an argument. > > The second one sends listening unix sockets, as well as IPv4/v6 sockets. > > I see no reason not to, and that means we no longer have to wait until > > the old process close the socket before being able to accept new connections > > on it. > > > The third one adds a new global optoin, nosockettransfer, if set, we assume > > we will never try to transfer listening sockets through the stats socket, > > and close any socket nout bound to our process, to save a few file > > descriptors. > > > > IMHO: a better name would be 'stats nounsedsockets', as it is referring to a > generic functionality of UNIX stats socket, rather to a very specific > functionality. > Well really it is a global setting, maybe my wording isn't great, but it makes haproxy close all sockets not bound to this process, as it used to, instead of keeping them around in case somebody asks for them. > I hope tomorrow I will find some time to test your patches. > Thanks a lot ! This is greatly appreciated. Regards, Olivier
Re: [RFC][PATCHES] seamless reload
On Mon, Apr 10, 2017 at 10:49:21PM +0200, Pavlos Parissis wrote: > On 07/04/2017 11:17 , Olivier Houchard wrote: > > On Fri, Apr 07, 2017 at 09:58:57PM +0200, Pavlos Parissis wrote: > >> On 06/04/2017 04:57 , Olivier Houchard wrote: > >>> On Thu, Apr 06, 2017 at 04:56:47PM +0200, Pavlos Parissis wrote: > On 06/04/2017 04:25 , Olivier Houchard wrote: > > Hi, > > > > The attached patchset is the first cut at an attempt to work around the > > linux issues with SOREUSEPORT that makes haproxy refuse a few new > > connections > > under heavy load. > > This works by transferring the existing sockets to the new process via > > the > > stats socket. A new command-line flag has been added, -x, that takes the > > path to the unix socket as an argument, and if set, will attempt to > > retrieve > > all the listening sockets; > > Right now, any error, either while connecting to the socket, or > > retrieving > > the file descriptors, is fatal, but maybe it'd be better to just fall > > back > > to the previous behavior instead of opening any missing socket ? I'm > > still > > undecided about that. > > > > Any testing, comments, etc would be greatly appreciated. > > > > Does this patch set support HAProxy in multiprocess mode (nbproc > 1) ? > > >>> > >>> Hi Pavlos, > >>> > >>> If it does not, it's a bug :) > >>> In my few tests, it seemed to work. > >>> > >>> Olivier > >>> > >> > >> > >> I run systems with systemd and I can't see how I can test the seamless > >> reload > >> functionality ( thanks for that) without a proper support for the UNIX > >> socket > >> file argument (-x) in the haproxy-systemd-wrapper. > >> > >> I believe you need to modify the wrapper to accept -x argument for a single > >> UNIX socket file or -X for a directory path with multiple UNIX socket > >> files, > >> when HAProxy runs in multi-process mode. > >> > >> What do you think? > >> > >> Cheers, > >> Pavlos > >> > >> > >> > > > > > > Hi Pavlos, > > > > I didn't consider systemd, so it may be I have to investigate there. > > You don't need to talk to all the processes to get the sockets, in the new > > world order, each process does have all the sockets, although it will accept > > connections only for those for which it is configured to do so (I plan to > > add > > a configuration option to restore the old behavior, for those who don't > > need > > that, and want to save file descriptors). > > Reading the haproxy-systemd-wrapper code, it should be trivial. > > I just need to figure out how to properly provide the socket path to the > > wrapper. > > I see that you already made use of a few environment variables in > > haproxy.service. Would that be reasonnable to add a new one, that could > > be set in haproxy.service.d/overwrite.conf ? I'm not super-used to systemd, > > and I'm not sure of how people are doing that kind of things. > > > > I believe you are referring to $CONFIG and PIDFILE environment variables. > Those > two variables are passed to the two arguments, which were present but > impossible > to adjust their input, switching to variables allowed people to overwrite > their input. > > In this case, we are talking about a new functionality I guess the best > approach > would be to have ExecStart using EXTRAOPTS: > ExecStart=/usr/sbin/haproxy-systemd-wrapper -f $CONFIG -p $PIDFILE $EXTRAOPTS > > This will allow users to set a value to the new argument and any other > argument > they want > cat /etc/systemd/system/haproxy.service.d/overwrite.conf > [Service] > Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" > "EXTRAOPTS=-x /foobar" > > or using default configuration file /etc/default/haproxy > > [Service] > Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" > EnvironmentFile=-/etc/default/haproxy > ExecStart=/usr/sbin/haproxy-systemd-wrapper -f $CONFIG -p $PIDFILE $EXTRAOPTS > > cat /etc/default/haproxy > EXTRAOPTS="-x /foobar" > > I hope it helps, > Cheers, > Hi Pavlos, Yeah I see what you mean, it is certainly doable, though -x is a bit special, because you don't use it the first time you run haproxy, only for reloading, so that would mean the wrapper has special knowledge about it, and remove it from the user-supplied command line the first time it's called. I'm a bit uneasy about that, but if it's felt the best way to do it, I'll go ahead. Regards, Olivier
Re: [RFC][PATCHES] seamless reload
On 10/04/2017 08:09 μμ, Olivier Houchard wrote: > > Hi, > > On top of those patches, here a 3 more patches. > The first one makes the systemd wrapper check for a HAPROXY_STATS_SOCKET > environment variable. If set, it will use that as an argument to -x, when > reloading the process. I see you want to introduce a specific environment variable for this functionality and then fetched in the code with getenv(). This is a way to do it. IMHO: I prefer to pass a value to an argument, for instance -x. It is also consistent with haproxy binary where someone uses -x argument as well. > The second one sends listening unix sockets, as well as IPv4/v6 sockets. > I see no reason not to, and that means we no longer have to wait until > the old process close the socket before being able to accept new connections > on it. > The third one adds a new global optoin, nosockettransfer, if set, we assume > we will never try to transfer listening sockets through the stats socket, > and close any socket nout bound to our process, to save a few file > descriptors. > IMHO: a better name would be 'stats nounsedsockets', as it is referring to a generic functionality of UNIX stats socket, rather to a very specific functionality. I hope tomorrow I will find some time to test your patches. Thanks a lot for your work on this, Pavlos signature.asc Description: OpenPGP digital signature
Re: [RFC][PATCHES] seamless reload
On 07/04/2017 11:17 μμ, Olivier Houchard wrote: > On Fri, Apr 07, 2017 at 09:58:57PM +0200, Pavlos Parissis wrote: >> On 06/04/2017 04:57 , Olivier Houchard wrote: >>> On Thu, Apr 06, 2017 at 04:56:47PM +0200, Pavlos Parissis wrote: On 06/04/2017 04:25 , Olivier Houchard wrote: > Hi, > > The attached patchset is the first cut at an attempt to work around the > linux issues with SOREUSEPORT that makes haproxy refuse a few new > connections > under heavy load. > This works by transferring the existing sockets to the new process via the > stats socket. A new command-line flag has been added, -x, that takes the > path to the unix socket as an argument, and if set, will attempt to > retrieve > all the listening sockets; > Right now, any error, either while connecting to the socket, or retrieving > the file descriptors, is fatal, but maybe it'd be better to just fall back > to the previous behavior instead of opening any missing socket ? I'm still > undecided about that. > > Any testing, comments, etc would be greatly appreciated. > Does this patch set support HAProxy in multiprocess mode (nbproc > 1) ? >>> >>> Hi Pavlos, >>> >>> If it does not, it's a bug :) >>> In my few tests, it seemed to work. >>> >>> Olivier >>> >> >> >> I run systems with systemd and I can't see how I can test the seamless reload >> functionality ( thanks for that) without a proper support for the UNIX socket >> file argument (-x) in the haproxy-systemd-wrapper. >> >> I believe you need to modify the wrapper to accept -x argument for a single >> UNIX socket file or -X for a directory path with multiple UNIX socket files, >> when HAProxy runs in multi-process mode. >> >> What do you think? >> >> Cheers, >> Pavlos >> >> >> > > > Hi Pavlos, > > I didn't consider systemd, so it may be I have to investigate there. > You don't need to talk to all the processes to get the sockets, in the new > world order, each process does have all the sockets, although it will accept > connections only for those for which it is configured to do so (I plan to add > a configuration option to restore the old behavior, for those who don't need > that, and want to save file descriptors). > Reading the haproxy-systemd-wrapper code, it should be trivial. > I just need to figure out how to properly provide the socket path to the > wrapper. > I see that you already made use of a few environment variables in > haproxy.service. Would that be reasonnable to add a new one, that could > be set in haproxy.service.d/overwrite.conf ? I'm not super-used to systemd, > and I'm not sure of how people are doing that kind of things. > I believe you are referring to $CONFIG and PIDFILE environment variables. Those two variables are passed to the two arguments, which were present but impossible to adjust their input, switching to variables allowed people to overwrite their input. In this case, we are talking about a new functionality I guess the best approach would be to have ExecStart using EXTRAOPTS: ExecStart=/usr/sbin/haproxy-systemd-wrapper -f $CONFIG -p $PIDFILE $EXTRAOPTS This will allow users to set a value to the new argument and any other argument they want cat /etc/systemd/system/haproxy.service.d/overwrite.conf [Service] Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "EXTRAOPTS=-x /foobar" or using default configuration file /etc/default/haproxy [Service] Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" EnvironmentFile=-/etc/default/haproxy ExecStart=/usr/sbin/haproxy-systemd-wrapper -f $CONFIG -p $PIDFILE $EXTRAOPTS cat /etc/default/haproxy EXTRAOPTS="-x /foobar" I hope it helps, Cheers, signature.asc Description: OpenPGP digital signature
Re: [RFC][PATCHES] seamless reload
Hi, On top of those patches, here a 3 more patches. The first one makes the systemd wrapper check for a HAPROXY_STATS_SOCKET environment variable. If set, it will use that as an argument to -x, when reloading the process. The second one sends listening unix sockets, as well as IPv4/v6 sockets. I see no reason not to, and that means we no longer have to wait until the old process close the socket before being able to accept new connections on it. The third one adds a new global optoin, nosockettransfer, if set, we assume we will never try to transfer listening sockets through the stats socket, and close any socket nout bound to our process, to save a few file descriptors. Regards, Olivier >From 8d6c38b6824346b096ba31757ab62bc986a433b3 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Sun, 9 Apr 2017 16:28:10 +0200 Subject: [PATCH 7/9] MINOR: systemd wrapper: add support for passing the -x option. Make the systemd wrapper chech if HAPROXY_STATS_SOCKET if set. If set, it will use it as an argument to the "-x" option, which makes haproxy asks for any listening socket, on the stats socket, in order to achieve reloads with no new connection lost. --- contrib/systemd/haproxy.service.in | 2 ++ src/haproxy-systemd-wrapper.c | 10 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/contrib/systemd/haproxy.service.in b/contrib/systemd/haproxy.service.in index dca81a2..05bb716 100644 --- a/contrib/systemd/haproxy.service.in +++ b/contrib/systemd/haproxy.service.in @@ -3,6 +3,8 @@ Description=HAProxy Load Balancer After=network.target [Service] +# You can point the environment variable HAPROXY_STATS_SOCKET to a stats +# socket if you want seamless reloads. Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" ExecStartPre=@SBINDIR@/haproxy -f $CONFIG -c -q ExecStart=@SBINDIR@/haproxy-systemd-wrapper -f $CONFIG -p $PIDFILE diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c index f6a9c85..1d00111 100644 --- a/src/haproxy-systemd-wrapper.c +++ b/src/haproxy-systemd-wrapper.c @@ -92,11 +92,15 @@ static void spawn_haproxy(char **pid_strv, int nb_pid) pid = fork(); if (!pid) { char **argv; + char *stats_socket = NULL; int i; int argno = 0; /* 3 for "haproxy -Ds -sf" */ - argv = calloc(4 + main_argc + nb_pid + 1, sizeof(char *)); + if (nb_pid > 0) + stats_socket = getenv("HAPROXY_STATS_SOCKET"); + argv = calloc(4 + main_argc + nb_pid + 1 + + stats_socket != NULL ? 2 : 0, sizeof(char *)); if (!argv) { fprintf(stderr, SD_NOTICE "haproxy-systemd-wrapper: failed to calloc(), please try again later.\n"); exit(1); @@ -121,6 +125,10 @@ static void spawn_haproxy(char **pid_strv, int nb_pid) argv[argno++] = "-sf"; for (i = 0; i < nb_pid; ++i) argv[argno++] = pid_strv[i]; + if (stats_socket != NULL) { + argv[argno++] = "-x"; + argv[argno++] = stats_socket; + } } argv[argno] = NULL; -- 2.9.3 >From df5e6e70f2e73fca9e28ba273904ab5c5acf53d3 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Sun, 9 Apr 2017 19:17:15 +0200 Subject: [PATCH 8/9] MINOR: cli: When sending listening sockets, send unix sockets too. Send unix sockets, as well as IPv4/IPv6 sockets, so that we don't have to wait for the old process to die before being able to bind those. --- src/cli.c| 6 -- src/proto_uxst.c | 50 ++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/cli.c b/src/cli.c index d5ff11f..533f792 100644 --- a/src/cli.c +++ b/src/cli.c @@ -1067,7 +1067,8 @@ static int _getsocks(char **args, struct appctx *appctx, void *private) list_for_each_entry(l, &px->conf.listeners, by_fe) { /* Only transfer IPv4/IPv6 sockets */ if (l->proto->sock_family == AF_INET || - l->proto->sock_family == AF_INET6) + l->proto->sock_family == AF_INET6 || + l->proto->sock_family == AF_UNIX) tot_fd_nb++; } px = px->next; @@ -1120,7 +1121,8 @@ static int _getsocks(char **args, struct appctx *appctx, void *private) /* Only transfer IPv4/IPv6 sockets */ if (l->state >= LI_LISTEN && (l->proto->sock_family == AF_INET || - l->proto->sock_family == AF_INET6)) { + l->proto->sock_family == AF_INET6 || + l->p
Re: [RFC][PATCHES] seamless reload
On Fri, Apr 07, 2017 at 09:58:57PM +0200, Pavlos Parissis wrote: > On 06/04/2017 04:57 , Olivier Houchard wrote: > > On Thu, Apr 06, 2017 at 04:56:47PM +0200, Pavlos Parissis wrote: > >> On 06/04/2017 04:25 , Olivier Houchard wrote: > >>> Hi, > >>> > >>> The attached patchset is the first cut at an attempt to work around the > >>> linux issues with SOREUSEPORT that makes haproxy refuse a few new > >>> connections > >>> under heavy load. > >>> This works by transferring the existing sockets to the new process via the > >>> stats socket. A new command-line flag has been added, -x, that takes the > >>> path to the unix socket as an argument, and if set, will attempt to > >>> retrieve > >>> all the listening sockets; > >>> Right now, any error, either while connecting to the socket, or retrieving > >>> the file descriptors, is fatal, but maybe it'd be better to just fall back > >>> to the previous behavior instead of opening any missing socket ? I'm still > >>> undecided about that. > >>> > >>> Any testing, comments, etc would be greatly appreciated. > >>> > >> > >> Does this patch set support HAProxy in multiprocess mode (nbproc > 1) ? > >> > > > > Hi Pavlos, > > > > If it does not, it's a bug :) > > In my few tests, it seemed to work. > > > > Olivier > > > > > I run systems with systemd and I can't see how I can test the seamless reload > functionality ( thanks for that) without a proper support for the UNIX socket > file argument (-x) in the haproxy-systemd-wrapper. > > I believe you need to modify the wrapper to accept -x argument for a single > UNIX socket file or -X for a directory path with multiple UNIX socket files, > when HAProxy runs in multi-process mode. > > What do you think? > > Cheers, > Pavlos > > > Hi Pavlos, I didn't consider systemd, so it may be I have to investigate there. You don't need to talk to all the processes to get the sockets, in the new world order, each process does have all the sockets, although it will accept connections only for those for which it is configured to do so (I plan to add a configuration option to restore the old behavior, for those who don't need that, and want to save file descriptors). Reading the haproxy-systemd-wrapper code, it should be trivial. I just need to figure out how to properly provide the socket path to the wrapper. I see that you already made use of a few environment variables in haproxy.service. Would that be reasonnable to add a new one, that could be set in haproxy.service.d/overwrite.conf ? I'm not super-used to systemd, and I'm not sure of how people are doing that kind of things. Thanks ! Olivier
Re: [RFC][PATCHES] seamless reload
On 06/04/2017 04:57 μμ, Olivier Houchard wrote: > On Thu, Apr 06, 2017 at 04:56:47PM +0200, Pavlos Parissis wrote: >> On 06/04/2017 04:25 μμ, Olivier Houchard wrote: >>> Hi, >>> >>> The attached patchset is the first cut at an attempt to work around the >>> linux issues with SOREUSEPORT that makes haproxy refuse a few new >>> connections >>> under heavy load. >>> This works by transferring the existing sockets to the new process via the >>> stats socket. A new command-line flag has been added, -x, that takes the >>> path to the unix socket as an argument, and if set, will attempt to retrieve >>> all the listening sockets; >>> Right now, any error, either while connecting to the socket, or retrieving >>> the file descriptors, is fatal, but maybe it'd be better to just fall back >>> to the previous behavior instead of opening any missing socket ? I'm still >>> undecided about that. >>> >>> Any testing, comments, etc would be greatly appreciated. >>> >> >> Does this patch set support HAProxy in multiprocess mode (nbproc > 1) ? >> > > Hi Pavlos, > > If it does not, it's a bug :) > In my few tests, it seemed to work. > > Olivier > I run systems with systemd and I can't see how I can test the seamless reload functionality ( thanks for that) without a proper support for the UNIX socket file argument (-x) in the haproxy-systemd-wrapper. I believe you need to modify the wrapper to accept -x argument for a single UNIX socket file or -X for a directory path with multiple UNIX socket files, when HAProxy runs in multi-process mode. What do you think? Cheers, Pavlos signature.asc Description: OpenPGP digital signature
Re: [RFC][PATCHES] seamless reload
On Thu, Apr 06, 2017 at 04:56:47PM +0200, Pavlos Parissis wrote: > On 06/04/2017 04:25 μμ, Olivier Houchard wrote: > > Hi, > > > > The attached patchset is the first cut at an attempt to work around the > > linux issues with SOREUSEPORT that makes haproxy refuse a few new > > connections > > under heavy load. > > This works by transferring the existing sockets to the new process via the > > stats socket. A new command-line flag has been added, -x, that takes the > > path to the unix socket as an argument, and if set, will attempt to retrieve > > all the listening sockets; > > Right now, any error, either while connecting to the socket, or retrieving > > the file descriptors, is fatal, but maybe it'd be better to just fall back > > to the previous behavior instead of opening any missing socket ? I'm still > > undecided about that. > > > > Any testing, comments, etc would be greatly appreciated. > > > > Does this patch set support HAProxy in multiprocess mode (nbproc > 1) ? > Hi Pavlos, If it does not, it's a bug :) In my few tests, it seemed to work. Olivier
Re: [RFC][PATCHES] seamless reload
On 06/04/2017 04:25 μμ, Olivier Houchard wrote: > Hi, > > The attached patchset is the first cut at an attempt to work around the > linux issues with SOREUSEPORT that makes haproxy refuse a few new connections > under heavy load. > This works by transferring the existing sockets to the new process via the > stats socket. A new command-line flag has been added, -x, that takes the > path to the unix socket as an argument, and if set, will attempt to retrieve > all the listening sockets; > Right now, any error, either while connecting to the socket, or retrieving > the file descriptors, is fatal, but maybe it'd be better to just fall back > to the previous behavior instead of opening any missing socket ? I'm still > undecided about that. > > Any testing, comments, etc would be greatly appreciated. > Does this patch set support HAProxy in multiprocess mode (nbproc > 1) ? Cheers, Pavlos signature.asc Description: OpenPGP digital signature