]> review.fuel-infra Code Review - packages/xenial/haproxy.git/commitdiff
Fix show server state through socket 73/24673/1 10.0/newton 9.0 master
authorIvan Suzdal <isuzdal@mirantis.com>
Mon, 8 Aug 2016 15:20:01 +0000 (18:20 +0300)
committerIvan Suzdal <isuzdal@mirantis.com>
Mon, 8 Aug 2016 15:20:10 +0000 (18:20 +0300)
Change-Id: Ie1979fd39f8893acbe3b2059e91e544584ecca1d
Related-Bug: #1608561

debian/changelog
debian/patches/MIRA0002-Fix-show-server-state-through-socket.patch [new file with mode: 0644]
debian/patches/series

index 171089e6c365204cc1e3f2638cbc9d50523714a3..ed06bdd5cc6e004adaed83a1a87bc94c55721c4d 100644 (file)
@@ -1,3 +1,11 @@
+haproxy (1.6.3-1~u16.04+mos3) mos; urgency=medium
+
+  * BUGFIX: show servers state may show an empty or incomplete result
+    -  debian/patches/MIRA0002-Fix-show-server-state-through-socket.patch
+    Closes: #LP1608561
+
+ -- Ivan Suzdal <mos-linux@mirantis.com>  Mon, 08 Aug 2016 15:19:24 +0000
+
 haproxy (1.6.3-1~u16.04+mos2) mos10.0; urgency=medium
 
   * SECURITY UPDATE: denial of service via reqdeny
