[PATCH] Upstream: cleanup at shutdown

Piotr Sikora piotr at aviatrix.com
Wed Feb 28 01:21:15 UTC 2024


# HG changeset patch
# User Piotr Sikora <piotr at aviatrix.com>
# Date 1708977618 0
#      Mon Feb 26 20:00:18 2024 +0000
# Branch patch003
# Node ID 8edb4003177dac56301aed7f86f8d2a564b47552
# Parent  f8d9fb94eab212f6e640b7a68ed111562e3157d5
Upstream: cleanup at shutdown.

Add "free_upstream" callback called on worker exit to
free any per-upstream objects allocated from the heap.

Found with LeakSanitizer.

Signed-off-by: Piotr Sikora <piotr at aviatrix.com>

diff -r f8d9fb94eab2 -r 8edb4003177d src/http/modules/ngx_http_upstream_random_module.c
--- a/src/http/modules/ngx_http_upstream_random_module.c	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/http/modules/ngx_http_upstream_random_module.c	Mon Feb 26 20:00:18 2024 +0000
@@ -114,6 +114,35 @@
 }
 
 
+static void
+ngx_http_upstream_free_random(ngx_http_upstream_srv_conf_t *us)
+{
+#if (NGX_HTTP_UPSTREAM_ZONE)
+
+    ngx_http_upstream_rr_peers_t         *peers;
+    ngx_http_upstream_random_srv_conf_t  *rcf;
+
+    peers = us->peer.data;
+
+    if (peers->shpool) {
+
+        rcf = ngx_http_conf_upstream_srv_conf(us,
+                                              ngx_http_upstream_random_module);
+
+        if (rcf->ranges) {
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+                           "free ranges: %p", rcf->ranges);
+            ngx_free(rcf->ranges);
+            rcf->ranges = NULL;
+        }
+    }
+
+#endif
+
+    ngx_http_upstream_free_round_robin(us);
+}
+
+
 static ngx_int_t
 ngx_http_upstream_update_random(ngx_pool_t *pool,
     ngx_http_upstream_srv_conf_t *us)
@@ -465,6 +494,7 @@
     }
 
     uscf->peer.init_upstream = ngx_http_upstream_init_random;
+    uscf->peer.free_upstream = ngx_http_upstream_free_random;
 
     uscf->flags = NGX_HTTP_UPSTREAM_CREATE
                   |NGX_HTTP_UPSTREAM_WEIGHT
diff -r f8d9fb94eab2 -r 8edb4003177d src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/http/ngx_http_upstream.c	Mon Feb 26 20:00:18 2024 +0000
@@ -189,6 +189,8 @@
     ngx_http_upstream_t *u, ngx_connection_t *c);
 #endif
 
+static void ngx_http_upstream_worker_cleanup(ngx_cycle_t *cycle);
+
 
 static ngx_http_upstream_header_t  ngx_http_upstream_headers_in[] = {
 
@@ -368,7 +370,7 @@
     NULL,                                  /* init process */
     NULL,                                  /* init thread */
     NULL,                                  /* exit thread */
-    NULL,                                  /* exit process */
+    ngx_http_upstream_worker_cleanup,      /* exit process */
     NULL,                                  /* exit master */
     NGX_MODULE_V1_PADDING
 };
@@ -6829,3 +6831,29 @@
 
     return NGX_CONF_OK;
 }
+
+
+static void
+ngx_http_upstream_worker_cleanup(ngx_cycle_t *cycle)
+{
+    ngx_uint_t                       i;
+    ngx_http_upstream_free_pt        free;
+    ngx_http_upstream_srv_conf_t   **uscfp;
+    ngx_http_upstream_main_conf_t   *umcf;
+
+    umcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_upstream_module);
+
+    if (umcf) {
+
+        uscfp = umcf->upstreams.elts;
+
+        for (i = 0; i < umcf->upstreams.nelts; i++) {
+
+            free = uscfp[i]->peer.free_upstream
+                       ? uscfp[i]->peer.free_upstream
+                       : ngx_http_upstream_free_round_robin;
+
+            free(uscfp[i]);
+        }
+    }
+}
diff -r f8d9fb94eab2 -r 8edb4003177d src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/http/ngx_http_upstream.h	Mon Feb 26 20:00:18 2024 +0000
@@ -82,11 +82,13 @@
     ngx_http_upstream_srv_conf_t *us);
 typedef ngx_int_t (*ngx_http_upstream_init_peer_pt)(ngx_http_request_t *r,
     ngx_http_upstream_srv_conf_t *us);
