aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuslan Ermilov <ru@nginx.com>2017-08-04 17:03:10 +0300
committerRuslan Ermilov <ru@nginx.com>2017-08-04 17:03:10 +0300
commitc9a81b29b5a7699f3c25c83b6ee9e0c2a07f5f79 (patch)
treef7317f3dcd42527510833c263678a31d1187f0c3
parentc09bba400d233331f1b405e18c6912a30502dee9 (diff)
downloadnginx-c9a81b29b5a7699f3c25c83b6ee9e0c2a07f5f79.tar.gz
nginx-c9a81b29b5a7699f3c25c83b6ee9e0c2a07f5f79.zip
Upstream: copy peer data in shared memory.
This, in addition to 1eb753aa8e5e, fixes "upstream zone" on Windows.
-rw-r--r--src/http/modules/ngx_http_upstream_zone_module.c77
-rw-r--r--src/stream/ngx_stream_upstream_zone_module.c77
2 files changed, 138 insertions, 16 deletions
diff --git a/src/http/modules/ngx_http_upstream_zone_module.c b/src/http/modules/ngx_http_upstream_zone_module.c
index 401167bc7..d340b481f 100644
--- a/src/http/modules/ngx_http_upstream_zone_module.c
+++ b/src/http/modules/ngx_http_upstream_zone_module.c
@@ -16,6 +16,8 @@ static ngx_int_t ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone,
void *data);
static ngx_http_upstream_rr_peers_t *ngx_http_upstream_zone_copy_peers(
ngx_slab_pool_t *shpool, ngx_http_upstream_srv_conf_t *uscf);
+static ngx_http_upstream_rr_peer_t *ngx_http_upstream_zone_copy_peer(
+ ngx_http_upstream_rr_peers_t *peers, ngx_http_upstream_rr_peer_t *src);
static ngx_command_t ngx_http_upstream_zone_commands[] = {
@@ -215,14 +217,11 @@ ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool,
for (peerp = &peers->peer; *peerp; peerp = &peer->next) {
/* pool is unlocked */
- peer = ngx_slab_calloc_locked(shpool,
- sizeof(ngx_http_upstream_rr_peer_t));
+ peer = ngx_http_upstream_zone_copy_peer(peers, *peerp);
if (peer == NULL) {
return NULL;
}
- ngx_memcpy(peer, *peerp, sizeof(ngx_http_upstream_rr_peer_t));
-
*peerp = peer;
}
@@ -243,14 +242,11 @@ ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool,
for (peerp = &backup->peer; *peerp; peerp = &peer->next) {
/* pool is unlocked */
- peer = ngx_slab_calloc_locked(shpool,
- sizeof(ngx_http_upstream_rr_peer_t));
+ peer = ngx_http_upstream_zone_copy_peer(backup, *peerp);
if (peer == NULL) {
return NULL;
}
- ngx_memcpy(peer, *peerp, sizeof(ngx_http_upstream_rr_peer_t));
-
*peerp = peer;
}
@@ -262,3 +258,68 @@ done:
return peers;
}
+
+
+static ngx_http_upstream_rr_peer_t *
+ngx_http_upstream_zone_copy_peer(ngx_http_upstream_rr_peers_t *peers,
+ ngx_http_upstream_rr_peer_t *src)
+{
+ ngx_slab_pool_t *pool;
+ ngx_http_upstream_rr_peer_t *dst;
+
+ pool = peers->shpool;
+
+ dst = ngx_slab_calloc_locked(pool, sizeof(ngx_http_upstream_rr_peer_t));
+ if (dst == NULL) {
+ return NULL;
+ }
+
+ if (src) {
+ ngx_memcpy(dst, src, sizeof(ngx_http_upstream_rr_peer_t));
+ dst->sockaddr = NULL;
+ dst->name.data = NULL;
+ dst->server.data = NULL;
+ }
+
+ dst->sockaddr = ngx_slab_calloc_locked(pool, NGX_SOCKADDRLEN);
+ if (dst->sockaddr == NULL) {
+ goto failed;
+ }
+
+ dst->name.data = ngx_slab_calloc_locked(pool, NGX_SOCKADDR_STRLEN);
+ if (dst->name.data == NULL) {
+ goto failed;
+ }
+
+ if (src) {
+ ngx_memcpy(dst->sockaddr, src->sockaddr, src->socklen);
+ ngx_memcpy(dst->name.data, src->name.data, src->name.len);
+
+ dst->server.data = ngx_slab_alloc_locked(pool, src->server.len);
+ if (dst->server.data == NULL) {
+ goto failed;
+ }
+
+ ngx_memcpy(dst->server.data, src->server.data, src->server.len);
+ }
+
+ return dst;
+
+failed:
+
+ if (dst->server.data) {
+ ngx_slab_free_locked(pool, dst->server.data);
+ }
+
+ if (dst->name.data) {
+ ngx_slab_free_locked(pool, dst->name.data);
+ }
+
+ if (dst->sockaddr) {
+ ngx_slab_free_locked(pool, dst->sockaddr);
+ }
+
+ ngx_slab_free_locked(pool, dst);
+
+ return NULL;
+}
diff --git a/src/stream/ngx_stream_upstream_zone_module.c b/src/stream/ngx_stream_upstream_zone_module.c
index a02d684df..4f72188f6 100644
--- a/src/stream/ngx_stream_upstream_zone_module.c
+++ b/src/stream/ngx_stream_upstream_zone_module.c
@@ -16,6 +16,8 @@ static ngx_int_t ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone,
void *data);
static ngx_stream_upstream_rr_peers_t *ngx_stream_upstream_zone_copy_peers(
ngx_slab_pool_t *shpool, ngx_stream_upstream_srv_conf_t *uscf);
+static ngx_stream_upstream_rr_peer_t *ngx_stream_upstream_zone_copy_peer(
+ ngx_stream_upstream_rr_peers_t *peers, ngx_stream_upstream_rr_peer_t *src);
static ngx_command_t ngx_stream_upstream_zone_commands[] = {
@@ -212,14 +214,11 @@ ngx_stream_upstream_zone_copy_peers(ngx_slab_pool_t *shpool,
for (peerp = &peers->peer; *peerp; peerp = &peer->next) {
/* pool is unlocked */
- peer = ngx_slab_calloc_locked(shpool,
- sizeof(ngx_stream_upstream_rr_peer_t));
+ peer = ngx_stream_upstream_zone_copy_peer(peers, *peerp);
if (peer == NULL) {
return NULL;
}
- ngx_memcpy(peer, *peerp, sizeof(ngx_stream_upstream_rr_peer_t));
-
*peerp = peer;
}
@@ -240,14 +239,11 @@ ngx_stream_upstream_zone_copy_peers(ngx_slab_pool_t *shpool,
for (peerp = &backup->peer; *peerp; peerp = &peer->next) {
/* pool is unlocked */
- peer = ngx_slab_calloc_locked(shpool,
- sizeof(ngx_stream_upstream_rr_peer_t));
+ peer = ngx_stream_upstream_zone_copy_peer(backup, *peerp);
if (peer == NULL) {
return NULL;
}
- ngx_memcpy(peer, *peerp, sizeof(ngx_stream_upstream_rr_peer_t));
-
*peerp = peer;
}
@@ -259,3 +255,68 @@ done:
return peers;
}
+
+
+static ngx_stream_upstream_rr_peer_t *
+ngx_stream_upstream_zone_copy_peer(ngx_stream_upstream_rr_peers_t *peers,
+ ngx_stream_upstream_rr_peer_t *src)
+{
+ ngx_slab_pool_t *pool;
+ ngx_stream_upstream_rr_peer_t *dst;
+
+ pool = peers->shpool;
+
+ dst = ngx_slab_calloc_locked(pool, sizeof(ngx_stream_upstream_rr_peer_t));
+ if (dst == NULL) {
+ return NULL;
+ }
+
+ if (src) {
+ ngx_memcpy(dst, src, sizeof(ngx_stream_upstream_rr_peer_t));
+ dst->sockaddr = NULL;
+ dst->name.data = NULL;
+ dst->server.data = NULL;
+ }
+
+ dst->sockaddr = ngx_slab_calloc_locked(pool, NGX_SOCKADDRLEN);
+ if (dst->sockaddr == NULL) {
+ goto failed;
+ }
+
+ dst->name.data = ngx_slab_calloc_locked(pool, NGX_SOCKADDR_STRLEN);
+ if (dst->name.data == NULL) {
+ goto failed;
+ }
+
+ if (src) {
+ ngx_memcpy(dst->sockaddr, src->sockaddr, src->socklen);
+ ngx_memcpy(dst->name.data, src->name.data, src->name.len);
+
+ dst->server.data = ngx_slab_alloc_locked(pool, src->server.len);
+ if (dst->server.data == NULL) {
+ goto failed;
+ }
+
+ ngx_memcpy(dst->server.data, src->server.data, src->server.len);
+ }
+
+ return dst;
+
+failed:
+
+ if (dst->server.data) {
+ ngx_slab_free_locked(pool, dst->server.data);
+ }
+
+ if (dst->name.data) {
+ ngx_slab_free_locked(pool, dst->name.data);
+ }
+
+ if (dst->sockaddr) {
+ ngx_slab_free_locked(pool, dst->sockaddr);
+ }
+
+ ngx_slab_free_locked(pool, dst);
+
+ return NULL;
+}