1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Valentin V. Bartenev
5 * Copyright (C) NGINX, Inc.
6 */
7
8#include <nxt_main.h>

--- 25 unchanged lines hidden (view full) ---

34 u_char *title;
35 nxt_str_t detail;
36 ssize_t offset;
37 nxt_uint_t line;
38 nxt_uint_t column;
39} nxt_controller_response_t;
40
41
42static nxt_int_t nxt_controller_prefork(nxt_task_t *task,
43 nxt_process_t *process, nxt_mp_t *mp);
44static nxt_int_t nxt_controller_start(nxt_task_t *task,
45 nxt_process_data_t *data);
46static void nxt_controller_process_new_port_handler(nxt_task_t *task,
47 nxt_port_recv_msg_t *msg);
48static void nxt_controller_send_current_conf(nxt_task_t *task);
49static void nxt_controller_router_ready_handler(nxt_task_t *task,
50 nxt_port_recv_msg_t *msg);
51static void nxt_controller_remove_pid_handler(nxt_task_t *task,
52 nxt_port_recv_msg_t *msg);
53static nxt_int_t nxt_controller_conf_default(void);
54static void nxt_controller_conf_init_handler(nxt_task_t *task,
55 nxt_port_recv_msg_t *msg, void *data);
56static void nxt_controller_flush_requests(nxt_task_t *task);
57static nxt_int_t nxt_controller_conf_send(nxt_task_t *task,
58 nxt_conf_value_t *conf, nxt_port_rpc_handler_t handler, void *data);
59
60static void nxt_controller_conn_init(nxt_task_t *task, void *obj, void *data);

--- 23 unchanged lines hidden (view full) ---