+typedef void (*ngx_http_upstream_free_pt)(ngx_http_upstream_srv_conf_t *us);
 
 
 typedef struct {
     ngx_http_upstream_init_pt        init_upstream;
     ngx_http_upstream_init_peer_pt   init;
+    ngx_http_upstream_free_pt        free_upstream;
     void                            *data;
 } ngx_http_upstream_peer_t;
 
diff -r f8d9fb94eab2 -r 8edb4003177d src/http/ngx_http_upstream_round_robin.c
--- a/src/http/ngx_http_upstream_round_robin.c	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/http/ngx_http_upstream_round_robin.c	Mon Feb 26 20:00:18 2024 +0000
@@ -851,3 +851,34 @@
 }
 
 #endif
+
+
+void
+ngx_http_upstream_free_round_robin(ngx_http_upstream_srv_conf_t *us)
+{
+#if (NGX_HTTP_SSL)
+
+    ngx_uint_t                     i;
+    ngx_http_upstream_rr_peer_t   *peer;
+    ngx_http_upstream_rr_peers_t  *peers;
+
+    peers = us->peer.data;
+
+#if (NGX_HTTP_UPSTREAM_ZONE)
+    if (peers->shpool) {
+        return;
+    }
+#endif
+
+    for (peer = peers->peer, i = 0; peer; peer = peer->next, i++) {
+
+        if (peer->ssl_session) {
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+                           "free session: %p", peer->ssl_session);
+            ngx_ssl_free_session(peer->ssl_session);
+            peer->ssl_session = NULL;
+        }
+    }
+
+#endif
+}
diff -r f8d9fb94eab2 -r 8edb4003177d src/http/ngx_http_upstream_round_robin.h
--- a/src/http/ngx_http_upstream_round_robin.h	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/http/ngx_http_upstream_round_robin.h	Mon Feb 26 20:00:18 2024 +0000
@@ -144,6 +144,7 @@
     void *data);
 void ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,
     void *data, ngx_uint_t state);
+void ngx_http_upstream_free_round_robin(ngx_http_upstream_srv_conf_t *us);
 
 #if (NGX_HTTP_SSL)
 ngx_int_t
diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream.c
--- a/src/stream/ngx_stream_upstream.c	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/stream/ngx_stream_upstream.c	Mon Feb 26 20:00:18 2024 +0000
@@ -25,6 +25,8 @@
 static void *ngx_stream_upstream_create_main_conf(ngx_conf_t *cf);
 static char *ngx_stream_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
 
+static void ngx_stream_upstream_worker_cleanup(ngx_cycle_t *cycle);
+
 
 static ngx_command_t  ngx_stream_upstream_commands[] = {
 
@@ -68,7 +70,7 @@
     NULL,                                  /* init process */
     NULL,                                  /* init thread */
     NULL,                                  /* exit thread */
-    NULL,                                  /* exit process */
+    ngx_stream_upstream_worker_cleanup,    /* exit process */
     NULL,                                  /* exit master */
     NGX_MODULE_V1_PADDING
 };
@@ -713,3 +715,30 @@
 
     return NGX_CONF_OK;
 }
+
+
+static void
+ngx_stream_upstream_worker_cleanup(ngx_cycle_t *cycle)
+{
+    ngx_uint_t                         i;
+    ngx_stream_upstream_free_pt        free;
+    ngx_stream_upstream_srv_conf_t   **uscfp;
+    ngx_stream_upstream_main_conf_t   *umcf;
+
+    umcf = ngx_stream_cycle_get_module_main_conf(cycle,
+                                                 ngx_stream_upstream_module);
+
+    if (umcf) {
+
+        uscfp = umcf->upstreams.elts;
+
+        for (i = 0; i < umcf->upstreams.nelts; i++) {
+
+            free = uscfp[i]->peer.free_upstream
+                       ? uscfp[i]->peer.free_upstream
+                       : ngx_stream_upstream_free_round_robin;
+
+            free(uscfp[i]);
+        }
+    }
+}
diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream.h
--- a/src/stream/ngx_stream_upstream.h	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/stream/ngx_stream_upstream.h	Mon Feb 26 20:00:18 2024 +0000
@@ -40,11 +40,13 @@
     ngx_stream_upstream_srv_conf_t *us);
 typedef ngx_int_t (*ngx_stream_upstream_init_peer_pt)(ngx_stream_session_t *s,
     ngx_stream_upstream_srv_conf_t *us);
