Mercurial > hg > nginx
annotate src/http/modules/ngx_http_upstream_zone_module.c @ 6949:ff0c8e11edbc
Simplified and improved sendfile() code on Linux.
The ngx_linux_sendfile() function is now used for both normal sendfile()
and sendfile in threads. The ngx_linux_sendfile_thread() function was
modified to use the same interface as ngx_linux_sendfile(), and is simply
called from ngx_linux_sendfile() when threads are enabled.
Special return code NGX_DONE is used to indicate that a thread task was
posted and no further actions are needed.
If number of bytes sent is less that what we were sending, we now always
retry sending. This is needed for sendfile() in threads as the number
of bytes we are sending might have been changed since the thread task
was posted. And this is also needed for Linux 4.3+, as sendfile() might
be interrupted at any time and provides no indication if it was interrupted
or not (ticket #1174).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 28 Mar 2017 18:15:39 +0300 |
parents | 341e4303d25b |
children | 1eb753aa8e5e |
rev | line source |
---|---|
6103 | 1 |
2 /* | |
3 * Copyright (C) Ruslan Ermilov | |
4 * Copyright (C) Nginx, Inc. | |
5 */ | |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
11 | |
12 | |
13 static char *ngx_http_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, | |
14 void *conf); | |
15 static ngx_int_t ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone, | |
16 void *data); | |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
17 static ngx_http_upstream_rr_peers_t *ngx_http_upstream_zone_copy_peers( |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
18 ngx_slab_pool_t *shpool, ngx_http_upstream_srv_conf_t *uscf); |
6103 | 19 |
20 | |
21 static ngx_command_t ngx_http_upstream_zone_commands[] = { | |
22 | |
23 { ngx_string("zone"), | |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
24 NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12, |
6103 | 25 ngx_http_upstream_zone, |
26 0, | |
27 0, | |
28 NULL }, | |
29 | |
30 ngx_null_command | |
31 }; | |
32 | |
33 | |
34 static ngx_http_module_t ngx_http_upstream_zone_module_ctx = { | |
35 NULL, /* preconfiguration */ | |
36 NULL, /* postconfiguration */ | |
37 | |
38 NULL, /* create main configuration */ | |
39 NULL, /* init main configuration */ | |
40 | |
41 NULL, /* create server configuration */ | |
42 NULL, /* merge server configuration */ | |
43 | |
44 NULL, /* create location configuration */ | |
45 NULL /* merge location configuration */ | |
46 }; | |
47 | |
48 | |
49 ngx_module_t ngx_http_upstream_zone_module = { | |
50 NGX_MODULE_V1, | |
51 &ngx_http_upstream_zone_module_ctx, /* module context */ | |
52 ngx_http_upstream_zone_commands, /* module directives */ | |
53 NGX_HTTP_MODULE, /* module type */ | |
54 NULL, /* init master */ | |
55 NULL, /* init module */ | |
56 NULL, /* init process */ | |
57 NULL, /* init thread */ | |
58 NULL, /* exit thread */ | |
59 NULL, /* exit process */ | |
60 NULL, /* exit master */ | |
61 NGX_MODULE_V1_PADDING | |
62 }; | |
63 | |
64 | |
65 static char * | |
66 ngx_http_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
67 { | |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
68 ssize_t size; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
69 ngx_str_t *value; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
70 ngx_http_upstream_srv_conf_t *uscf; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
71 ngx_http_upstream_main_conf_t *umcf; |
6103 | 72 |
73 uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); | |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
74 umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module); |
6103 | 75 |
76 value = cf->args->elts; | |
77 | |
78 if (!value[1].len) { | |
79 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
80 "invalid zone name \"%V\"", &value[1]); | |
81 return NGX_CONF_ERROR; | |
82 } | |
83 | |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
84 if (cf->args->nelts == 3) { |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
85 size = ngx_parse_size(&value[2]); |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
86 |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
87 if (size == NGX_ERROR) { |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
88 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
89 "invalid zone size \"%V\"", &value[2]); |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
90 return NGX_CONF_ERROR; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
91 } |
6103 | 92 |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
93 if (size < (ssize_t) (8 * ngx_pagesize)) { |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
94 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
95 "zone \"%V\" is too small", &value[1]); |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
96 return NGX_CONF_ERROR; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
97 } |
6103 | 98 |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
99 } else { |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
100 size = 0; |
6103 | 101 } |
102 | |
103 uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size, | |
104 &ngx_http_upstream_module); | |
105 if (uscf->shm_zone == NULL) { | |
106 return NGX_CONF_ERROR; | |
107 } | |
108 | |
109 uscf->shm_zone->init = ngx_http_upstream_init_zone; | |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
110 uscf->shm_zone->data = umcf; |
6103 | 111 |
112 uscf->shm_zone->noreuse = 1; | |
113 | |
114 return NGX_CONF_OK; | |
115 } | |
116 | |
117 | |
118 static ngx_int_t | |
119 ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data) | |
120 { | |
121 size_t len; | |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
122 ngx_uint_t i; |
6103 | 123 ngx_slab_pool_t *shpool; |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
124 ngx_http_upstream_rr_peers_t *peers, **peersp; |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
125 ngx_http_upstream_srv_conf_t *uscf, **uscfp; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
126 ngx_http_upstream_main_conf_t *umcf; |
6103 | 127 |
128 shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; | |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
129 umcf = shm_zone->data; |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
130 uscfp = umcf->upstreams.elts; |
6103 | 131 |
132 if (shm_zone->shm.exists) { | |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
133 peers = shpool->data; |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
134 |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
135 for (i = 0; i < umcf->upstreams.nelts; i++) { |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
136 uscf = uscfp[i]; |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
137 |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
138 if (uscf->shm_zone != shm_zone) { |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
139 continue; |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
140 } |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
141 |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
142 uscf->peer.data = peers; |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
143 peers = peers->zone_next; |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
144 } |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
145 |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
146 return NGX_OK; |
6103 | 147 } |
148 | |
149 len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len; | |
150 | |
151 shpool->log_ctx = ngx_slab_alloc(shpool, len); | |
152 if (shpool->log_ctx == NULL) { | |
153 return NGX_ERROR; | |
154 } | |
155 | |
156 ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z", | |
157 &shm_zone->shm.name); | |
158 | |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
159 |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
160 /* copy peers to shared memory */ |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
161 |
6214
341e4303d25b
Fixed strict aliasing warnings with old GCC versions.
Ruslan Ermilov <ru@nginx.com>
parents:
6198
diff
changeset
|
162 peersp = (ngx_http_upstream_rr_peers_t **) (void *) &shpool->data; |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
163 |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
164 for (i = 0; i < umcf->upstreams.nelts; i++) { |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
165 uscf = uscfp[i]; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
166 |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
167 if (uscf->shm_zone != shm_zone) { |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
168 continue; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
169 } |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
170 |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
171 peers = ngx_http_upstream_zone_copy_peers(shpool, uscf); |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
172 if (peers == NULL) { |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
173 return NGX_ERROR; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
174 } |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
175 |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
176 *peersp = peers; |
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
177 peersp = &peers->zone_next; |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
178 } |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
179 |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
180 return NGX_OK; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
181 } |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
182 |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
183 |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
184 static ngx_http_upstream_rr_peers_t * |
6123
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
185 ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool, |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
186 ngx_http_upstream_srv_conf_t *uscf) |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
187 { |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
188 ngx_http_upstream_rr_peer_t *peer, **peerp; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
189 ngx_http_upstream_rr_peers_t *peers, *backup; |
caa103acf180
Upstream: allow multiple upstreams to use the same shared zone.
Ruslan Ermilov <ru@nginx.com>
parents:
6103
diff
changeset
|
190 |
6103 | 191 peers = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t)); |
192 if (peers == NULL) { | |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
193 return NULL; |
6103 | 194 } |
195 | |
196 ngx_memcpy(peers, uscf->peer.data, sizeof(ngx_http_upstream_rr_peers_t)); | |
197 | |
198 peers->shpool = shpool; | |
199 | |
200 for (peerp = &peers->peer; *peerp; peerp = &peer->next) { | |
201 /* pool is unlocked */ | |
202 peer = ngx_slab_calloc_locked(shpool, | |
203 sizeof(ngx_http_upstream_rr_peer_t)); | |
204 if (peer == NULL) { | |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
205 return NULL; |
6103 | 206 } |
207 | |
208 ngx_memcpy(peer, *peerp, sizeof(ngx_http_upstream_rr_peer_t)); | |
209 | |
210 *peerp = peer; | |
211 } | |
212 | |
213 if (peers->next == NULL) { | |
214 goto done; | |
215 } | |
216 | |
217 backup = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t)); | |
218 if (backup == NULL) { | |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
219 return NULL; |
6103 | 220 } |
221 | |
222 ngx_memcpy(backup, peers->next, sizeof(ngx_http_upstream_rr_peers_t)); | |
223 | |
224 backup->shpool = shpool; | |
225 | |
226 for (peerp = &backup->peer; *peerp; peerp = &peer->next) { | |
227 /* pool is unlocked */ | |
228 peer = ngx_slab_calloc_locked(shpool, | |
229 sizeof(ngx_http_upstream_rr_peer_t)); | |
230 if (peer == NULL) { | |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
231 return NULL; |
6103 | 232 } |
233 | |
234 ngx_memcpy(peer, *peerp, sizeof(ngx_http_upstream_rr_peer_t)); | |
235 | |
236 *peerp = peer; | |
237 } | |
238 | |
239 peers->next = backup; | |
240 | |
241 done: | |
242 | |
243 uscf->peer.data = peers; | |
244 | |
6198
311d232ad803
Upstream: fixed shared upstreams on win32.
Ruslan Ermilov <ru@nginx.com>
parents:
6123
diff
changeset
|
245 return peers; |
6103 | 246 } |