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 }