Mercurial > hg > nginx
comparison src/stream/ngx_stream_upstream_zone_module.c @ 6123:caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Wed, 22 Apr 2015 18:37:34 +0300 |
parents | 61d7ae76647d |
children | 68c106e6fa0a |
comparison
equal
deleted
inserted
replaced
6122:85f00678e54a | 6123:caa103acf180 |
---|---|
12 | 12 |
13 static char *ngx_stream_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, | 13 static char *ngx_stream_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, |
14 void *conf); | 14 void *conf); |
15 static ngx_int_t ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, | 15 static ngx_int_t ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, |
16 void *data); | 16 void *data); |
17 static ngx_int_t ngx_stream_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, | |
18 ngx_stream_upstream_srv_conf_t *uscf); | |
17 | 19 |
18 | 20 |
19 static ngx_command_t ngx_stream_upstream_zone_commands[] = { | 21 static ngx_command_t ngx_stream_upstream_zone_commands[] = { |
20 | 22 |
21 { ngx_string("zone"), | 23 { ngx_string("zone"), |
22 NGX_STREAM_UPS_CONF|NGX_CONF_TAKE2, | 24 NGX_STREAM_UPS_CONF|NGX_CONF_TAKE12, |
23 ngx_stream_upstream_zone, | 25 ngx_stream_upstream_zone, |
24 0, | 26 0, |
25 0, | 27 0, |
26 NULL }, | 28 NULL }, |
27 | 29 |
55 | 57 |
56 | 58 |
57 static char * | 59 static char * |
58 ngx_stream_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 60 ngx_stream_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
59 { | 61 { |
60 ssize_t size; | 62 ssize_t size; |
61 ngx_str_t *value; | 63 ngx_str_t *value; |
62 ngx_stream_upstream_srv_conf_t *uscf; | 64 ngx_stream_upstream_srv_conf_t *uscf; |
65 ngx_stream_upstream_main_conf_t *umcf; | |
63 | 66 |
64 uscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_upstream_module); | 67 uscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_upstream_module); |
68 umcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_upstream_module); | |
65 | 69 |
66 value = cf->args->elts; | 70 value = cf->args->elts; |
67 | 71 |
68 if (!value[1].len) { | 72 if (!value[1].len) { |
69 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 73 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
70 "invalid zone name \"%V\"", &value[1]); | 74 "invalid zone name \"%V\"", &value[1]); |
71 return NGX_CONF_ERROR; | 75 return NGX_CONF_ERROR; |
72 } | 76 } |
73 | 77 |
74 size = ngx_parse_size(&value[2]); | 78 if (cf->args->nelts == 3) { |
75 | 79 size = ngx_parse_size(&value[2]); |
76 if (size == NGX_ERROR) { | 80 |
77 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 81 if (size == NGX_ERROR) { |
78 "invalid zone size \"%V\"", &value[2]); | 82 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
79 return NGX_CONF_ERROR; | 83 "invalid zone size \"%V\"", &value[2]); |
80 } | 84 return NGX_CONF_ERROR; |
81 | 85 } |
82 if (size < (ssize_t) (8 * ngx_pagesize)) { | 86 |
83 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 87 if (size < (ssize_t) (8 * ngx_pagesize)) { |
84 "zone \"%V\" is too small", &value[1]); | 88 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
85 return NGX_CONF_ERROR; | 89 "zone \"%V\" is too small", &value[1]); |
90 return NGX_CONF_ERROR; | |
91 } | |
92 | |
93 } else { | |
94 size = 0; | |
86 } | 95 } |
87 | 96 |
88 uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size, | 97 uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size, |
89 &ngx_stream_upstream_module); | 98 &ngx_stream_upstream_module); |
90 if (uscf->shm_zone == NULL) { | 99 if (uscf->shm_zone == NULL) { |
91 return NGX_CONF_ERROR; | 100 return NGX_CONF_ERROR; |
92 } | 101 } |
93 | 102 |
94 if (uscf->shm_zone->data) { | |
95 uscf = uscf->shm_zone->data; | |
96 | |
97 ngx_conf_log_error(NGX_LOG_WARN, cf, 0, | |
98 "upstream \"%V\" in %s:%ui " | |
99 "is already bound to zone \"%V\"", | |
100 &uscf->host, uscf->file_name, uscf->line, | |
101 &value[1]); | |
102 return NGX_CONF_ERROR; | |
103 } | |
104 | |
105 uscf->shm_zone->init = ngx_stream_upstream_init_zone; | 103 uscf->shm_zone->init = ngx_stream_upstream_init_zone; |
106 uscf->shm_zone->data = uscf; | 104 uscf->shm_zone->data = umcf; |
107 | 105 |
108 uscf->shm_zone->noreuse = 1; | 106 uscf->shm_zone->noreuse = 1; |
109 | 107 |
110 return NGX_CONF_OK; | 108 return NGX_CONF_OK; |
111 } | 109 } |
112 | 110 |
113 | 111 |
114 static ngx_int_t | 112 static ngx_int_t |
115 ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data) | 113 ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data) |
116 { | 114 { |
117 ngx_stream_upstream_srv_conf_t *ouscf = data; | |
118 | |
119 size_t len; | 115 size_t len; |
116 ngx_uint_t i; | |
120 ngx_slab_pool_t *shpool; | 117 ngx_slab_pool_t *shpool; |
121 ngx_stream_upstream_rr_peer_t *peer, **peerp; | 118 ngx_stream_upstream_srv_conf_t *uscf, **uscfp; |
122 ngx_stream_upstream_rr_peers_t *peers, *backup; | 119 ngx_stream_upstream_main_conf_t *umcf; |
123 ngx_stream_upstream_srv_conf_t *uscf; | |
124 | |
125 uscf = shm_zone->data; | |
126 | |
127 if (ouscf) { | |
128 ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, | |
129 "zone \"%V\" cannot be reused", &shm_zone->shm.name); | |
130 return NGX_ERROR; | |
131 } | |
132 | 120 |
133 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; | 121 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; |
134 | 122 |
135 if (shm_zone->shm.exists) { | 123 if (shm_zone->shm.exists) { |
136 return NGX_ERROR; | 124 return NGX_ERROR; |
137 } | 125 } |
138 | |
139 | |
140 /* copy peers to shared memory */ | |
141 | 126 |
142 len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len; | 127 len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len; |
143 | 128 |
144 shpool->log_ctx = ngx_slab_alloc(shpool, len); | 129 shpool->log_ctx = ngx_slab_alloc(shpool, len); |
145 if (shpool->log_ctx == NULL) { | 130 if (shpool->log_ctx == NULL) { |
146 return NGX_ERROR; | 131 return NGX_ERROR; |
147 } | 132 } |
148 | 133 |
149 ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z", | 134 ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z", |
150 &shm_zone->shm.name); | 135 &shm_zone->shm.name); |
136 | |
137 | |
138 /* copy peers to shared memory */ | |
139 | |
140 umcf = shm_zone->data; | |
141 uscfp = umcf->upstreams.elts; | |
142 | |
143 for (i = 0; i < umcf->upstreams.nelts; i++) { | |
144 uscf = uscfp[i]; | |
145 | |
146 if (uscf->shm_zone != shm_zone) { | |
147 continue; | |
148 } | |
149 | |
150 if (ngx_stream_upstream_zone_copy_peers(shpool, uscf) != NGX_OK) { | |
151 return NGX_ERROR; | |
152 } | |
153 } | |
154 | |
155 return NGX_OK; | |
156 } | |
157 | |
158 | |
159 static ngx_int_t | |
160 ngx_stream_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, | |
161 ngx_stream_upstream_srv_conf_t *uscf) | |
162 { | |
163 ngx_stream_upstream_rr_peer_t *peer, **peerp; | |
164 ngx_stream_upstream_rr_peers_t *peers, *backup; | |
151 | 165 |
152 peers = ngx_slab_alloc(shpool, sizeof(ngx_stream_upstream_rr_peers_t)); | 166 peers = ngx_slab_alloc(shpool, sizeof(ngx_stream_upstream_rr_peers_t)); |
153 if (peers == NULL) { | 167 if (peers == NULL) { |
154 return NGX_ERROR; | 168 return NGX_ERROR; |
155 } | 169 } |