Line data Source code
1 :
2 : /*
3 : * Copyright (C) Yichun Zhang (agentzh)
4 : */
5 :
6 :
7 : #ifndef DDEBUG
8 : #define DDEBUG 0
9 : #endif
10 : #include "ddebug.h"
11 :
12 :
13 : #include "ngx_http_lua_initworkerby.h"
14 : #include "ngx_http_lua_util.h"
15 :
16 :
17 : static u_char *ngx_http_lua_log_init_worker_error(ngx_log_t *log,
18 : u_char *buf, size_t len);
19 :
20 :
21 : ngx_int_t
22 18 : ngx_http_lua_init_worker(ngx_cycle_t *cycle)
23 : {
24 : char *rv;
25 : void *cur, *prev;
26 : ngx_uint_t i;
27 : ngx_conf_t conf;
28 : ngx_cycle_t *fake_cycle;
29 : ngx_module_t **modules;
30 : ngx_open_file_t *file, *ofile;
31 : ngx_list_part_t *part;
32 18 : ngx_connection_t *c = NULL;
33 : ngx_http_module_t *module;
34 18 : ngx_http_request_t *r = NULL;
35 : ngx_http_lua_ctx_t *ctx;
36 : ngx_http_conf_ctx_t *conf_ctx, http_ctx;
37 : ngx_http_lua_loc_conf_t *top_llcf;
38 : ngx_http_lua_main_conf_t *lmcf;
39 : ngx_http_core_loc_conf_t *clcf, *top_clcf;
40 :
41 18 : lmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_lua_module);
42 :
43 18 : if (lmcf == NULL
44 18 : || lmcf->init_worker_handler == NULL
45 0 : || lmcf->lua == NULL)
46 : {
47 18 : return NGX_OK;
48 : }
49 :
50 0 : conf_ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
51 0 : http_ctx.main_conf = conf_ctx->main_conf;
52 :
53 0 : top_clcf = conf_ctx->loc_conf[ngx_http_core_module.ctx_index];
54 0 : top_llcf = conf_ctx->loc_conf[ngx_http_lua_module.ctx_index];
55 :
56 0 : ngx_memzero(&conf, sizeof(ngx_conf_t));
57 :
58 0 : conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, cycle->log);
59 0 : if (conf.temp_pool == NULL) {
60 0 : return NGX_ERROR;
61 : }
62 :
63 0 : conf.temp_pool->log = cycle->log;
64 :
65 : /* we fake a temporary ngx_cycle_t here because some
66 : * modules' merge conf handler may produce side effects in
67 : * cf->cycle (like ngx_proxy vs cf->cycle->paths).
68 : * also, we cannot allocate our temp cycle on the stack
69 : * because some modules like ngx_http_core_module reference
70 : * addresses within cf->cycle (i.e., via "&cf->cycle->new_log")
71 : */
72 :
73 0 : fake_cycle = ngx_palloc(cycle->pool, sizeof(ngx_cycle_t));
74 0 : if (fake_cycle == NULL) {
75 0 : goto failed;
76 : }
77 :
78 0 : ngx_memcpy(fake_cycle, cycle, sizeof(ngx_cycle_t));
79 :
80 : #if defined(nginx_version) && nginx_version >= 9007
81 :
82 0 : ngx_queue_init(&fake_cycle->reusable_connections_queue);
83 :
84 : #endif
85 :
86 0 : if (ngx_array_init(&fake_cycle->listening, cycle->pool,
87 : cycle->listening.nelts || 1,
88 : sizeof(ngx_listening_t))
89 : != NGX_OK)
90 : {
91 0 : goto failed;
92 : }
93 :
94 : #if defined(nginx_version) && nginx_version >= 1003007
95 :
96 0 : if (ngx_array_init(&fake_cycle->paths, cycle->pool, cycle->paths.nelts || 1,
97 : sizeof(ngx_path_t *))
98 : != NGX_OK)
99 : {
100 0 : goto failed;
101 : }
102 :
103 : #endif
104 :
105 0 : part = &cycle->open_files.part;
106 0 : ofile = part->elts;
107 :
108 0 : if (ngx_list_init(&fake_cycle->open_files, cycle->pool, part->nelts || 1,
109 : sizeof(ngx_open_file_t))
110 : != NGX_OK)
111 : {
112 0 : goto failed;
113 : }
114 :
115 0 : for (i = 0; /* void */ ; i++) {
116 :
117 0 : if (i >= part->nelts) {
118 0 : if (part->next == NULL) {
119 0 : break;
120 : }
121 0 : part = part->next;
122 0 : ofile = part->elts;
123 0 : i = 0;
124 : }
125 :
126 0 : file = ngx_list_push(&fake_cycle->open_files);
127 0 : if (file == NULL) {
128 0 : goto failed;
129 : }
130 :
131 0 : ngx_memcpy(file, ofile, sizeof(ngx_open_file_t));
132 : }
133 :
134 0 : if (ngx_list_init(&fake_cycle->shared_memory, cycle->pool, 1,
135 : sizeof(ngx_shm_zone_t))
136 : != NGX_OK)
137 : {
138 0 : goto failed;
139 : }
140 :
141 0 : conf.ctx = &http_ctx;
142 0 : conf.cycle = fake_cycle;
143 0 : conf.pool = fake_cycle->pool;
144 0 : conf.log = cycle->log;
145 :
146 0 : http_ctx.loc_conf = ngx_pcalloc(conf.pool,
147 : sizeof(void *) * ngx_http_max_module);
148 0 : if (http_ctx.loc_conf == NULL) {
149 0 : return NGX_ERROR;
150 : }
151 :
152 0 : http_ctx.srv_conf = ngx_pcalloc(conf.pool,
153 : sizeof(void *) * ngx_http_max_module);
154 0 : if (http_ctx.srv_conf == NULL) {
155 0 : return NGX_ERROR;
156 : }
157 :
158 : #if defined(nginx_version) && nginx_version >= 1009011
159 0 : modules = cycle->modules;
160 : #else
161 : modules = ngx_modules;
162 : #endif
163 :
164 0 : for (i = 0; modules[i]; i++) {
165 0 : if (modules[i]->type != NGX_HTTP_MODULE) {
166 0 : continue;
167 : }
168 :
169 0 : module = modules[i]->ctx;
170 :
171 0 : if (module->create_srv_conf) {
172 0 : cur = module->create_srv_conf(&conf);
173 0 : if (cur == NULL) {
174 0 : return NGX_ERROR;
175 : }
176 :
177 0 : http_ctx.srv_conf[modules[i]->ctx_index] = cur;
178 :
179 0 : if (module->merge_srv_conf) {
180 0 : prev = module->create_srv_conf(&conf);
181 0 : if (prev == NULL) {
182 0 : return NGX_ERROR;
183 : }
184 :
185 0 : rv = module->merge_srv_conf(&conf, prev, cur);
186 0 : if (rv != NGX_CONF_OK) {
187 0 : goto failed;
188 : }
189 : }
190 : }
191 :
192 0 : if (module->create_loc_conf) {
193 0 : cur = module->create_loc_conf(&conf);
194 0 : if (cur == NULL) {
195 0 : return NGX_ERROR;
196 : }
197 :
198 0 : http_ctx.loc_conf[modules[i]->ctx_index] = cur;
199 :
200 0 : if (module->merge_loc_conf) {
201 0 : if (modules[i] == &ngx_http_lua_module) {
202 0 : prev = top_llcf;
203 :
204 0 : } else if (modules[i] == &ngx_http_core_module) {
205 0 : prev = top_clcf;
206 :
207 : } else {
208 0 : prev = module->create_loc_conf(&conf);
209 0 : if (prev == NULL) {
210 0 : return NGX_ERROR;
211 : }
212 : }
213 :
214 0 : rv = module->merge_loc_conf(&conf, prev, cur);
215 0 : if (rv != NGX_CONF_OK) {
216 0 : goto failed;
217 : }
218 : }
219 : }
220 : }
221 :
222 0 : ngx_destroy_pool(conf.temp_pool);
223 0 : conf.temp_pool = NULL;
224 :
225 0 : c = ngx_http_lua_create_fake_connection(NULL);
226 0 : if (c == NULL) {
227 0 : goto failed;
228 : }
229 :
230 0 : c->log->handler = ngx_http_lua_log_init_worker_error;
231 :
232 0 : r = ngx_http_lua_create_fake_request(c);
233 0 : if (r == NULL) {
234 0 : goto failed;
235 : }
236 :
237 0 : r->main_conf = http_ctx.main_conf;
238 0 : r->srv_conf = http_ctx.srv_conf;
239 0 : r->loc_conf = http_ctx.loc_conf;
240 :
241 0 : clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
242 :
243 : #if defined(nginx_version) && nginx_version >= 1003014
244 :
245 : # if nginx_version >= 1009000
246 :
247 0 : ngx_set_connection_log(r->connection, clcf->error_log);
248 :
249 : # else
250 :
251 : ngx_http_set_connection_log(r->connection, clcf->error_log);
252 :
253 : # endif
254 :
255 : #else
256 :
257 : c->log->file = clcf->error_log->file;
258 :
259 : if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
260 : c->log->log_level = clcf->error_log->log_level;
261 : }
262 :
263 : #endif
264 :
265 0 : ctx = ngx_http_lua_create_ctx(r);
266 0 : if (ctx == NULL) {
267 0 : goto failed;
268 : }
269 :
270 0 : ctx->context = NGX_HTTP_LUA_CONTEXT_INIT_WORKER;
271 0 : ctx->cur_co_ctx = NULL;
272 0 : r->read_event_handler = ngx_http_block_reading;
273 :
274 0 : ngx_http_lua_set_req(lmcf->lua, r);
275 :
276 0 : (void) lmcf->init_worker_handler(cycle->log, lmcf, lmcf->lua);
277 :
278 0 : ngx_destroy_pool(c->pool);
279 0 : return NGX_OK;
280 :
281 0 : failed:
282 :
283 0 : if (conf.temp_pool) {
284 0 : ngx_destroy_pool(conf.temp_pool);
285 : }
286 :
287 0 : if (c) {
288 0 : ngx_http_lua_close_fake_connection(c);
289 : }
290 :
291 0 : return NGX_ERROR;
292 : }
293 :
294 :
295 : ngx_int_t
296 0 : ngx_http_lua_init_worker_by_inline(ngx_log_t *log,
297 : ngx_http_lua_main_conf_t *lmcf, lua_State *L)
298 : {
299 : int status;
300 :
301 0 : status = luaL_loadbuffer(L, (char *) lmcf->init_worker_src.data,
302 : lmcf->init_worker_src.len, "=init_worker_by_lua")
303 0 : || ngx_http_lua_do_call(log, L);
304 :
305 0 : return ngx_http_lua_report(log, L, status, "init_worker_by_lua");
306 : }
307 :
308 :
309 : ngx_int_t
310 0 : ngx_http_lua_init_worker_by_file(ngx_log_t *log, ngx_http_lua_main_conf_t *lmcf,
311 : lua_State *L)
312 : {
313 : int status;
314 :
315 0 : status = luaL_loadfile(L, (char *) lmcf->init_worker_src.data)
316 0 : || ngx_http_lua_do_call(log, L);
317 :
318 0 : return ngx_http_lua_report(log, L, status, "init_worker_by_lua_file");
319 : }
320 :
321 :
322 : static u_char *
323 0 : ngx_http_lua_log_init_worker_error(ngx_log_t *log, u_char *buf, size_t len)
324 : {
325 : u_char *p;
326 :
327 0 : if (log->action) {
328 0 : p = ngx_snprintf(buf, len, " while %s", log->action);
329 0 : len -= p - buf;
330 0 : buf = p;
331 : }
332 :
333 0 : return ngx_snprintf(buf, len, ", context: init_worker_by_lua*");
334 : }
|