+typedef void (*ngx_stream_upstream_free_pt)(ngx_stream_upstream_srv_conf_t *us);
 
 
 typedef struct {
     ngx_stream_upstream_init_pt        init_upstream;
     ngx_stream_upstream_init_peer_pt   init;
+    ngx_stream_upstream_free_pt        free_upstream;
     void                              *data;
 } ngx_stream_upstream_peer_t;
 
diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream_random_module.c
--- a/src/stream/ngx_stream_upstream_random_module.c	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/stream/ngx_stream_upstream_random_module.c	Mon Feb 26 20:00:18 2024 +0000
@@ -112,6 +112,35 @@
 }
 
 
+static void
+ngx_stream_upstream_free_random(ngx_stream_upstream_srv_conf_t *us)
+{
+#if (NGX_STREAM_UPSTREAM_ZONE)
+
+    ngx_stream_upstream_rr_peers_t         *peers;
+    ngx_stream_upstream_random_srv_conf_t  *rcf;
+
+    peers = us->peer.data;
+
+    if (peers->shpool) {
+
+        rcf = ngx_stream_conf_upstream_srv_conf(us,
+                                            ngx_stream_upstream_random_module);
+
+        if (rcf->ranges) {
+            ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0,
+                           "free ranges: %p", rcf->ranges);
+            ngx_free(rcf->ranges);
+            rcf->ranges = NULL;
+        }
+    }
+
+#endif
+
+    ngx_stream_upstream_free_round_robin(us);
+}
+
+
 static ngx_int_t
 ngx_stream_upstream_update_random(ngx_pool_t *pool,
     ngx_stream_upstream_srv_conf_t *us)
@@ -465,6 +494,7 @@
     }
 
     uscf->peer.init_upstream = ngx_stream_upstream_init_random;
+    uscf->peer.free_upstream = ngx_stream_upstream_free_random;
 
     uscf->flags = NGX_STREAM_UPSTREAM_CREATE
                   |NGX_STREAM_UPSTREAM_WEIGHT
diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream_round_robin.c
--- a/src/stream/ngx_stream_upstream_round_robin.c	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/stream/ngx_stream_upstream_round_robin.c	Mon Feb 26 20:00:18 2024 +0000
@@ -883,3 +883,34 @@
 }
 
 #endif
+
+
+void
+ngx_stream_upstream_free_round_robin(ngx_stream_upstream_srv_conf_t *us)
+{
+#if (NGX_STREAM_SSL)
+
+    ngx_uint_t                       i;
+    ngx_stream_upstream_rr_peer_t   *peer;
+    ngx_stream_upstream_rr_peers_t  *peers;
+
+    peers = us->peer.data;
+
+#if (NGX_STREAM_UPSTREAM_ZONE)
+    if (peers->shpool) {
+        return;
+    }
+#endif
+
+    for (peer = peers->peer, i = 0; peer; peer = peer->next, i++) {
+
+        if (peer->ssl_session) {
+            ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ngx_cycle->log, 0,
+                           "free session: %p", peer->ssl_session);
+            ngx_ssl_free_session(peer->ssl_session);
+            peer->ssl_session = NULL;
+        }
+    }
+
+#endif
+}
diff -r f8d9fb94eab2 -r 8edb4003177d src/stream/ngx_stream_upstream_round_robin.h
--- a/src/stream/ngx_stream_upstream_round_robin.h	Mon Feb 26 20:00:16 2024 +0000
+++ b/src/stream/ngx_stream_upstream_round_robin.h	Mon Feb 26 20:00:18 2024 +0000
@@ -142,6 +142,7 @@
     void *data);
 void ngx_stream_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,
     void *data, ngx_uint_t state);
+void ngx_stream_upstream_free_round_robin(ngx_stream_upstream_srv_conf_t *us);
 
 
 #endif /* _NGX_STREAM_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ */


More information about the nginx-devel mailing list