]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cli: add 'expose-fd listeners' to pass listeners FDs
authorWilliam Lallemand <wlallemand@haproxy.com>
Fri, 26 May 2017 15:42:10 +0000 (17:42 +0200)
committerWilly Tarreau <w@1wt.eu>
Sat, 27 May 2017 05:02:17 +0000 (07:02 +0200)
This patch changes the stats socket rights for allowing the sending of
listening sockets.

The previous behavior was to allow any unix stats socket with admin
level to send sockets. It's not possible anymore, you have to set this
option to activate the socket sending.

Example:
   stats socket /var/run/haproxy4.sock mode 666 expose-fd listeners level user process 4

doc/configuration.txt
doc/management.txt
include/types/global.h
src/cli.c

index edd9e79ba49fc5db169ac211b93eb2d15baac241..f9bdf2add034c66fedddc752906100bda1d7a0ec 100644 (file)
@@ -10413,6 +10413,11 @@ defer-accept
   an established connection while the proxy will only see it in SYN_RECV. This
   option is only supported on TCPv4/TCPv6 sockets and ignored by other ones.
 
+expose-fd listeners
+  This option is only usable with the stats socket. It gives your stats socket
+  the capability to pass listeners FD to another HAProxy process.
+  See alors "-x" in the management guide.
+
 force-sslv3
   This option enforces use of SSLv3 only on SSL connections instantiated from
   this listener. SSLv3 is generally less expensive than the TLS counterparts
index d1ea1f64af384a518b1b022cd47b222e0c091238..565813e3ff90572519d9a64ffe7db4f26e515937 100644 (file)
@@ -280,7 +280,8 @@ list of options is :
   -x <unix_socket> : connect to the specified socket and try to retrieve any
     listening sockets from the old process, and use them instead of trying to
     bind new ones. This is useful to avoid missing any new connection when
-    reloading the configuration on Linux.
+    reloading the configuration on Linux. The capability must be enable on the
+    stats socket using "expose-fd listeners" in your configuration.
 
 A safe way to start HAProxy from an init file consists in forcing the daemon
 mode, storing existing pids to a pid file and using this pid file to notify
index cd5fda3c32ea523c0836f895685a13ea20299f0e..aeb82eae967315b9873ef161383d34c20907dc3f 100644 (file)
@@ -71,6 +71,7 @@
 #define ACCESS_LVL_ADMIN    3
 #define ACCESS_LVL_MASK     0x3
 
+#define ACCESS_FD_LISTENERS 0x4  /* expose listeners FDs on stats socket */
 
 /* SSL server verify mode */
 enum {
index cdbaf2b4d3ac741b35439a8df0b153ef80ec14a3..55115d689baa07d6b01efe79af9d58d4192aa535 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -993,6 +993,24 @@ static int cli_parse_set_ratelimit(char **args, struct appctx *appctx, void *pri
        return 1;
 }
 
+/* parse the "expose-fd" argument on the bind lines */
+static int bind_parse_expose_fd(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+       if (!*args[cur_arg + 1]) {
+               memprintf(err, "'%s' : missing fd type", args[cur_arg]);
+               return ERR_ALERT | ERR_FATAL;
+       }
+       if (!strcmp(args[cur_arg+1], "listeners")) {
+               conf->level |= ACCESS_FD_LISTENERS;
+       } else {
+               memprintf(err, "'%s' only supports 'listeners' (got '%s')",
+                         args[cur_arg], args[cur_arg+1]);
+               return ERR_ALERT | ERR_FATAL;
+       }
+
+       return 0;
+}
+
 /* parse the "level" argument on the bind lines */
 static int bind_parse_level(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
 {
@@ -1026,6 +1044,7 @@ static int _getsocks(char **args, struct appctx *appctx, void *private)
        unsigned char *tmpbuf = NULL;
        struct cmsghdr *cmsg;
        struct stream_interface *si = appctx->owner;
+       struct stream *s = si_strm(si);
        struct connection *remote = objt_conn(si_opposite(si)->end);
        struct msghdr msghdr;
        struct iovec iov;
@@ -1057,7 +1076,7 @@ static int _getsocks(char **args, struct appctx *appctx, void *private)
        setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void *)&tv, sizeof(tv));
        iov.iov_base = &tot_fd_nb;
        iov.iov_len = sizeof(tot_fd_nb);
-       if (!cli_has_level(appctx, ACCESS_LVL_ADMIN))
+       if (!(strm_li(s)->bind_conf->level & ACCESS_FD_LISTENERS))
                goto out;
        memset(&msghdr, 0, sizeof(msghdr));
        /*
@@ -1224,7 +1243,8 @@ static struct cfg_kw_list cfg_kws = {ILH, {
 }};
 
 static struct bind_kw_list bind_kws = { "STAT", { }, {
-       { "level",    bind_parse_level,    1 }, /* set the unix socket admin level */
+       { "level",     bind_parse_level,    1 }, /* set the unix socket admin level */
+       { "expose-fd", bind_parse_expose_fd, 1 }, /* set the unix socket expose fd rights */
        { NULL, NULL, 0 },
 }};