84 nxt_controller_request_t *req, nxt_str_t *path);
85static nxt_bool_t nxt_controller_check_postpone_request(nxt_task_t *task);
86#if (NXT_TLS)
87static void nxt_controller_process_cert(nxt_task_t *task,
88 nxt_controller_request_t *req, nxt_str_t *path);
89static void nxt_controller_process_cert_save(nxt_task_t *task,
90 nxt_port_recv_msg_t *msg, void *data);
91static nxt_bool_t nxt_controller_cert_in_use(nxt_str_t *name);
92static void nxt_controller_cert_cleanup(nxt_task_t *task, void *obj,
93 void *data);
94#endif
95static void nxt_controller_conf_handler(nxt_task_t *task,
96 nxt_port_recv_msg_t *msg, void *data);
97static void nxt_controller_conf_store(nxt_task_t *task,
98 nxt_conf_value_t *conf);
99static void nxt_controller_response(nxt_task_t *task,
100 nxt_controller_request_t *req, nxt_controller_response_t *resp);
101static u_char *nxt_controller_date(u_char *buf, nxt_realtime_t *now,

--- 15 unchanged lines hidden (view full) ---

117
118
119static const nxt_event_conn_state_t nxt_controller_conn_read_state;
120static const nxt_event_conn_state_t nxt_controller_conn_body_read_state;
121static const nxt_event_conn_state_t nxt_controller_conn_write_state;
122static const nxt_event_conn_state_t nxt_controller_conn_close_state;
123
124
117nxt_port_handlers_t nxt_controller_process_port_handlers = {
118 .quit = nxt_worker_process_quit_handler,
125static const nxt_port_handlers_t nxt_controller_process_port_handlers = {
126 .quit = nxt_signal_quit_handler,
127 .new_port = nxt_controller_process_new_port_handler,
128 .change_file = nxt_port_change_log_file_handler,
129 .mmap = nxt_port_mmap_handler,
130 .process_ready = nxt_controller_router_ready_handler,
131 .data = nxt_port_data_handler,
124 .remove_pid = nxt_port_remove_pid_handler,
132 .remove_pid = nxt_controller_remove_pid_handler,
133 .rpc_ready = nxt_port_rpc_handler,
134 .rpc_error = nxt_port_rpc_handler,
135};
136
137
130nxt_int_t
131nxt_controller_start(nxt_task_t *task, void *data)
138const nxt_process_init_t nxt_controller_process = {
139 .name = "controller",
140 .type = NXT_PROCESS_CONTROLLER,
141 .prefork = nxt_controller_prefork,
142 .restart = 1,
143 .setup = nxt_process_core_setup,
144 .start = nxt_controller_start,
145 .port_handlers = &nxt_controller_process_port_handlers,
146 .signals = nxt_process_signals,
147};
148
149
150static nxt_int_t
151nxt_controller_prefork(nxt_task_t *task, nxt_process_t *process, nxt_mp_t *mp)
152{
153 ssize_t n;
154 nxt_int_t ret;
155 nxt_str_t *conf;
156 nxt_file_t file;
157 nxt_runtime_t *rt;
158 nxt_file_info_t fi;
159 nxt_controller_init_t ctrl_init;
160
161 nxt_log(task, NXT_LOG_INFO, "controller started");
162
163 rt = task->thread->runtime;
164
165 nxt_memzero(&ctrl_init, sizeof(nxt_controller_init_t));
166
167 conf = &ctrl_init.conf;
168
169 nxt_memzero(&file, sizeof(nxt_file_t));
170
171 file.name = (nxt_file_name_t *) rt->conf;
172
173 ret = nxt_file_open(task, &file, NXT_FILE_RDONLY, NXT_FILE_OPEN, 0);
174
175 if (ret == NXT_OK) {
176 ret = nxt_file_info(&file, &fi);
177
178 if (nxt_fast_path(ret == NXT_OK && nxt_is_file(&fi))) {
179 conf->length = nxt_file_size(&fi);
180 conf->start = nxt_mp_alloc(mp, conf->length);
181 if (nxt_slow_path(conf->start == NULL)) {
182 nxt_file_close(task, &file);
183 return NXT_ERROR;
184 }
185
186 n = nxt_file_read(&file, conf->start, conf->length, 0);
187
188 if (nxt_slow_path(n != (ssize_t) conf->length)) {
189 conf->start = NULL;
190 conf->length = 0;
191
192 nxt_alert(task, "failed to restore previous configuration: "
193 "cannot read the file");
194 }
195 }
196
197 nxt_file_close(task, &file);
198 }
199
200#if (NXT_TLS)
201 ctrl_init.certs = nxt_cert_store_load(task, mp);
202
203 nxt_mp_cleanup(mp, nxt_controller_cert_cleanup, task, ctrl_init.certs, rt);
204#endif
205
206 process->data.controller = ctrl_init;
207
208 return NXT_OK;
209}
210
211
212#if (NXT_TLS)
213
214static void
215nxt_controller_cert_cleanup(nxt_task_t *task, void *obj, void *data)
216{
217 pid_t main_pid;
218 nxt_array_t *certs;
219 nxt_runtime_t *rt;
220
221 certs = obj;
222 rt = data;
223
224 main_pid = rt->port_by_type[NXT_PROCESS_MAIN]->pid;
225
226 if (nxt_pid == main_pid && certs != NULL) {
227 nxt_cert_store_release(certs);
228 }
229}
230
231#endif
232
233
234static nxt_int_t
235nxt_controller_start(nxt_task_t *task, nxt_process_data_t *data)
236{
237 nxt_mp_t *mp;
238 nxt_int_t ret;
239 nxt_str_t *json;
240 nxt_conf_value_t *conf;
241 nxt_conf_validation_t vldt;
242 nxt_controller_init_t *init;
243
244 ret = nxt_http_fields_hash(&nxt_controller_fields_hash,
245 nxt_controller_request_fields,
246 nxt_nitems(nxt_controller_request_fields));
247
248 if (nxt_slow_path(ret != NXT_OK)) {
249 return NXT_ERROR;
250 }
251
252 nxt_queue_init(&nxt_controller_waiting_requests);
253
150 init = data;
254 init = &data->controller;
255
256#if (NXT_TLS)
153
257 if (init->certs != NULL) {
258 nxt_cert_info_init(task, init->certs);
259 nxt_cert_store_release(init->certs);
260 }
158
261#endif
262
263 json = &init->conf;
264
265 if (json->start == NULL) {
266 return NXT_OK;
267 }
268
269 mp = nxt_mp_create(1024, 128, 256, 32);
270 if (nxt_slow_path(mp == NULL)) {
271 return NXT_ERROR;
272 }
273
274 conf = nxt_conf_json_parse_str(mp, json);
173 nxt_free(json->start);
174
275 if (nxt_slow_path(conf == NULL)) {
276 nxt_alert(task, "failed to restore previous configuration: "
277 "file is corrupted or not enough memory");
278
279 nxt_mp_destroy(mp);
280 return NXT_OK;
281 }
282

--- 107 unchanged lines hidden (view full) ---

390 nxt_controller_router_ready = 1;
391
392 if (router_port != NULL) {
393 nxt_controller_send_current_conf(task);
394 }
395}
396
397
398static void
399nxt_controller_remove_pid_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
400{
401 nxt_pid_t pid;
402 nxt_process_t *process;
403 nxt_runtime_t *rt;
404
405 rt = task->thread->runtime;
406
407 nxt_assert(nxt_buf_used_size(msg->buf) == sizeof(pid));
408
409 nxt_memcpy(&pid, msg->buf->mem.pos, sizeof(pid));
410
411 process = nxt_runtime_process_find(rt, pid);
412 if (process != NULL && nxt_process_type(process) == NXT_PROCESS_ROUTER) {
413 nxt_controller_router_ready = 0;
414 }
415
416 nxt_port_remove_pid_handler(task, msg);
417}
418
419
420static nxt_int_t
421nxt_controller_conf_default(void)
422{
423 nxt_mp_t *mp;
424 nxt_conf_value_t *conf;
425
426 static const nxt_str_t json
427 = nxt_string("{ \"listeners\": {}, \"applications\": {} }");

--- 1446 unchanged lines hidden ---