]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: server: do not use refcount in free_server in stopping mode
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 9 Aug 2021 13:08:54 +0000 (15:08 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 9 Aug 2021 15:53:30 +0000 (17:53 +0200)
Currently there is a leak at process shutdown with dynamic servers with
check/agent-check activated. Check purges are not executed on process
stopping, so the server is not liberated due to its refcount.

The solution is simply to ignore the refcount on process stopping mode
and free the server on the first free_server invocation.

This should not be backported, unless dynamic server checks are
backported. In this case, the following commit must be backported first.
  7afa5c1843521ec3be7549592d2b38ccc9d68b73
  MINOR: global: define MODE_STOPPING

src/server.c

index b762ce9412ebdf50ccfa0640e79cb43fb8af9271..6405c3636fae60f09a40b431f6f3de94689bf233 100644 (file)
@@ -2210,16 +2210,20 @@ static uint srv_release_dynsrv(struct server *srv)
        return HA_ATOMIC_SUB_FETCH(&srv->refcount_dynsrv, 1);
 }
 
-/* Deallocate a server <srv> and its member. <srv> must be allocated.
+/* Deallocate a server <srv> and its member. <srv> must be allocated. For
+ * dynamic servers, its refcount is decremented first. The free operations are
+ * conducted only if the refcount is nul, unless the process is stopping.
  */
 void free_server(struct server *srv)
 {
        /* For dynamic servers, decrement the reference counter. Only free the
         * server when reaching zero.
         */
-       if (srv->flags & SRV_F_DYNAMIC) {
-               if (srv_release_dynsrv(srv))
-                       return;
+       if (likely(!(global.mode & MODE_STOPPING))) {
+               if (srv->flags & SRV_F_DYNAMIC) {
+                       if (srv_release_dynsrv(srv))
+                               return;
+               }
        }
 
        task_destroy(srv->warmup);