diff --git a/debian/patches/MIRA0002-Fix-show-server-state-through-socket.patch b/debian/patches/MIRA0002-Fix-show-server-state-through-socket.patch
new file mode 100644 (file)
index 0000000..257a136
--- /dev/null
@@ -0,0 +1,155 @@
+--- a/include/types/applet.h
++++ b/include/types/applet.h
+@@ -131,7 +131,9 @@
+                       struct dns_resolvers *ptr;
+               } resolvers;
+               struct {
+-                      struct proxy *backend;
++                      int iid;                /* if >= 0, ID of the proxy to filter on */
++                      struct proxy *px;       /* current proxy being dumped, NULL = not started yet. */
++                      struct server *sv;      /* current server being dumped, NULL = not started yet. */
+               } server_state;
+       } ctx;                                  /* used by stats I/O handlers to dump the stats */
+ };
+--- a/src/dumpstats.c
++++ b/src/dumpstats.c
+@@ -148,7 +148,7 @@
+ #endif
+ static void cli_release_handler(struct appctx *appctx);
+-static void dump_servers_state(struct proxy *backend, struct chunk *buf);
++static int dump_servers_state(struct stream_interface *si, struct chunk *buf);
+ /*
+  * cli_io_handler()
+@@ -1200,18 +1200,21 @@
+                       appctx->st0 = STAT_CLI_O_INFO; // stats_dump_info_to_buffer
+               }
+               else if (strcmp(args[1], "servers") == 0 && strcmp(args[2], "state") == 0) {
+-                      appctx->ctx.server_state.backend = NULL;
++                      appctx->ctx.server_state.iid = 0;
++                      appctx->ctx.server_state.px = NULL;
++                      appctx->ctx.server_state.sv = NULL;
+                       /* check if a backend name has been provided */
+                       if (*args[3]) {
+                               /* read server state from local file */
+-                              appctx->ctx.server_state.backend = proxy_be_by_name(args[3]);
++                              appctx->ctx.server_state.px = proxy_be_by_name(args[3]);
+-                              if (appctx->ctx.server_state.backend == NULL) {
++                              if (!appctx->ctx.server_state.px) {
+                                       appctx->ctx.cli.msg = "Can't find backend.\n";
+                                       appctx->st0 = STAT_CLI_PRINT;
+                                       return 1;
+                               }
++                              appctx->ctx.server_state.iid = appctx->ctx.server_state.px->uuid;
+                       }
+                       appctx->st2 = STAT_ST_INIT;
+                       appctx->st0 = STAT_CLI_O_SERVERS_STATE; // stats_dump_servers_state_to_buffer
+@@ -2736,20 +2739,24 @@
+  * By default, we only export to the last known server state file format.
+  * These information can be used at next startup to recover same level of server state.
+  */
+-static void dump_servers_state(struct proxy *backend, struct chunk *buf)
++static int dump_servers_state(struct stream_interface *si, struct chunk *buf)
+ {
++      struct appctx *appctx = __objt_appctx(si->end);
+       struct server *srv;
+       char srv_addr[INET6_ADDRSTRLEN + 1];
+       time_t srv_time_since_last_change;
+       int bk_f_forced_id, srv_f_forced_id;
++
+       /* we don't want to report any state if the backend is not enabled on this process */
+-      if (backend->bind_proc && !(backend->bind_proc & (1UL << (relative_pid - 1))))
+-              return;
++      if (appctx->ctx.server_state.px->bind_proc && !(appctx->ctx.server_state.px->bind_proc & (1UL << (relative_pid - 1))))
++              return 1;
+-      srv = backend->srv;
++      if (!appctx->ctx.server_state.sv)
++              appctx->ctx.server_state.sv = appctx->ctx.server_state.px->srv;
+-      while (srv) {
++      for (; appctx->ctx.server_state.sv != NULL; appctx->ctx.server_state.sv = srv->next) {
++              srv = appctx->ctx.server_state.sv;
+               srv_addr[0] = '\0';
+               srv_time_since_last_change = 0;
+               bk_f_forced_id = 0;
+@@ -2766,7 +2773,7 @@
+                               break;
+               }
+               srv_time_since_last_change = now.tv_sec - srv->last_change;
+-              bk_f_forced_id = backend->options & PR_O_FORCED_ID ? 1 : 0;
++              bk_f_forced_id = appctx->ctx.server_state.px->options & PR_O_FORCED_ID ? 1 : 0;
+               srv_f_forced_id = srv->flags & SRV_F_FORCED_ID ? 1 : 0;
+               chunk_appendf(buf,
+@@ -2776,14 +2783,17 @@
+                               "%d %d %d %d %d "
+                               "%d %d"
+                               "\n",
+-                              backend->uuid, backend->id,
++                              appctx->ctx.server_state.px->uuid, appctx->ctx.server_state.px->id,
+                               srv->puid, srv->id, srv_addr,
+                               srv->state, srv->admin, srv->uweight, srv->iweight, (long int)srv_time_since_last_change,
+                               srv->check.status, srv->check.result, srv->check.health, srv->check.state, srv->agent.state,
+                               bk_f_forced_id, srv_f_forced_id);
+-
+-              srv = srv->next;
++              if (bi_putchk(si_ic(si), &trash) == -1) {
++                      si_applet_cant_put(si);
++                      return 0;
++              }
+       }
++      return 1;
+ }
+ /* Parses backend list and simply report backend names */
+@@ -2826,24 +2836,30 @@
+       chunk_reset(&trash);
+-      chunk_printf(&trash, "%d\n# %s\n", SRV_STATE_FILE_VERSION, SRV_STATE_FILE_FIELD_NAMES);
+-
+-      if (appctx->ctx.server_state.backend) {
+-              dump_servers_state(appctx->ctx.server_state.backend, &trash);
+-      }
+-      else {
+-              for (curproxy = proxy; curproxy != NULL; curproxy = curproxy->next) {
+-                      /* servers are only in backends */
+-                      if (!(curproxy->cap & PR_CAP_BE))
+-                              continue;
+-
+-                      dump_servers_state(curproxy, &trash);
++      if (!appctx->ctx.server_state.px) {
++              chunk_printf(&trash, "%d\n# %s\n", SRV_STATE_FILE_VERSION, SRV_STATE_FILE_FIELD_NAMES);
++              if (bi_putchk(si_ic(si), &trash) == -1) {
++                      si_applet_cant_put(si);
++                      return 0;
+               }
++              appctx->ctx.server_state.px = proxy;
+       }
+-      if (bi_putchk(si_ic(si), &trash) == -1) {
+-              si_applet_cant_put(si);
+-              return 0;
++      for (; appctx->ctx.server_state.px != NULL; appctx->ctx.server_state.px = curproxy->next) {
++              curproxy = appctx->ctx.server_state.px;
++              /* servers are only in backends */
++              if (curproxy->cap & PR_CAP_BE) {
++                      if (!dump_servers_state(si, &trash))
++                              return 0;
++
++                      if (bi_putchk(si_ic(si), &trash) == -1) {
++                              si_applet_cant_put(si);
++                              return 0;
++                      }
++              }
++              /* only the selected proxy is dumped */
++              if (appctx->ctx.server_state.iid)
++                      break;
+       }
+       return 1;
index 280e12616c09ca08f2af8ec2b4d36eced13dfbe9..7ce1c9aade55f161dd8489f6bbddd020487ffdb8 100644 (file)
@@ -5,3 +5,4 @@ haproxy.service-check-config-before-reload.patch
 haproxy.service-use-environment-variables.patch
 CVE-2016-5360.patch
 MIRA0001-Adding-include-configuration-statement-to-haproxy.patch
+MIRA0002-Fix-show-server-state-through-socket.patch