1 /*
2
3 The uWSGI Emperor
4
5 */
6 #include "uwsgi.h"
7
8
9 extern struct uwsgi_server uwsgi;
10 extern char **environ;
11
12 void emperor_send_stats(int);
13
14 time_t emperor_throttle;
15 int emperor_throttle_level;
16 int emperor_warming_up = 1;
17
18 struct uwsgi_instance *ui;
19
20 time_t on_royal_death = 0;
21
22 /*
23
24 blacklist subsystem
25
26 failed unloyal vassals are blacklisted and throttled
27
28 */
29 struct uwsgi_emperor_blacklist_item {
30 char id[0xff];
31 struct timeval first_attempt;
32 struct timeval last_attempt;
33 int throttle_level;
34 int attempt;
35 struct uwsgi_emperor_blacklist_item *prev;
36 struct uwsgi_emperor_blacklist_item *next;
37 };
38
39 struct uwsgi_emperor_blacklist_item *emperor_blacklist;
40
41 /*
42 this should be placed in core/socket.c but we realized it was needed
43 only after 2.0 so we cannot change uwsgi.h
44
45 basically it is a stripped down bind_to_tcp/bind_to_unix with rollback
46 */
on_demand_bind(char * socket_name)47 static int on_demand_bind(char *socket_name) {
48 union uwsgi_sockaddr us;
49 socklen_t addr_len = sizeof(struct sockaddr_un);
50 char *is_tcp = strchr(socket_name, ':');
51 int af_family = is_tcp ? AF_INET : AF_UNIX;
52 int fd = socket(af_family, SOCK_STREAM, 0);
53 if (fd < 0)
54 return -1;
55
56 memset(&us, 0, sizeof(union uwsgi_sockaddr));
57
58 if (is_tcp) {
59 int reuse = 1;
60 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(int)) < 0) {
61 goto error;
62 }
63 us.sa_in.sin_family = AF_INET;
64 us.sa_in.sin_port = htons(atoi(is_tcp + 1));
65 *is_tcp = 0;
66 if (socket_name[0] != 0) {
67 us.sa_in.sin_addr.s_addr = inet_addr(socket_name);
68 }
69 else {
70 us.sa_in.sin_addr.s_addr = INADDR_ANY;
71 }
72 *is_tcp = ':';
73 addr_len = sizeof(struct sockaddr_in);
74 }
75 else {
76 if (unlink(socket_name) != 0 && errno != ENOENT) {
77 goto error;
78 }
79
80 us.sa_un.sun_family = AF_UNIX;
81 memcpy(us.sa_un.sun_path, socket_name, UMIN(strlen(socket_name), 102));
82 addr_len = strlen(socket_name) + ((void *) us.sa_un.sun_path - (void *) &us.sa_un);
83 }
84
85 if (bind(fd, (struct sockaddr *) &us, addr_len) != 0) {
86 goto error;
87 }
88
89 if (!is_tcp) {
90 if (chmod(socket_name, 0666)) {
91 goto error;
92 }
93 }
94
95 if (listen(fd, uwsgi.listen_queue) != 0) {
96 goto error;
97 }
98
99 return fd;
100
101 error:
102 close(fd);
103 return -1;
104 }
105
uwsgi_emperor_blacklist_check(char * id)106 struct uwsgi_emperor_blacklist_item *uwsgi_emperor_blacklist_check(char *id) {
107 struct uwsgi_emperor_blacklist_item *uebi = emperor_blacklist;
108 while (uebi) {
109 if (!strcmp(uebi->id, id)) {
110 return uebi;
111 }
112 uebi = uebi->next;
113 }
114 return NULL;
115 }
116
117
uwsgi_emperor_blacklist_add(char * id)118 void uwsgi_emperor_blacklist_add(char *id) {
119
120 // check if the item is already in the blacklist
121 struct uwsgi_emperor_blacklist_item *uebi = uwsgi_emperor_blacklist_check(id);
122 if (uebi) {
123 gettimeofday(&uebi->last_attempt, NULL);
124 if (uebi->throttle_level < (uwsgi.emperor_max_throttle * 1000)) {
125 uebi->throttle_level += (uwsgi.emperor_throttle * 1000);
126 }
127 else {
128 uwsgi_log_verbose("[emperor] maximum throttle level for vassal %s reached !!!\n", id);
129 uebi->throttle_level = uebi->throttle_level / 2;
130 }
131 uebi->attempt++;
132 if (uebi->attempt == 2) {
133 uwsgi_log_verbose("[emperor] unloyal bad behaving vassal found: %s throttling it...\n", id);
134 }
135 return;
136 }
137
138 uebi = emperor_blacklist;
139 if (!uebi) {
140 uebi = uwsgi_calloc(sizeof(struct uwsgi_emperor_blacklist_item));
141 uebi->prev = NULL;
142 emperor_blacklist = uebi;
143 }
144 else {
145 while (uebi) {
146 if (!uebi->next) {
147 uebi->next = uwsgi_calloc(sizeof(struct uwsgi_emperor_blacklist_item));
148 uebi->next->prev = uebi;
149 uebi = uebi->next;
150 break;
151 }
152 uebi = uebi->next;
153 }
154 }
155
156 snprintf(uebi->id, 0xff, "%s", id);
157 gettimeofday(&uebi->first_attempt, NULL);
158 memcpy(&uebi->last_attempt, &uebi->first_attempt, sizeof(struct timeval));
159 uebi->throttle_level = uwsgi.emperor_throttle;
160 uebi->next = NULL;
161
162 }
163
uwsgi_emperor_blacklist_remove(char * id)164 void uwsgi_emperor_blacklist_remove(char *id) {
165
166 struct uwsgi_emperor_blacklist_item *uebi = uwsgi_emperor_blacklist_check(id);
167 if (!uebi)
168 return;
169
170 // ok let's remove the item
171 //is it the first item ?
172 if (uebi == emperor_blacklist) {
173 emperor_blacklist = uebi->next;
174 }
175
176 struct uwsgi_emperor_blacklist_item *next = uebi->next;
177 struct uwsgi_emperor_blacklist_item *prev = uebi->prev;
178
179 if (next)
180 next->prev = prev;
181
182 if (prev)
183 prev->next = next;
184
185 free(uebi);
186 }
187
188
189 struct uwsgi_emperor_scanner *emperor_scanners;
190
has_extra_extension(char * name)191 static int has_extra_extension(char *name) {
192 struct uwsgi_string_list *usl = uwsgi.emperor_extra_extension;
193 while (usl) {
194 if (uwsgi_endswith(name, usl->value)) {
195 return 1;
196 }
197 usl = usl->next;
198 }
199 return 0;
200 }
201
uwsgi_emperor_is_valid(char * name)202 int uwsgi_emperor_is_valid(char *name) {
203
204 if (uwsgi_endswith(name, ".xml") || uwsgi_endswith(name, ".ini") || uwsgi_endswith(name, ".yml") || uwsgi_endswith(name, ".yaml") || uwsgi_endswith(name, ".js") || uwsgi_endswith(name, ".json") || has_extra_extension(name)) {
205
206 if (strlen(name) < 0xff) {
207 return 1;
208 }
209 }
210
211
212 return 0;
213 }
214
emperor_check_on_demand_socket(char * filename)215 static char *emperor_check_on_demand_socket(char *filename) {
216 size_t len = 0;
217 if (uwsgi.emperor_on_demand_extension) {
218 char *tmp = uwsgi_concat2(filename, uwsgi.emperor_on_demand_extension);
219 int fd = open(tmp, O_RDONLY);
220 free(tmp);
221 if (fd < 0)
222 return NULL;
223 char *ret = uwsgi_read_fd(fd, &len, 1);
224 close(fd);
225 // change the first non printable character to 0
226 size_t i;
227 for (i = 0; i < len; i++) {
228 if (ret[i] < 32) {
229 ret[i] = 0;
230 break;
231 }
232 }
233 if (ret[0] == 0) {
234 free(ret);
235 return NULL;
236 }
237 return ret;
238 }
239 else if (uwsgi.emperor_on_demand_directory) {
240 // we need to build the socket path automagically
241 char *start_of_vassal_name = uwsgi_get_last_char(filename, '/');
242 if (!start_of_vassal_name) {
243 start_of_vassal_name = filename;
244 }
245 else {
246 start_of_vassal_name++;
247 }
248 char *last_dot = uwsgi_get_last_char(filename, '.');
249 if (!last_dot)
250 return NULL;
251
252 return uwsgi_concat4n(uwsgi.emperor_on_demand_directory, strlen(uwsgi.emperor_on_demand_directory), "/", 1, start_of_vassal_name, last_dot - start_of_vassal_name, ".socket", 7);
253 }
254 else if (uwsgi.emperor_on_demand_exec) {
255 int cpipe[2];
256 if (pipe(cpipe)) {
257 uwsgi_error("emperor_check_on_demand_socket()pipe()");
258 return NULL;
259 }
260 char *cmd = uwsgi_concat4(uwsgi.emperor_on_demand_exec, " \"", filename, "\"");
261 int r = uwsgi_run_command(cmd, NULL, cpipe[1]);
262 free(cmd);
263 if (r < 0) {
264 close(cpipe[0]);
265 close(cpipe[1]);
266 return NULL;
267 }
268 char *ret = uwsgi_read_fd(cpipe[0], &len, 1);
269 close(cpipe[0]);
270 close(cpipe[1]);
271 // change the first non prinabel character to 0
272 size_t i;
273 for (i = 0; i < len; i++) {
274 if (ret[i] < 32) {
275 ret[i] = 0;
276 break;
277 }
278 }
279 if (ret[0] == 0) {
280 free(ret);
281 return NULL;
282 }
283 return ret;
284 }
285 return NULL;
286 }
287
288 // this is the monitor for non-glob directories
uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner * ues)289 void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *ues) {
290 struct uwsgi_instance *ui_current;
291 struct dirent *de;
292 struct stat st;
293
294 if (chdir(ues->arg)) {
295 uwsgi_error("chdir()");
296 return;
297 }
298
299 DIR *dir = opendir(".");
300 while ((de = readdir(dir)) != NULL) {
301
302 if (!uwsgi_emperor_is_valid(de->d_name))
303 continue;
304
305 if (uwsgi.emperor_nofollow) {
306 if (lstat(de->d_name, &st))
307 continue;
308 if (!S_ISLNK(st.st_mode) && !S_ISREG(st.st_mode))
309 continue;
310 }
311 else {
312 if (stat(de->d_name, &st))
313 continue;
314 if (!S_ISREG(st.st_mode))
315 continue;
316 }
317
318 ui_current = emperor_get(de->d_name);
319
320 uid_t t_uid = st.st_uid;
321 gid_t t_gid = st.st_gid;
322
323 if (uwsgi.emperor_tyrant && uwsgi.emperor_tyrant_nofollow) {
324 struct stat lst;
325 if (lstat(de->d_name, &lst)) {
326 uwsgi_error("[emperor-tyrant]/lstat()");
327 if (ui_current) {
328 uwsgi_log("!!! availability of file %s changed. stopping the instance... !!!\n", de->d_name);
329 emperor_stop(ui_current);
330 }
331 continue;
332 }
333 t_uid = lst.st_uid;
334 t_gid = lst.st_gid;
335 }
336
337 if (ui_current) {
338 // check if uid or gid are changed, in such case, stop the instance
339 if (uwsgi.emperor_tyrant) {
340 if (t_uid != ui_current->uid || t_gid != ui_current->gid) {
341 uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", de->d_name);
342 emperor_stop(ui_current);
343 continue;
344 }
345 }
346 // check if mtime is changed and the uWSGI instance must be reloaded
347 if (st.st_mtime > ui_current->last_mod) {
348 emperor_respawn(ui_current, st.st_mtime);
349 }
350 }
351 else {
352 char *socket_name = emperor_check_on_demand_socket(de->d_name);
353 emperor_add(ues, de->d_name, st.st_mtime, NULL, 0, t_uid, t_gid, socket_name);
354 if (socket_name)
355 free(socket_name);
356 }
357 }
358 closedir(dir);
359
360 // now check for removed instances
361 struct uwsgi_instance *c_ui = ui->ui_next;
362
363 while (c_ui) {
364 if (c_ui->scanner == ues) {
365 if (c_ui->zerg) {
366 char *colon = strrchr(c_ui->name, ':');
367 if (!colon) {
368 emperor_stop(c_ui);
369 }
370 else {
371 char *filename = uwsgi_calloc(0xff);
372 memcpy(filename, c_ui->name, colon - c_ui->name);
373 if (uwsgi.emperor_nofollow) {
374 if (lstat(filename, &st)) {
375 emperor_stop(c_ui);
376 }
377 }
378 else {
379 if (stat(filename, &st)) {
380 emperor_stop(c_ui);
381 }
382 }
383 free(filename);
384 }
385 }
386 else {
387 if (uwsgi.emperor_nofollow) {
388 if (lstat(c_ui->name, &st)) {
389 emperor_stop(c_ui);
390 }
391 }
392 else {
393 if (stat(c_ui->name, &st)) {
394 emperor_stop(c_ui);
395 }
396 }
397 }
398 }
399 c_ui = c_ui->ui_next;
400 }
401 }
402
403 // this is the monitor for glob patterns
uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner * ues)404 void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *ues) {
405
406 glob_t g;
407 int i;
408 struct stat st;
409 struct uwsgi_instance *ui_current;
410
411 if (chdir(uwsgi.cwd)) {
412 uwsgi_error("uwsgi_imperial_monitor_glob()/chdir()");
413 exit(1);
414 }
415
416 if (glob(ues->arg, GLOB_MARK | GLOB_NOCHECK, NULL, &g)) {
417 uwsgi_error("uwsgi_imperial_monitor_glob()/glob()");
418 return;
419 }
420
421 for (i = 0; i < (int) g.gl_pathc; i++) {
422
423 if (!uwsgi_emperor_is_valid(g.gl_pathv[i]))
424 continue;
425
426 if (uwsgi.emperor_nofollow) {
427 if (lstat(g.gl_pathv[i], &st))
428 continue;
429 if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode))
430 continue;
431 }
432 else {
433 if (stat(g.gl_pathv[i], &st))
434 continue;
435 if (!S_ISREG(st.st_mode))
436 continue;
437 }
438
439 ui_current = emperor_get(g.gl_pathv[i]);
440
441 uid_t t_uid = st.st_uid;
442 gid_t t_gid = st.st_gid;
443
444 if (uwsgi.emperor_tyrant && uwsgi.emperor_tyrant_nofollow) {
445 struct stat lst;
446 if (lstat(g.gl_pathv[i], &lst)) {
447 uwsgi_error("[emperor-tyrant]/lstat()");
448 if (ui_current) {
449 uwsgi_log("!!! availability of file %s changed. stopping the instance... !!!\n", g.gl_pathv[i]);
450 emperor_stop(ui_current);
451 }
452 continue;
453 }
454 t_uid = lst.st_uid;
455 t_gid = lst.st_gid;
456 }
457
458 if (ui_current) {
459 // check if uid or gid are changed, in such case, stop the instance
460 if (uwsgi.emperor_tyrant) {
461 if (t_uid != ui_current->uid || t_gid != ui_current->gid) {
462 uwsgi_log("!!! permissions of file %s changed. stopping the instance... !!!\n", g.gl_pathv[i]);
463 emperor_stop(ui_current);
464 continue;
465 }
466 }
467 // check if mtime is changed and the uWSGI instance must be reloaded
468 if (st.st_mtime > ui_current->last_mod) {
469 emperor_respawn(ui_current, st.st_mtime);
470 }
471 }
472 else {
473 char *socket_name = emperor_check_on_demand_socket(g.gl_pathv[i]);
474 emperor_add(ues, g.gl_pathv[i], st.st_mtime, NULL, 0, t_uid, t_gid, socket_name);
475 if (socket_name)
476 free(socket_name);
477 }
478
479 }
480 globfree(&g);
481
482 // now check for removed instances
483 struct uwsgi_instance *c_ui = ui->ui_next;
484
485 while (c_ui) {
486 if (c_ui->scanner == ues) {
487 if (c_ui->zerg) {
488 char *colon = strrchr(c_ui->name, ':');
489 if (!colon) {
490 emperor_stop(c_ui);
491 }
492 else {
493 char *filename = uwsgi_calloc(0xff);
494 memcpy(filename, c_ui->name, colon - c_ui->name);
495 if (uwsgi.emperor_nofollow) {
496 if (lstat(filename, &st)) {
497 emperor_stop(c_ui);
498 }
499 }
500 else {
501 if (stat(filename, &st)) {
502 emperor_stop(c_ui);
503 }
504 }
505 free(filename);
506 }
507 }
508 else {
509 if (uwsgi.emperor_nofollow) {
510 if (lstat(c_ui->name, &st)) {
511 emperor_stop(c_ui);
512 }
513 }
514 else {
515 if (stat(c_ui->name, &st)) {
516 emperor_stop(c_ui);
517 }
518 }
519 }
520 }
521 c_ui = c_ui->ui_next;
522 }
523
524
525 }
526
uwsgi_register_imperial_monitor(char * name,void (* init)(struct uwsgi_emperor_scanner *),void (* func)(struct uwsgi_emperor_scanner *))527 void uwsgi_register_imperial_monitor(char *name, void (*init) (struct uwsgi_emperor_scanner *), void (*func) (struct uwsgi_emperor_scanner *)) {
528
529 struct uwsgi_imperial_monitor *uim = uwsgi.emperor_monitors;
530 if (!uim) {
531 uim = uwsgi_calloc(sizeof(struct uwsgi_imperial_monitor));
532 uwsgi.emperor_monitors = uim;
533 }
534 else {
535 while (uim) {
536 if (!uim->next) {
537 uim->next = uwsgi_calloc(sizeof(struct uwsgi_imperial_monitor));
538 uim = uim->next;
539 break;
540 }
541 uim = uim->next;
542 }
543 }
544
545 uim->scheme = name;
546 uim->init = init;
547 uim->func = func;
548 uim->next = NULL;
549 }
550
551
552 // the sad death of an Emperor
royal_death(int signum)553 static void royal_death(int signum) {
554
555 if (on_royal_death) {
556 uwsgi_log("[emperor] *** RAGNAROK ALREADY EVOKED (mercyless in %d seconds)***\n", uwsgi.reload_mercy - (uwsgi_now() - on_royal_death));
557 return;
558 }
559
560 struct uwsgi_instance *c_ui = ui->ui_next;
561
562 if (uwsgi.vassals_stop_hook) {
563
564
565 while (c_ui) {
566 uwsgi_log("[emperor] running vassal stop-hook: %s %s\n", uwsgi.vassals_stop_hook, c_ui->name);
567 if (uwsgi.emperor_absolute_dir) {
568 if (setenv("UWSGI_VASSALS_DIR", uwsgi.emperor_absolute_dir, 1)) {
569 uwsgi_error("setenv()");
570 }
571 }
572 int stop_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_stop_hook, c_ui->name);
573 uwsgi_log("[emperor] %s stop-hook returned %d\n", c_ui->name, stop_hook_ret);
574 c_ui = c_ui->ui_next;
575 }
576 }
577
578 uwsgi_log("[emperor] *** RAGNAROK EVOKED ***\n");
579
580 while (c_ui) {
581 emperor_stop(c_ui);
582 c_ui = c_ui->ui_next;
583 }
584
585 if (!uwsgi.reload_mercy)
586 uwsgi.reload_mercy = 30;
587 on_royal_death = uwsgi_now();
588 }
589
590 // massive reload of vassals
emperor_massive_reload(int signum)591 static void emperor_massive_reload(int signum) {
592 struct uwsgi_instance *c_ui = ui->ui_next;
593
594 while (c_ui) {
595 emperor_respawn(c_ui, uwsgi_now());
596 c_ui = c_ui->ui_next;
597 }
598 }
599
600
emperor_stats()601 static void emperor_stats() {
602
603 struct uwsgi_instance *c_ui = ui->ui_next;
604
605 while (c_ui) {
606
607 uwsgi_log("vassal instance %s (last modified %lld) status %d loyal %d zerg %d\n", c_ui->name, (long long) c_ui->last_mod, c_ui->status, c_ui->loyal, c_ui->zerg);
608
609 c_ui = c_ui->ui_next;
610 }
611
612 }
613
emperor_get_by_fd(int fd)614 struct uwsgi_instance *emperor_get_by_fd(int fd) {
615
616 struct uwsgi_instance *c_ui = ui;
617
618 while (c_ui->ui_next) {
619 c_ui = c_ui->ui_next;
620
621 if (c_ui->pipe[0] == fd) {
622 return c_ui;
623 }
624 }
625 return NULL;
626 }
627
emperor_get_by_socket_fd(int fd)628 struct uwsgi_instance *emperor_get_by_socket_fd(int fd) {
629
630 struct uwsgi_instance *c_ui = ui;
631
632 while (c_ui->ui_next) {
633 c_ui = c_ui->ui_next;
634
635 // over engineering...
636 if (c_ui->on_demand_fd > -1 && c_ui->on_demand_fd == fd) {
637 return c_ui;
638 }
639 }
640 return NULL;
641 }
642
643
644
emperor_get(char * name)645 struct uwsgi_instance *emperor_get(char *name) {
646
647 struct uwsgi_instance *c_ui = ui;
648
649 while (c_ui->ui_next) {
650 c_ui = c_ui->ui_next;
651
652 if (!strcmp(c_ui->name, name)) {
653 return c_ui;
654 }
655 }
656 return NULL;
657 }
658
emperor_del(struct uwsgi_instance * c_ui)659 void emperor_del(struct uwsgi_instance *c_ui) {
660
661 struct uwsgi_instance *parent_ui = c_ui->ui_prev;
662 struct uwsgi_instance *child_ui = c_ui->ui_next;
663
664 parent_ui->ui_next = child_ui;
665 if (child_ui) {
666 child_ui->ui_prev = parent_ui;
667 }
668
669 // this will destroy the whole uWSGI instance (and workers)
670 if (c_ui->pipe[0] != -1)
671 close(c_ui->pipe[0]);
672 if (c_ui->pipe[1] != -1)
673 close(c_ui->pipe[1]);
674
675 if (c_ui->use_config) {
676 if (c_ui->pipe_config[0] != -1)
677 close(c_ui->pipe_config[0]);
678 if (c_ui->pipe_config[1] != -1)
679 close(c_ui->pipe_config[1]);
680 }
681
682 if (uwsgi.vassals_stop_hook) {
683 uwsgi_log("[emperor] running vassal stop-hook: %s %s\n", uwsgi.vassals_stop_hook, c_ui->name);
684 if (uwsgi.emperor_absolute_dir) {
685 if (setenv("UWSGI_VASSALS_DIR", uwsgi.emperor_absolute_dir, 1)) {
686 uwsgi_error("setenv()");
687 }
688 }
689 int stop_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_stop_hook, c_ui->name);
690 uwsgi_log("[emperor] %s stop-hook returned %d\n", c_ui->name, stop_hook_ret);
691 }
692
693 uwsgi_log_verbose("[emperor] removed uwsgi instance %s\n", c_ui->name);
694 // put the instance in the blacklist (or update its throttling value)
695 if (!c_ui->loyal && !uwsgi.emperor_no_blacklist) {
696 uwsgi_emperor_blacklist_add(c_ui->name);
697 }
698
699 if (c_ui->zerg) {
700 uwsgi.emperor_broodlord_count--;
701 }
702
703 if (c_ui->socket_name) {
704 free(c_ui->socket_name);
705 }
706
707 if (c_ui->config)
708 free(c_ui->config);
709
710 if (c_ui->on_demand_fd > -1) {
711 close(c_ui->on_demand_fd);
712 }
713
714 free(c_ui);
715
716 }
717
emperor_back_to_ondemand(struct uwsgi_instance * c_ui)718 void emperor_back_to_ondemand(struct uwsgi_instance *c_ui) {
719 if (c_ui->status > 0)
720 return;
721
722 // remove uWSGI instance
723
724 if (c_ui->pid != -1) {
725 if (write(c_ui->pipe[0], uwsgi.emperor_graceful_shutdown ? "\2" : "\0", 1) != 1) {
726 uwsgi_error("emperor_stop()/write()");
727 }
728 }
729
730 c_ui->status = 2;
731 c_ui->cursed_at = uwsgi_now();
732
733 uwsgi_log_verbose("[emperor] bringing back instance %s to on-demand mode\n", c_ui->name);
734 }
735
emperor_stop(struct uwsgi_instance * c_ui)736 void emperor_stop(struct uwsgi_instance *c_ui) {
737 if (c_ui->status == 1)
738 return;
739 // remove uWSGI instance
740
741 if (c_ui->pid != -1) {
742 if (write(c_ui->pipe[0], uwsgi.emperor_graceful_shutdown ? "\2" : "\0", 1) != 1) {
743 uwsgi_error("emperor_stop()/write()");
744 }
745 }
746
747 c_ui->status = 1;
748 c_ui->cursed_at = uwsgi_now();
749
750 uwsgi_log_verbose("[emperor] stop the uwsgi instance %s\n", c_ui->name);
751 }
752
emperor_curse(struct uwsgi_instance * c_ui)753 void emperor_curse(struct uwsgi_instance *c_ui) {
754 if (c_ui->status == 1)
755 return;
756 // curse uWSGI instance
757
758 // take in account on-demand mode
759 if (c_ui->status == 0)
760 c_ui->status = 1;
761 c_ui->cursed_at = uwsgi_now();
762
763 uwsgi_log_verbose("[emperor] curse the uwsgi instance %s (pid: %d)\n", c_ui->name, (int) c_ui->pid);
764
765 }
766
767 // send configuration (if required to the vassal)
emperor_push_config(struct uwsgi_instance * c_ui)768 static void emperor_push_config(struct uwsgi_instance *c_ui) {
769 struct uwsgi_header uh;
770
771 if (c_ui->use_config) {
772 uh.modifier1 = 115;
773 uh.pktsize = c_ui->config_len;
774 uh.modifier2 = 0;
775 if (write(c_ui->pipe_config[0], &uh, 4) != 4) {
776 uwsgi_error("[uwsgi-emperor] write() header config");
777 }
778 else {
779 if (write(c_ui->pipe_config[0], c_ui->config, c_ui->config_len) != (long) c_ui->config_len) {
780 uwsgi_error("[uwsgi-emperor] write() config");
781 }
782 }
783 }
784 }
785
emperor_respawn(struct uwsgi_instance * c_ui,time_t mod)786 void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) {
787
788 // if the vassal is being destroyed, do not honour respawns
789 if (c_ui->status > 0)
790 return;
791
792 // check if we are in on_demand mode (the respawn will be ignored)
793 if (c_ui->pid == -1 && c_ui->on_demand_fd > -1) {
794 c_ui->last_mod = mod;
795 // reset readyness
796 c_ui->ready = 0;
797 // reset accepting
798 c_ui->accepting = 0;
799 uwsgi_log_verbose("[emperor] updated configuration for \"on demand\" instance %s\n", c_ui->name);
800 return;
801 }
802
803 // reload the uWSGI instance
804 if (write(c_ui->pipe[0], "\1", 1) != 1) {
805 // the vassal could be already dead, better to curse it
806 uwsgi_error("emperor_respawn/write()");
807 emperor_curse(c_ui);
808 return;
809 }
810
811 // push the config to the config pipe (if needed)
812 emperor_push_config(c_ui);
813
814 c_ui->respawns++;
815 c_ui->last_mod = mod;
816 c_ui->last_run = uwsgi_now();
817 // reset readyness
818 c_ui->ready = 0;
819 // reset accepting
820 c_ui->accepting = 0;
821
822 uwsgi_log_verbose("[emperor] reload the uwsgi instance %s\n", c_ui->name);
823 }
824
emperor_add(struct uwsgi_emperor_scanner * ues,char * name,time_t born,char * config,uint32_t config_size,uid_t uid,gid_t gid,char * socket_name)825 void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid, char *socket_name) {
826
827 struct uwsgi_instance *c_ui = ui;
828 struct uwsgi_instance *n_ui = NULL;
829 struct timeval tv;
830
831 #ifdef UWSGI_DEBUG
832 uwsgi_log("\n\nVASSAL %s %d %.*s %d %d\n", name, born, config_size, config, uid, gid);
833 #endif
834
835 if (strlen(name) > (0xff - 1)) {
836 uwsgi_log("[emperor] invalid vassal name: %s\n", name);
837 return;
838 }
839
840
841 gettimeofday(&tv, NULL);
842 int now = tv.tv_sec;
843 uint64_t micros = (tv.tv_sec * 1000ULL * 1000ULL) + tv.tv_usec;
844
845 // blacklist check
846 struct uwsgi_emperor_blacklist_item *uebi = uwsgi_emperor_blacklist_check(name);
847 if (uebi) {
848 uint64_t i_micros = (uebi->last_attempt.tv_sec * 1000ULL * 1000ULL) + uebi->last_attempt.tv_usec + uebi->throttle_level;
849 if (i_micros > micros) {
850 return;
851 }
852 }
853
854 // TODO make it meaningful
855 if (now - emperor_throttle < 1) {
856 emperor_throttle_level = emperor_throttle_level * 2;
857 }
858 else {
859 if (emperor_throttle_level > uwsgi.emperor_throttle) {
860 emperor_throttle_level = emperor_throttle_level / 2;
861 }
862
863 if (emperor_throttle_level < uwsgi.emperor_throttle) {
864 emperor_throttle_level = uwsgi.emperor_throttle;
865 }
866 }
867
868 emperor_throttle = now;
869 #ifdef UWSGI_DEBUG
870 uwsgi_log("emperor throttle = %d\n", emperor_throttle_level);
871 #endif
872 /*
873 if (emperor_warming_up) {
874 if (emperor_throttle_level > 0) {
875 // wait 10 milliseconds in case of fork-bombing
876 // pretty random value, but should avoid the load average to increase
877 usleep(10 * 1000);
878 }
879 }
880 else {
881 usleep(emperor_throttle_level * 1000);
882 }
883 */
884
885 if (uwsgi.emperor_tyrant) {
886 if (uid == 0 || gid == 0) {
887 uwsgi_log("[emperor-tyrant] invalid permissions for vassal %s\n", name);
888 return;
889 }
890 }
891
892 while (c_ui->ui_next) {
893 c_ui = c_ui->ui_next;
894 }
895
896 n_ui = uwsgi_calloc(sizeof(struct uwsgi_instance));
897
898 if (config) {
899 n_ui->use_config = 1;
900 n_ui->config = config;
901 n_ui->config_len = config_size;
902 }
903
904 c_ui->ui_next = n_ui;
905 #ifdef UWSGI_DEBUG
906 uwsgi_log("c_ui->ui_next = %p\n", c_ui->ui_next);
907 #endif
908 n_ui->ui_prev = c_ui;
909
910 if (strchr(name, ':')) {
911 n_ui->zerg = 1;
912 uwsgi.emperor_broodlord_count++;
913 }
914
915 n_ui->scanner = ues;
916 memcpy(n_ui->name, name, strlen(name));
917 n_ui->born = born;
918 n_ui->uid = uid;
919 n_ui->gid = gid;
920 n_ui->last_mod = born;
921 // start non-ready
922 n_ui->last_ready = 0;
923 n_ui->ready = 0;
924 // start without loyalty
925 n_ui->last_loyal = 0;
926 n_ui->loyal = 0;
927
928 n_ui->first_run = uwsgi_now();
929 n_ui->last_run = n_ui->first_run;
930 n_ui->on_demand_fd = -1;
931 if (socket_name) {
932 n_ui->socket_name = uwsgi_str(socket_name);
933 }
934
935 n_ui->pid = -1;
936 n_ui->pipe[0] = -1;
937 n_ui->pipe[1] = -1;
938
939 n_ui->pipe_config[0] = -1;
940 n_ui->pipe_config[1] = -1;
941
942 // ok here we check if we need to bind to the specified socket or continue with the activation
943 if (socket_name) {
944 n_ui->on_demand_fd = on_demand_bind(socket_name);
945 if (n_ui->on_demand_fd < 0) {
946 uwsgi_error("emperor_add()/bind()");
947 emperor_del(n_ui);
948 return;
949 }
950
951 event_queue_add_fd_read(uwsgi.emperor_queue, n_ui->on_demand_fd);
952 uwsgi_log("[uwsgi-emperor] %s -> \"on demand\" instance detected, waiting for connections on socket \"%s\" ...\n", name, socket_name);
953 return;
954 }
955
956 if (uwsgi_emperor_vassal_start(n_ui)) {
957 // clear the vassal
958 emperor_del(n_ui);
959 }
960 }
961
962 static int uwsgi_emperor_spawn_vassal(struct uwsgi_instance *);
963
uwsgi_emperor_vassal_start(struct uwsgi_instance * n_ui)964 int uwsgi_emperor_vassal_start(struct uwsgi_instance *n_ui) {
965
966 pid_t pid;
967
968 if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe)) {
969 uwsgi_error("socketpair()");
970 return -1;
971 }
972 uwsgi_socket_nb(n_ui->pipe[0]);
973
974 event_queue_add_fd_read(uwsgi.emperor_queue, n_ui->pipe[0]);
975
976 if (n_ui->use_config) {
977 if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe_config)) {
978 uwsgi_error("socketpair()");
979 return -1;
980 }
981 uwsgi_socket_nb(n_ui->pipe_config[0]);
982 }
983
984 if (n_ui->zerg) {
985 uwsgi.emperor_broodlord_num++;
986 }
987
988 // TODO pre-start hook
989
990 // a new uWSGI instance will start
991 #if defined(__linux__) && !defined(OBSOLETE_LINUX_KERNEL) && !defined(__ia64__)
992 if (uwsgi.emperor_clone) {
993 char stack[PTHREAD_STACK_MIN];
994 pid = clone((int (*)(void *)) uwsgi_emperor_spawn_vassal, stack + PTHREAD_STACK_MIN, SIGCHLD | uwsgi.emperor_clone, (void *) n_ui);
995 }
996 else {
997 #endif
998 pid = fork();
999 #if defined(__linux__) && !defined(OBSOLETE_LINUX_KERNEL) && !defined(__ia64__)
1000 }
1001 #endif
1002 if (pid < 0) {
1003 uwsgi_error("uwsgi_emperor_spawn_vassal()/fork()")
1004 }
1005 else if (pid > 0) {
1006 n_ui->pid = pid;
1007 // close the right side of the pipe
1008 close(n_ui->pipe[1]);
1009 n_ui->pipe[1] = -1;
1010 /* THE ON-DEMAND file descriptor is left mapped to the emperor to allow fast-respawn
1011 // TODO add an option to force closing it
1012 // close the "on demand" socket
1013 if (n_ui->on_demand_fd > -1) {
1014 close(n_ui->on_demand_fd);
1015 n_ui->on_demand_fd = -1;
1016 }
1017 */
1018 if (n_ui->use_config) {
1019 close(n_ui->pipe_config[1]);
1020 n_ui->pipe_config[1] = -1;
1021 emperor_push_config(n_ui);
1022 }
1023
1024 // once the config is sent we can run hooks (they can fail)
1025 // exec hooks have access to all of the currently defined vars + UWSGI_VASSAL_PID, UWSGI_VASSAL_UID, UWSGI_VASSAL_GID, UWSGI_VASSAL_CONFIG
1026 uwsgi_hooks_run(uwsgi.hook_as_emperor, "as-emperor", 0);
1027 struct uwsgi_string_list *usl;
1028 uwsgi_foreach(usl, uwsgi.mount_as_emperor) {
1029 uwsgi_log("mounting \"%s\" (as-emperor for vassal \"%s\" pid: %d uid: %d gid: %d)...\n", usl->value, n_ui->name, n_ui->pid, n_ui->uid, n_ui->gid);
1030 if (uwsgi_mount_hook(usl->value)) {
1031 uwsgi_log("unable to mount %s\n", usl->value);
1032 }
1033 }
1034
1035 uwsgi_foreach(usl, uwsgi.umount_as_emperor) {
1036 uwsgi_log("un-mounting \"%s\" (as-emperor for vassal \"%s\" pid: %d uid: %d gid: %d)...\n", usl->value, n_ui->name, n_ui->pid, n_ui->uid, n_ui->gid);
1037 if (uwsgi_umount_hook(usl->value)) {
1038 uwsgi_log("unable to umount %s\n", usl->value);
1039 }
1040 }
1041 uwsgi_foreach(usl, uwsgi.exec_as_emperor) {
1042 uwsgi_log("running \"%s\" (as-emperor for vassal \"%s\" pid: %d uid: %d gid: %d)...\n", usl->value, n_ui->name, n_ui->pid, n_ui->uid, n_ui->gid);
1043 char *argv[4];
1044 argv[0] = uwsgi_concat2("UWSGI_VASSAL_CONFIG=", n_ui->name);
1045 char argv_pid[17 + 11];
1046 snprintf(argv_pid, 17 + 11, "UWSGI_VASSAL_PID=%d", (int) n_ui->pid);
1047 argv[1] = argv_pid;
1048 char argv_uid[17 + 11];
1049 snprintf(argv_uid, 17 + 11, "UWSGI_VASSAL_UID=%d", (int) n_ui->uid);
1050 argv[2] = argv_uid;
1051 char argv_gid[17 + 11];
1052 snprintf(argv_gid, 17 + 11, "UWSGI_VASSAL_GID=%d", (int) n_ui->gid);
1053 argv[3] = argv_gid;
1054 int ret = uwsgi_run_command_putenv_and_wait(NULL, usl->value, argv, 4);
1055 uwsgi_log("command \"%s\" exited with code: %d\n", usl->value, ret);
1056 free(argv[0]);
1057 }
1058 // 4 call hooks
1059 // config / config + pid / config + pid + uid + gid
1060 // call
1061 uwsgi_foreach(usl, uwsgi.call_as_emperor) {
1062 void (*func) (void) = dlsym(RTLD_DEFAULT, usl->value);
1063 if (!func) {
1064 uwsgi_log("unable to call function \"%s\"\n", usl->value);
1065 }
1066 else {
1067 func();
1068 }
1069 }
1070
1071 uwsgi_foreach(usl, uwsgi.call_as_emperor1) {
1072 void (*func) (char *) = dlsym(RTLD_DEFAULT, usl->value);
1073 if (!func) {
1074 uwsgi_log("unable to call function \"%s\"\n", usl->value);
1075 }
1076 else {
1077 func(n_ui->name);
1078 }
1079 }
1080
1081 uwsgi_foreach(usl, uwsgi.call_as_emperor2) {
1082 void (*func) (char *, pid_t) = dlsym(RTLD_DEFAULT, usl->value);
1083 if (!func) {
1084 uwsgi_log("unable to call function \"%s\"\n", usl->value);
1085 }
1086 else {
1087 func(n_ui->name, n_ui->pid);
1088 }
1089 }
1090
1091 uwsgi_foreach(usl, uwsgi.call_as_emperor4) {
1092 void (*func) (char *, pid_t, uid_t, gid_t) = dlsym(RTLD_DEFAULT, usl->value);
1093 if (!func) {
1094 uwsgi_log("unable to call function \"%s\"\n", usl->value);
1095 }
1096 else {
1097 func(n_ui->name, n_ui->pid, n_ui->uid, n_ui->gid);
1098 }
1099 }
1100 return 0;
1101 }
1102 else {
1103 uwsgi_emperor_spawn_vassal(n_ui);
1104 }
1105 return -1;
1106 }
1107
uwsgi_emperor_spawn_vassal(struct uwsgi_instance * n_ui)1108 static int uwsgi_emperor_spawn_vassal(struct uwsgi_instance *n_ui) {
1109 int i;
1110
1111 // run plugin hooks for the vassal
1112 for (i = 0; i < 256; i++) {
1113 if (uwsgi.p[i]->vassal) {
1114 uwsgi.p[i]->vassal(n_ui);
1115 }
1116 }
1117
1118 for (i = 0; i < uwsgi.gp_cnt; i++) {
1119 if (uwsgi.gp[i]->vassal) {
1120 uwsgi.gp[i]->vassal(n_ui);
1121 }
1122 }
1123
1124 #ifdef __linux__
1125 if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
1126 uwsgi_error("prctl()");
1127 }
1128 #ifdef CLONE_NEWUSER
1129 if (uwsgi.emperor_clone & CLONE_NEWUSER) {
1130 if (setuid(0)) {
1131 uwsgi_error("uwsgi_emperor_spawn_vassal()/setuid(0)");
1132 exit(1);
1133 }
1134 }
1135 #endif
1136
1137 #ifdef UWSGI_CAP
1138 #if defined(CAP_LAST_CAP) && defined(PR_CAPBSET_READ) && defined(PR_CAPBSET_DROP)
1139 if (uwsgi.emperor_cap && uwsgi.emperor_cap_count > 0) {
1140 int i;
1141 for (i = 0; i <= CAP_LAST_CAP; i++) {
1142
1143 int has_cap = prctl(PR_CAPBSET_READ, i, 0, 0, 0);
1144 if (has_cap == 1) {
1145 if (i == CAP_SETPCAP)
1146 continue;
1147 int j;
1148 int found = 0;
1149 for (j = 0; j < uwsgi.emperor_cap_count; j++) {
1150 if (uwsgi.emperor_cap[j] == (int) i) {
1151 found = 1;
1152 break;
1153 }
1154 }
1155 if (found)
1156 continue;
1157 if (prctl(PR_CAPBSET_DROP, i, 0, 0, 0)) {
1158 uwsgi_error("uwsgi_emperor_spawn_vassal()/prctl()");
1159 uwsgi_log_verbose("unable to drop capability %lu\n", i);
1160 exit(1);
1161 }
1162 }
1163 }
1164 // just for being paranoid
1165 #ifdef SECBIT_KEEP_CAPS
1166 if (prctl(SECBIT_KEEP_CAPS, 1, 0, 0, 0) < 0) {
1167 uwsgi_error("prctl()");
1168 exit(1);
1169 }
1170 #else
1171 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
1172 uwsgi_error("prctl()");
1173 exit(1);
1174 }
1175 #endif
1176 uwsgi_log("capabilities applied for vassal %s (pid: %d)\n", n_ui->name, (int) getpid());
1177 }
1178 #endif
1179 #endif
1180 #endif
1181
1182 if (uwsgi.emperor_tyrant) {
1183 uwsgi_log("[emperor-tyrant] dropping privileges to %d %d for instance %s\n", (int) n_ui->uid, (int) n_ui->gid, n_ui->name);
1184 if (setgid(n_ui->gid)) {
1185 uwsgi_error("setgid()");
1186 exit(1);
1187 }
1188 if (setgroups(0, NULL)) {
1189 uwsgi_error("setgroups()");
1190 exit(1);
1191 }
1192
1193 if (setuid(n_ui->uid)) {
1194 uwsgi_error("setuid()");
1195 exit(1);
1196 }
1197
1198 }
1199
1200 unsetenv("UWSGI_RELOADS");
1201 unsetenv("NOTIFY_SOCKET");
1202
1203 char *uef = uwsgi_num2str(n_ui->pipe[1]);
1204 if (setenv("UWSGI_EMPEROR_FD", uef, 1)) {
1205 uwsgi_error("setenv()");
1206 exit(1);
1207 }
1208 free(uef);
1209
1210 // add UWSGI_BROODLORD_NUM
1211 if (n_ui->zerg) {
1212 uef = uwsgi_num2str(uwsgi.emperor_broodlord_num);
1213 if (setenv("UWSGI_BROODLORD_NUM", uef, 1)) {
1214 uwsgi_error("setenv()");
1215 exit(1);
1216 }
1217 free(uef);
1218 }
1219
1220 if (n_ui->use_config) {
1221 uef = uwsgi_num2str(n_ui->pipe_config[1]);
1222 if (setenv("UWSGI_EMPEROR_FD_CONFIG", uef, 1)) {
1223 uwsgi_error("setenv()");
1224 exit(1);
1225 }
1226 free(uef);
1227 }
1228
1229 char **uenvs = environ;
1230 while (*uenvs) {
1231 if (!strncmp(*uenvs, "UWSGI_VASSAL_", 13) && strchr(*uenvs, '=')) {
1232 char *oe = uwsgi_concat2n(*uenvs, strchr(*uenvs, '=') - *uenvs, "", 0), *ne;
1233 #ifdef UNSETENV_VOID
1234 unsetenv(oe);
1235 #else
1236 if (unsetenv(oe)) {
1237 uwsgi_error("unsetenv()");
1238 free(oe);
1239 break;
1240 }
1241 #endif
1242 free(oe);
1243
1244 ne = uwsgi_concat2("UWSGI_", *uenvs + 13);
1245 #ifdef UWSGI_DEBUG
1246 uwsgi_log("putenv %s\n", ne);
1247 #endif
1248
1249 if (putenv(ne)) {
1250 uwsgi_error("putenv()");
1251 }
1252 // do not free ne as putenv will add it to the environ
1253 uenvs = environ;
1254 continue;
1255 }
1256 uenvs++;
1257 }
1258
1259 // close the left side of the pipe
1260 close(n_ui->pipe[0]);
1261
1262 if (n_ui->use_config) {
1263 close(n_ui->pipe_config[0]);
1264 }
1265
1266 int counter = 4;
1267 struct uwsgi_string_list *uct;
1268 uwsgi_foreach(uct, uwsgi.vassals_templates_before) counter += 2;
1269 uwsgi_foreach(uct, uwsgi.vassals_includes_before) counter += 2;
1270 uwsgi_foreach(uct, uwsgi.vassals_set) counter += 2;
1271 uwsgi_foreach(uct, uwsgi.vassals_templates) counter += 2;
1272 uwsgi_foreach(uct, uwsgi.vassals_includes) counter += 2;
1273
1274 char **vassal_argv = uwsgi_malloc(sizeof(char *) * counter);
1275 // set args
1276 vassal_argv[0] = uwsgi.emperor_wrapper ? uwsgi.emperor_wrapper : uwsgi.binary_path;
1277
1278 // reset counter
1279 counter = 1;
1280
1281 uwsgi_foreach(uct, uwsgi.vassals_templates_before) {
1282 vassal_argv[counter] = "--inherit";
1283 vassal_argv[counter + 1] = uct->value;
1284 counter += 2;
1285 }
1286
1287 uwsgi_foreach(uct, uwsgi.vassals_includes_before) {
1288 vassal_argv[counter] = "--include";
1289 vassal_argv[counter + 1] = uct->value;
1290 counter += 2;
1291 }
1292
1293 uwsgi_foreach(uct, uwsgi.vassals_set) {
1294 vassal_argv[counter] = "--set";
1295 vassal_argv[counter + 1] = uct->value;
1296 counter += 2;
1297 }
1298
1299 char *colon = NULL;
1300 if (uwsgi.emperor_broodlord) {
1301 colon = strchr(n_ui->name, ':');
1302 if (colon) {
1303 colon[0] = 0;
1304 }
1305 }
1306 // initialize to a default value
1307 vassal_argv[counter] = "--inherit";
1308
1309 if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".xml"))
1310 vassal_argv[counter] = "--xml";
1311 if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".ini"))
1312 vassal_argv[counter] = "--ini";
1313 if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".yml"))
1314 vassal_argv[counter] = "--yaml";
1315 if (!strcmp(n_ui->name + (strlen(n_ui->name) - 5), ".yaml"))
1316 vassal_argv[counter] = "--yaml";
1317 if (!strcmp(n_ui->name + (strlen(n_ui->name) - 3), ".js"))
1318 vassal_argv[counter] = "--json";
1319 if (!strcmp(n_ui->name + (strlen(n_ui->name) - 5), ".json"))
1320 vassal_argv[counter] = "--json";
1321 struct uwsgi_string_list *usl = uwsgi.emperor_extra_extension;
1322 while (usl) {
1323 if (uwsgi_endswith(n_ui->name, usl->value)) {
1324 vassal_argv[counter] = "--config";
1325 break;
1326 }
1327 usl = usl->next;
1328 }
1329 if (colon)
1330 colon[0] = ':';
1331
1332 // start config filename...
1333 counter++;
1334
1335 vassal_argv[counter] = n_ui->name;
1336 if (uwsgi.emperor_magic_exec) {
1337 if (!access(n_ui->name, R_OK | X_OK)) {
1338 vassal_argv[counter] = uwsgi_concat2("exec://", n_ui->name);
1339 }
1340
1341 }
1342
1343 if (n_ui->use_config) {
1344 vassal_argv[counter] = uwsgi_concat2("emperor://", n_ui->name);
1345 }
1346
1347 // start templates,includes,inherit...
1348 counter++;
1349
1350 uwsgi_foreach(uct, uwsgi.vassals_templates) {
1351 vassal_argv[counter] = "--inherit";
1352 vassal_argv[counter + 1] = uct->value;
1353 counter += 2;
1354 }
1355
1356 uwsgi_foreach(uct, uwsgi.vassals_includes) {
1357 vassal_argv[counter] = "--include";
1358 vassal_argv[counter + 1] = uct->value;
1359 counter += 2;
1360 }
1361
1362 vassal_argv[counter] = NULL;
1363
1364 // disable stdin OR map it to the "on demand" socket
1365 if (n_ui->on_demand_fd > -1) {
1366 if (n_ui->on_demand_fd != 0) {
1367 if (dup2(n_ui->on_demand_fd, 0) < 0) {
1368 uwsgi_error("dup2()");
1369 exit(1);
1370 }
1371 close(n_ui->on_demand_fd);
1372 }
1373 }
1374 else {
1375 uwsgi_remap_fd(0, "/dev/null");
1376 }
1377
1378 // close all of the unneded fd
1379 for (i = 3; i < (int) uwsgi.max_fd; i++) {
1380 if (uwsgi_fd_is_safe(i))
1381 continue;
1382 if (n_ui->use_config) {
1383 if (i == n_ui->pipe_config[1])
1384 continue;
1385 }
1386 if (i != n_ui->pipe[1]) {
1387 close(i);
1388 }
1389 }
1390
1391 // run start hook (can fail)
1392 if (uwsgi.vassals_start_hook) {
1393 uwsgi_log("[emperor] running vassal start-hook: %s %s\n", uwsgi.vassals_start_hook, n_ui->name);
1394 if (uwsgi.emperor_absolute_dir) {
1395 if (setenv("UWSGI_VASSALS_DIR", uwsgi.emperor_absolute_dir, 1)) {
1396 uwsgi_error("setenv()");
1397 }
1398 }
1399 int start_hook_ret = uwsgi_run_command_and_wait(uwsgi.vassals_start_hook, n_ui->name);
1400 uwsgi_log("[emperor] %s start-hook returned %d\n", n_ui->name, start_hook_ret);
1401 }
1402
1403 uwsgi_hooks_run(uwsgi.hook_as_vassal, "as-vassal", 1);
1404
1405 uwsgi_foreach(usl, uwsgi.mount_as_vassal) {
1406 uwsgi_log("mounting \"%s\" (as-vassal)...\n", usl->value);
1407 if (uwsgi_mount_hook(usl->value)) {
1408 exit(1);
1409 }
1410 }
1411
1412 uwsgi_foreach(usl, uwsgi.umount_as_vassal) {
1413 uwsgi_log("un-mounting \"%s\" (as-vassal)...\n", usl->value);
1414 if (uwsgi_umount_hook(usl->value)) {
1415 exit(1);
1416 }
1417 }
1418
1419 // run exec hooks (cannot fail)
1420 uwsgi_foreach(usl, uwsgi.exec_as_vassal) {
1421 uwsgi_log("running \"%s\" (as-vassal)...\n", usl->value);
1422 int ret = uwsgi_run_command_and_wait(NULL, usl->value);
1423 if (ret != 0) {
1424 uwsgi_log("command \"%s\" exited with non-zero code: %d\n", usl->value, ret);
1425 exit(1);
1426 }
1427 }
1428
1429 // run low-level hooks
1430 uwsgi_foreach(usl, uwsgi.call_as_vassal) {
1431 void (*func) (void) = dlsym(RTLD_DEFAULT, usl->value);
1432 if (!func) {
1433 uwsgi_log("unable to call function \"%s\"\n", usl->value);
1434 exit(1);
1435 }
1436 func();
1437 }
1438
1439 uwsgi_foreach(usl, uwsgi.call_as_vassal1) {
1440 void (*func) (char *) = dlsym(RTLD_DEFAULT, usl->value);
1441 if (!func) {
1442 uwsgi_log("unable to call function \"%s\"\n", usl->value);
1443 exit(1);
1444 }
1445 func(n_ui->name);
1446 }
1447
1448 uwsgi_foreach(usl, uwsgi.call_as_vassal3) {
1449 void (*func) (char *, uid_t, gid_t) = dlsym(RTLD_DEFAULT, usl->value);
1450 if (!func) {
1451 uwsgi_log("unable to call function \"%s\"\n", usl->value);
1452 exit(1);
1453 }
1454 func(n_ui->name, n_ui->uid, n_ui->gid);
1455 }
1456
1457 // ->vassal_before_exec
1458 for (i = 0; i < 256; i++) {
1459 if (uwsgi.p[i]->vassal_before_exec) {
1460 uwsgi.p[i]->vassal_before_exec(n_ui);
1461 }
1462 }
1463
1464 for (i = 0; i < uwsgi.gp_cnt; i++) {
1465 if (uwsgi.gp[i]->vassal) {
1466 uwsgi.gp[i]->vassal_before_exec(n_ui);
1467 }
1468 }
1469
1470
1471 if (uwsgi.emperor_wrapper_override) {
1472 char *orig_wrapper = vassal_argv[0];
1473 uwsgi_foreach(usl, uwsgi.emperor_wrapper_override) {
1474 vassal_argv[0] = usl->value;
1475 uwsgi_log("[emperor] trying to use %s as binary wrapper ...\n", usl->value);
1476 execvp(vassal_argv[0], vassal_argv);
1477 // not here if the binary is found
1478 }
1479 vassal_argv[0] = orig_wrapper;
1480 }
1481
1482 // start !!!
1483 if (execvp(vassal_argv[0], vassal_argv)) {
1484 uwsgi_error("execvp()");
1485 }
1486 uwsgi_log("[emperor] binary path: %s\n", vassal_argv[0]);
1487 uwsgi_log("[emperor] is the uwsgi binary in your system PATH ?\n");
1488
1489 // trying fallback
1490 uwsgi_foreach(usl, uwsgi.emperor_wrapper_fallback) {
1491 uwsgi_log("[emperor] trying to use %s as binary fallback ...\n", usl->value);
1492 vassal_argv[0] = usl->value;
1493 execvp(vassal_argv[0], vassal_argv);
1494 // not here if the binary is found
1495 }
1496 // never here
1497 exit(UWSGI_EXILE_CODE);
1498
1499 return 0;
1500 }
1501
uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner * ues)1502 void uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner *ues) {
1503 if (chdir(uwsgi.cwd)) {
1504 uwsgi_error("chdir()");
1505 exit(1);
1506 }
1507
1508 uwsgi.emperor_absolute_dir = uwsgi.cwd;
1509
1510 if (!uwsgi_startswith(ues->arg, "glob://", 7)) {
1511 ues->arg += 7;
1512 }
1513 }
1514
uwsgi_imperial_monitor_directory_init(struct uwsgi_emperor_scanner * ues)1515 void uwsgi_imperial_monitor_directory_init(struct uwsgi_emperor_scanner *ues) {
1516
1517 if (!uwsgi_startswith(ues->arg, "dir://", 6)) {
1518 ues->arg += 6;
1519 }
1520
1521 if (chdir(ues->arg)) {
1522 uwsgi_error("chdir()");
1523 exit(1);
1524 }
1525
1526 uwsgi.emperor_absolute_dir = uwsgi_malloc(PATH_MAX + 1);
1527 if (realpath(".", uwsgi.emperor_absolute_dir) == NULL) {
1528 uwsgi_error("realpath()");
1529 exit(1);
1530 }
1531
1532 ues->arg = uwsgi.emperor_absolute_dir;
1533
1534 }
1535
imperial_monitor_get_by_id(char * scheme)1536 struct uwsgi_imperial_monitor *imperial_monitor_get_by_id(char *scheme) {
1537 struct uwsgi_imperial_monitor *uim = uwsgi.emperor_monitors;
1538 while (uim) {
1539 if (!strcmp(uim->scheme, scheme)) {
1540 return uim;
1541 }
1542 uim = uim->next;
1543 }
1544 return NULL;
1545 }
1546
imperial_monitor_get_by_scheme(char * arg)1547 struct uwsgi_imperial_monitor *imperial_monitor_get_by_scheme(char *arg) {
1548 struct uwsgi_imperial_monitor *uim = uwsgi.emperor_monitors;
1549 while (uim) {
1550 char *scheme = uwsgi_concat2(uim->scheme, "://");
1551 if (!uwsgi_starts_with(arg, strlen(arg), scheme, strlen(scheme))) {
1552 free(scheme);
1553 return uim;
1554 }
1555 free(scheme);
1556 uim = uim->next;
1557 }
1558 return NULL;
1559 }
1560
emperor_add_scanner(struct uwsgi_imperial_monitor * monitor,char * arg)1561 void emperor_add_scanner(struct uwsgi_imperial_monitor *monitor, char *arg) {
1562 struct uwsgi_emperor_scanner *ues = emperor_scanners;
1563 if (!ues) {
1564 ues = uwsgi_calloc(sizeof(struct uwsgi_emperor_scanner));
1565 emperor_scanners = ues;
1566 }
1567 else {
1568 while (ues) {
1569 if (!ues->next) {
1570 ues->next = uwsgi_calloc(sizeof(struct uwsgi_emperor_scanner));
1571 ues = ues->next;
1572 break;
1573 }
1574 ues = ues->next;
1575 }
1576 }
1577
1578 ues->arg = arg;
1579 ues->monitor = monitor;
1580 ues->next = NULL;
1581 ues->fd = -1;
1582 // run the init hook
1583 ues->monitor->init(ues);
1584 }
1585
uwsgi_emperor_run_scanners(void)1586 void uwsgi_emperor_run_scanners(void) {
1587 struct uwsgi_emperor_scanner *ues = emperor_scanners;
1588 while (ues) {
1589 ues->monitor->func(ues);
1590 ues = ues->next;
1591 }
1592 emperor_warming_up = 0;
1593 }
1594
emperor_build_scanners()1595 void emperor_build_scanners() {
1596 struct uwsgi_string_list *usl = uwsgi.emperor;
1597 glob_t g;
1598 while (usl) {
1599 struct uwsgi_imperial_monitor *uim = imperial_monitor_get_by_scheme(usl->value);
1600 if (uim) {
1601 emperor_add_scanner(uim, usl->value);
1602 }
1603 else {
1604 // check for "glob" and fallback to "dir"
1605 if (!glob(usl->value, GLOB_MARK | GLOB_NOCHECK, NULL, &g)) {
1606 if (g.gl_pathc == 1 && g.gl_pathv[0][strlen(g.gl_pathv[0]) - 1] == '/') {
1607 globfree(&g);
1608 goto dir;
1609 }
1610 globfree(&g);
1611 uim = imperial_monitor_get_by_id("glob");
1612 emperor_add_scanner(uim, usl->value);
1613 goto next;
1614 }
1615 dir:
1616 uim = imperial_monitor_get_by_id("dir");
1617 emperor_add_scanner(uim, usl->value);
1618 }
1619 next:
1620 usl = usl->next;
1621 }
1622 }
1623
uwsgi_emperor_scanner_event(int fd)1624 int uwsgi_emperor_scanner_event(int fd) {
1625
1626 struct uwsgi_emperor_scanner *ues = emperor_scanners;
1627 while (ues) {
1628 if (ues->fd > -1 && ues->fd == fd) {
1629 ues->event_func(ues);
1630 return 1;
1631 }
1632 ues = ues->next;
1633 }
1634
1635 return 0;
1636
1637 }
1638
emperor_wakeup(int sn)1639 static void emperor_wakeup(int sn) {
1640 }
1641
emperor_cleanup(int signum)1642 static void emperor_cleanup(int signum) {
1643 uwsgi_log_verbose("[emperor] cleaning up blacklist ...\n");
1644 struct uwsgi_emperor_blacklist_item *uebi = emperor_blacklist;
1645 while (uebi) {
1646 struct uwsgi_emperor_blacklist_item *next = uebi->next;
1647 free(uebi);
1648 uebi = next;
1649 }
1650 emperor_blacklist = NULL;
1651 }
1652
emperor_loop()1653 void emperor_loop() {
1654
1655 // monitor a directory
1656
1657 struct uwsgi_instance ui_base;
1658 struct uwsgi_instance *ui_current;
1659
1660 pid_t diedpid;
1661 int waitpid_status;
1662 int has_children = 0;
1663 int i_am_alone = 0;
1664 int i;
1665
1666 void *events;
1667 int nevents;
1668 int interesting_fd;
1669 char notification_message[64];
1670 struct rlimit rl;
1671
1672 uwsgi.disable_nuclear_blast = 1;
1673
1674 uwsgi.emperor_stats_fd = -1;
1675
1676 if (uwsgi.emperor_pidfile) {
1677 uwsgi_write_pidfile(uwsgi.emperor_pidfile);
1678 }
1679
1680 signal(SIGPIPE, SIG_IGN);
1681 signal(SIGWINCH, emperor_wakeup);
1682 uwsgi_unix_signal(SIGINT, royal_death);
1683 uwsgi_unix_signal(SIGTERM, royal_death);
1684 uwsgi_unix_signal(SIGQUIT, royal_death);
1685 uwsgi_unix_signal(SIGUSR1, emperor_stats);
1686 uwsgi_unix_signal(SIGHUP, emperor_massive_reload);
1687 uwsgi_unix_signal(SIGURG, emperor_cleanup);
1688
1689 memset(&ui_base, 0, sizeof(struct uwsgi_instance));
1690
1691 if (getrlimit(RLIMIT_NOFILE, &rl)) {
1692 uwsgi_error("getrlimit()");
1693 exit(1);
1694 }
1695
1696 uwsgi.max_fd = rl.rlim_cur;
1697
1698 emperor_throttle_level = uwsgi.emperor_throttle;
1699 emperor_throttle = 0;
1700
1701 // the queue must be initialized before adding scanners
1702 uwsgi.emperor_queue = event_queue_init();
1703
1704 emperor_build_scanners();
1705
1706 events = event_queue_alloc(64);
1707
1708 if (uwsgi.has_emperor) {
1709 uwsgi_log("*** starting uWSGI sub-Emperor ***\n");
1710 }
1711 else {
1712 uwsgi_log("*** starting uWSGI Emperor ***\n");
1713 }
1714
1715 if (uwsgi.emperor_stats) {
1716 char *tcp_port = strchr(uwsgi.emperor_stats, ':');
1717 if (tcp_port) {
1718 // disable deferred accept for this socket
1719 int current_defer_accept = uwsgi.no_defer_accept;
1720 uwsgi.no_defer_accept = 1;
1721 uwsgi.emperor_stats_fd = bind_to_tcp(uwsgi.emperor_stats, uwsgi.listen_queue, tcp_port);
1722 uwsgi.no_defer_accept = current_defer_accept;
1723 }
1724 else {
1725 uwsgi.emperor_stats_fd = bind_to_unix(uwsgi.emperor_stats, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
1726 }
1727
1728 event_queue_add_fd_read(uwsgi.emperor_queue, uwsgi.emperor_stats_fd);
1729 uwsgi_log("*** Emperor stats server enabled on %s fd: %d ***\n", uwsgi.emperor_stats, uwsgi.emperor_stats_fd);
1730 }
1731
1732 ui = &ui_base;
1733
1734 int freq = 0;
1735
1736 uwsgi_hooks_run(uwsgi.hook_emperor_start, "emperor-start", 1);
1737
1738 // signal parent-Emperor about my loyalty
1739 if (uwsgi.has_emperor && !uwsgi.loyal) {
1740 uwsgi_log("announcing my loyalty to the Emperor...\n");
1741 char byte = 17;
1742 if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
1743 uwsgi_error("write()");
1744 }
1745 uwsgi.loyal = 1;
1746 }
1747
1748 for (;;) {
1749
1750 if (on_royal_death) {
1751 if (!ui->ui_next)
1752 break;
1753 if (uwsgi_now() - on_royal_death >= uwsgi.reload_mercy) {
1754 ui_current = ui->ui_next;
1755 while (ui_current) {
1756 uwsgi_log_verbose("[emperor] NO MERCY for vassal %s !!!\n", ui_current->name);
1757 if (kill(ui_current->pid, SIGKILL) < 0) {
1758 uwsgi_error("[emperor] kill()");
1759 emperor_del(ui_current);
1760 break;
1761 }
1762 ui_current = ui_current->ui_next;
1763 }
1764 break;
1765 }
1766 ui_current = ui->ui_next;
1767 while (ui_current) {
1768 struct uwsgi_instance *dead_vassal = ui_current;
1769 ui_current = ui_current->ui_next;
1770 pid_t dead_pid = waitpid(dead_vassal->pid, &waitpid_status, WNOHANG);
1771 if (dead_pid > 0 || dead_pid < 0) {
1772 emperor_del(dead_vassal);
1773 }
1774 }
1775 sleep(1);
1776 continue;
1777 }
1778
1779 if (!i_am_alone) {
1780 diedpid = waitpid(uwsgi.emperor_pid, &waitpid_status, WNOHANG);
1781 if (diedpid < 0 || diedpid > 0) {
1782 i_am_alone = 1;
1783 }
1784 }
1785
1786 nevents = event_queue_wait_multi(uwsgi.emperor_queue, freq, events, 64);
1787 freq = uwsgi.emperor_freq;
1788
1789 for (i = 0; i < nevents; i++) {
1790 interesting_fd = event_queue_interesting_fd(events, i);
1791
1792 if (uwsgi.emperor_stats && uwsgi.emperor_stats_fd > -1 && interesting_fd == uwsgi.emperor_stats_fd) {
1793 emperor_send_stats(uwsgi.emperor_stats_fd);
1794 continue;
1795 }
1796
1797 // check if a monitor is mapped to that file descriptor
1798 if (uwsgi_emperor_scanner_event(interesting_fd)) {
1799 continue;
1800 }
1801
1802 ui_current = emperor_get_by_fd(interesting_fd);
1803 if (ui_current) {
1804 char byte;
1805 ssize_t rlen = read(interesting_fd, &byte, 1);
1806 // retry if needed
1807 if (rlen < 0 && uwsgi_is_again()) continue;
1808 if (rlen <= 0) {
1809 // SAFE
1810 event_queue_del_fd(uwsgi.emperor_queue, interesting_fd, event_queue_read());
1811 if (ui_current->status > 0) {
1812 // temporarily set frequency to a low value , so we can eventually fast-restart the instance
1813 freq = ui_current->status;
1814 }
1815 emperor_curse(ui_current);
1816 }
1817 else {
1818 if (byte == 17) {
1819 ui_current->loyal = 1;
1820 ui_current->last_loyal = uwsgi_now();
1821 uwsgi_log_verbose("[emperor] vassal %s is now loyal\n", ui_current->name);
1822 // remove it from the blacklist
1823 uwsgi_emperor_blacklist_remove(ui_current->name);
1824 // TODO post-start hook
1825 }
1826 // heartbeat can be used for spotting blocked instances
1827 else if (byte == 26) {
1828 ui_current->last_heartbeat = uwsgi_now();
1829 }
1830 else if (byte == 22) {
1831 // command 22 changes meaning when in "on_demand" mode
1832 if (ui_current->on_demand_fd != -1) {
1833 emperor_back_to_ondemand(ui_current);
1834 }
1835 else {
1836 emperor_stop(ui_current);
1837 }
1838 }
1839 else if (byte == 30 && uwsgi.emperor_broodlord > 0 && uwsgi.emperor_broodlord_count < uwsgi.emperor_broodlord) {
1840 uwsgi_log_verbose("[emperor] going in broodlord mode: launching zergs for %s\n", ui_current->name);
1841 char *zerg_name = uwsgi_concat3(ui_current->name, ":", "zerg");
1842 // here we discard socket name as broodlord/zerg cannot be on demand
1843 emperor_add(ui_current->scanner, zerg_name, uwsgi_now(), NULL, 0, ui_current->uid, ui_current->gid, NULL);
1844 free(zerg_name);
1845 }
1846 else if (byte == 5) {
1847 ui_current->accepting = 1;
1848 ui_current->last_accepting = uwsgi_now();
1849 uwsgi_log_verbose("[emperor] vassal %s is ready to accept requests\n", ui_current->name);
1850 }
1851 else if (byte == 1) {
1852 ui_current->ready = 1;
1853 ui_current->last_ready = uwsgi_now();
1854 uwsgi_log_verbose("[emperor] vassal %s has been spawned\n", ui_current->name);
1855 }
1856 else if (byte == 2) {
1857 emperor_push_config(ui_current);
1858 }
1859 }
1860 }
1861 else {
1862 ui_current = emperor_get_by_socket_fd(interesting_fd);
1863 if (ui_current) {
1864 event_queue_del_fd(uwsgi.emperor_queue, ui_current->on_demand_fd, event_queue_read());
1865 if (uwsgi_emperor_vassal_start(ui_current)) {
1866 emperor_del(ui_current);
1867 }
1868 }
1869 else {
1870 uwsgi_log("[emperor] unrecognized vassal event on fd %d\n", interesting_fd);
1871 close(interesting_fd);
1872 }
1873 }
1874
1875 }
1876
1877 uwsgi_emperor_run_scanners();
1878
1879 // check for heartbeat (if required)
1880 ui_current = ui->ui_next;
1881 while (ui_current) {
1882 if (ui_current->last_heartbeat > 0) {
1883 #ifdef UWSGI_DEBUG
1884 uwsgi_log("%d %d %d %d\n", ui_current->last_heartbeat, uwsgi.emperor_heartbeat, ui_current->last_heartbeat + uwsgi.emperor_heartbeat, uwsgi_now());
1885 #endif
1886 if ((ui_current->last_heartbeat + uwsgi.emperor_heartbeat) < uwsgi_now()) {
1887 uwsgi_log("[emperor] vassal %s sent no heartbeat in last %d seconds, brutally respawning it...\n", ui_current->name, uwsgi.emperor_heartbeat);
1888 // set last_heartbeat to 0 avoiding races
1889 ui_current->last_heartbeat = 0;
1890 if (ui_current->pid > 0) {
1891 if (kill(ui_current->pid, SIGKILL) < 0) {
1892 uwsgi_error("[emperor] kill()");
1893 emperor_del(ui_current);
1894 break;
1895 }
1896 }
1897 }
1898 }
1899 ui_current = ui_current->ui_next;
1900 }
1901
1902
1903 recheck:
1904 // check for removed instances
1905 ui_current = ui;
1906 has_children = 0;
1907 while (ui_current->ui_next) {
1908 ui_current = ui_current->ui_next;
1909 if (ui_current->pid > -1) {
1910 has_children++;
1911 }
1912 }
1913
1914 if (uwsgi.notify) {
1915 if (snprintf(notification_message, 64, "The Emperor is governing %d vassals", has_children) >= 34) {
1916 uwsgi_notify(notification_message);
1917 }
1918 }
1919
1920 if (has_children) {
1921 diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
1922 }
1923 else {
1924 // vacuum
1925 waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
1926 diedpid = 0;
1927 }
1928 if (diedpid < 0) {
1929 // it looks like it happens when OOM is triggered to Linux cgroup, but it could be a uWSGI bug :P
1930 // by the way, fallback to a clean situation...
1931 if (errno == ECHILD) {
1932 uwsgi_log("--- MUTINY DETECTED !!! IMPALING VASSALS... ---\n");
1933 ui_current = ui->ui_next;
1934 while (ui_current) {
1935 struct uwsgi_instance *rebel_vassal = ui_current;
1936 ui_current = ui_current->ui_next;
1937 emperor_del(rebel_vassal);
1938 }
1939 }
1940 else {
1941 uwsgi_error("waitpid()");
1942 }
1943 }
1944 ui_current = ui;
1945 while (ui_current->ui_next) {
1946 ui_current = ui_current->ui_next;
1947 time_t now = uwsgi_now();
1948 if (diedpid > 0 && ui_current->pid == diedpid) {
1949 if (ui_current->status == 0) {
1950 // respawn an accidentally dead instance if its exit code is not UWSGI_EXILE_CODE
1951 if (WIFEXITED(waitpid_status) && WEXITSTATUS(waitpid_status) == UWSGI_EXILE_CODE) {
1952 // SAFE
1953 emperor_del(ui_current);
1954 }
1955 else {
1956 // UNSAFE
1957 char *config = NULL;
1958 if (ui_current->config) {
1959 config = uwsgi_str(ui_current->config);
1960 }
1961 char *socket_name = NULL;
1962 if (ui_current->socket_name) {
1963 socket_name = uwsgi_str(ui_current->socket_name);
1964 }
1965 emperor_add(ui_current->scanner, ui_current->name, ui_current->last_mod, config, ui_current->config_len, ui_current->uid, ui_current->gid, socket_name);
1966 // temporarily set frequency to 0, so we can eventually fast-restart the instance
1967 emperor_del(ui_current);
1968 freq = 0;
1969 }
1970 break;
1971 }
1972 else if (ui_current->status == 1) {
1973 // remove 'marked for dead' instance
1974 emperor_del(ui_current);
1975 // temporarily set frequency to 0, so we can eventually fast-restart the instance
1976 freq = 0;
1977 break;
1978 }
1979 // back to on_demand mode ...
1980 else if (ui_current->status == 2) {
1981 event_queue_add_fd_read(uwsgi.emperor_queue, ui_current->on_demand_fd);
1982 close(ui_current->pipe[0]);
1983 ui_current->pipe[0] = -1;
1984 if (ui_current->use_config) {
1985 close(ui_current->pipe_config[0]);
1986 ui_current->pipe_config[0] = -1;
1987 }
1988 ui_current->pid = -1;
1989 ui_current->status = 0;
1990 ui_current->cursed_at = 0;
1991 ui_current->ready = 0;
1992 ui_current->accepting = 0;
1993 uwsgi_log("[uwsgi-emperor] %s -> back to \"on demand\" mode, waiting for connections on socket \"%s\" ...\n", ui_current->name, ui_current->socket_name);
1994 break;
1995 }
1996 }
1997 else if (ui_current->cursed_at > 0) {
1998 if (ui_current->pid == -1) {
1999 emperor_del(ui_current);
2000 // temporarily set frequency to 0, so we can eventually fast-restart the instance
2001 freq = 0;
2002 break;
2003 }
2004 else if (now - ui_current->cursed_at >= uwsgi.emperor_curse_tolerance) {
2005 ui_current->cursed_at = now;
2006 if (kill(ui_current->pid, SIGKILL) < 0) {
2007 uwsgi_error("[emperor] kill()");
2008 // delete the vassal, something is seriously wrong better to not leak memory...
2009 emperor_del(ui_current);
2010 }
2011 break;
2012 }
2013 }
2014 }
2015
2016 // if waitpid returned an item, let's check for another (potential) one
2017 if (diedpid > 0)
2018 goto recheck;
2019
2020
2021 }
2022
2023 uwsgi_log_verbose("The Emperor is buried.\n");
2024 uwsgi_notify("The Emperor is buried.");
2025 exit(0);
2026
2027 }
2028
emperor_send_stats(int fd)2029 void emperor_send_stats(int fd) {
2030
2031 struct sockaddr_un client_src;
2032 socklen_t client_src_len = 0;
2033
2034 int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
2035 if (client_fd < 0) {
2036 uwsgi_error("accept()");
2037 return;
2038 }
2039
2040 if (uwsgi.stats_http) {
2041 if (uwsgi_send_http_stats(client_fd)) {
2042 close(client_fd);
2043 return;
2044 }
2045 }
2046
2047 struct uwsgi_stats *us = uwsgi_stats_new(8192);
2048
2049 if (uwsgi_stats_keyval_comma(us, "version", UWSGI_VERSION))
2050 goto end;
2051 if (uwsgi_stats_keylong_comma(us, "pid", (unsigned long long) getpid()))
2052 goto end;
2053 if (uwsgi_stats_keylong_comma(us, "uid", (unsigned long long) getuid()))
2054 goto end;
2055 if (uwsgi_stats_keylong_comma(us, "gid", (unsigned long long) getgid()))
2056 goto end;
2057
2058 char *cwd = uwsgi_get_cwd();
2059 if (uwsgi_stats_keyval_comma(us, "cwd", cwd))
2060 goto end0;
2061
2062 if (uwsgi_stats_key(us, "emperor"))
2063 goto end0;
2064 if (uwsgi_stats_list_open(us))
2065 goto end0;
2066 struct uwsgi_emperor_scanner *ues = emperor_scanners;
2067 while (ues) {
2068 if (uwsgi_stats_str(us, ues->arg))
2069 goto end0;
2070 ues = ues->next;
2071 if (ues) {
2072 if (uwsgi_stats_comma(us))
2073 goto end0;
2074 }
2075 }
2076 if (uwsgi_stats_list_close(us))
2077 goto end0;
2078
2079 if (uwsgi_stats_comma(us))
2080 goto end0;
2081
2082 if (uwsgi_stats_keylong_comma(us, "emperor_tyrant", (unsigned long long) uwsgi.emperor_tyrant))
2083 goto end0;
2084
2085 // will be zero for now
2086 if (uwsgi_stats_keylong_comma(us, "throttle_level", (unsigned long long) 0))
2087 goto end0;
2088
2089
2090 if (uwsgi_stats_key(us, "vassals"))
2091 goto end0;
2092 if (uwsgi_stats_list_open(us))
2093 goto end0;
2094
2095 struct uwsgi_instance *c_ui = ui->ui_next;
2096
2097 while (c_ui) {
2098 if (uwsgi_stats_object_open(us))
2099 goto end0;
2100
2101 if (uwsgi_stats_keyval_comma(us, "id", c_ui->name))
2102 goto end0;
2103
2104 if (uwsgi_stats_keyslong_comma(us, "pid", (long long) c_ui->pid))
2105 goto end0;
2106 if (uwsgi_stats_keylong_comma(us, "born", (unsigned long long) c_ui->born))
2107 goto end0;
2108 if (uwsgi_stats_keylong_comma(us, "last_mod", (unsigned long long) c_ui->last_mod))
2109 goto end0;
2110 if (uwsgi_stats_keylong_comma(us, "last_heartbeat", (unsigned long long) c_ui->last_heartbeat))
2111 goto end0;
2112 if (uwsgi_stats_keylong_comma(us, "loyal", (unsigned long long) c_ui->loyal))
2113 goto end0;
2114 if (uwsgi_stats_keylong_comma(us, "ready", (unsigned long long) c_ui->ready))
2115 goto end0;
2116 if (uwsgi_stats_keylong_comma(us, "accepting", (unsigned long long) c_ui->accepting))
2117 goto end0;
2118 if (uwsgi_stats_keylong_comma(us, "last_loyal", (unsigned long long) c_ui->last_loyal))
2119 goto end0;
2120 if (uwsgi_stats_keylong_comma(us, "last_ready", (unsigned long long) c_ui->last_ready))
2121 goto end0;
2122 if (uwsgi_stats_keylong_comma(us, "last_accepting", (unsigned long long) c_ui->last_accepting))
2123 goto end0;
2124 if (uwsgi_stats_keylong_comma(us, "first_run", (unsigned long long) c_ui->first_run))
2125 goto end0;
2126 if (uwsgi_stats_keylong_comma(us, "last_run", (unsigned long long) c_ui->last_run))
2127 goto end0;
2128 if (uwsgi_stats_keylong_comma(us, "cursed", (unsigned long long) c_ui->cursed_at))
2129 goto end0;
2130 if (uwsgi_stats_keylong_comma(us, "zerg", (unsigned long long) c_ui->zerg))
2131 goto end0;
2132
2133 if (uwsgi_stats_keyval_comma(us, "on_demand", c_ui->socket_name ? c_ui->socket_name : ""))
2134 goto end0;
2135
2136 if (uwsgi_stats_keylong_comma(us, "uid", (unsigned long long) c_ui->uid))
2137 goto end0;
2138 if (uwsgi_stats_keylong_comma(us, "gid", (unsigned long long) c_ui->gid))
2139 goto end0;
2140
2141 if (uwsgi_stats_keyval_comma(us, "monitor", c_ui->scanner->arg))
2142 goto end0;
2143
2144 if (uwsgi_stats_keylong(us, "respawns", (unsigned long long) c_ui->respawns))
2145 goto end0;
2146
2147 if (uwsgi_stats_object_close(us))
2148 goto end0;
2149
2150 c_ui = c_ui->ui_next;
2151
2152 if (c_ui) {
2153 if (uwsgi_stats_comma(us))
2154 goto end0;
2155 }
2156 }
2157
2158
2159 if (uwsgi_stats_list_close(us))
2160 goto end0;
2161
2162 if (uwsgi_stats_comma(us))
2163 goto end0;
2164
2165 if (uwsgi_stats_key(us, "blacklist"))
2166 goto end0;
2167 if (uwsgi_stats_list_open(us))
2168 goto end0;
2169
2170 struct uwsgi_emperor_blacklist_item *uebi = emperor_blacklist;
2171 while (uebi) {
2172
2173 if (uwsgi_stats_object_open(us))
2174 goto end0;
2175
2176 if (uwsgi_stats_keyval_comma(us, "id", uebi->id))
2177 goto end0;
2178
2179
2180 if (uwsgi_stats_keylong_comma(us, "throttle_level", uebi->throttle_level / 1000))
2181 goto end0;
2182
2183 if (uwsgi_stats_keylong_comma(us, "attempt", (unsigned long long) uebi->attempt))
2184 goto end0;
2185
2186 if (uwsgi_stats_keylong_comma(us, "first_attempt", (unsigned long long) uebi->first_attempt.tv_sec))
2187 goto end0;
2188
2189 if (uwsgi_stats_keylong(us, "last_attempt", (unsigned long long) uebi->last_attempt.tv_sec))
2190 goto end0;
2191
2192 if (uwsgi_stats_object_close(us))
2193 goto end0;
2194
2195
2196 uebi = uebi->next;
2197 if (uebi) {
2198 if (uwsgi_stats_comma(us))
2199 goto end0;
2200 }
2201 }
2202
2203
2204 if (uwsgi_stats_list_close(us))
2205 goto end0;
2206
2207 if (uwsgi_stats_object_close(us))
2208 goto end0;
2209
2210 size_t remains = us->pos;
2211 off_t pos = 0;
2212 while (remains > 0) {
2213 int ret = uwsgi_waitfd_write(client_fd, uwsgi.socket_timeout);
2214 if (ret <= 0) {
2215 goto end0;
2216 }
2217 ssize_t res = write(client_fd, us->base + pos, remains);
2218 if (res <= 0) {
2219 if (res < 0) {
2220 uwsgi_error("write()");
2221 }
2222 goto end0;
2223 }
2224 pos += res;
2225 remains -= res;
2226 }
2227
2228 end0:
2229 free(cwd);
2230 end:
2231 free(us->base);
2232 free(us);
2233 close(client_fd);
2234 }
2235
uwsgi_emperor_start()2236 void uwsgi_emperor_start() {
2237
2238 if (!uwsgi.sockets && !ushared->gateways_cnt && !uwsgi.master_process) {
2239 if (uwsgi.emperor_procname) {
2240 uwsgi_set_processname(uwsgi.emperor_procname);
2241 }
2242 uwsgi_notify_ready();
2243 emperor_loop();
2244 // never here
2245 exit(1);
2246 }
2247
2248 if (uwsgi.emperor_procname) {
2249 uwsgi.emperor_pid = uwsgi_fork(uwsgi.emperor_procname);
2250 }
2251 else {
2252 uwsgi.emperor_pid = uwsgi_fork("uWSGI Emperor");
2253 }
2254
2255 if (uwsgi.emperor_pid < 0) {
2256 uwsgi_error("pid()");
2257 exit(1);
2258 }
2259 else if (uwsgi.emperor_pid == 0) {
2260 #ifdef __linux__
2261 if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)) {
2262 uwsgi_error("prctl()");
2263 }
2264 #endif
2265 emperor_loop();
2266 // never here
2267 exit(1);
2268 }
2269
2270 }
2271
uwsgi_check_emperor()2272 void uwsgi_check_emperor() {
2273 char *emperor_fd_pass = getenv("UWSGI_EMPEROR_PROXY");
2274 if (emperor_fd_pass) {
2275 for (;;) {
2276 int proxy_fd = uwsgi_connect(emperor_fd_pass, 30, 0);
2277 if (proxy_fd < 0) {
2278 uwsgi_error("uwsgi_check_emperor()/uwsgi_connect()");
2279 sleep(1);
2280 continue;
2281 }
2282 int count = 2;
2283 int *fds = uwsgi_attach_fd(proxy_fd, &count, "uwsgi-emperor", 13);
2284 if (fds && count > 0) {
2285 char *env_emperor_fd = uwsgi_num2str(fds[0]);
2286 if (setenv("UWSGI_EMPEROR_FD", env_emperor_fd, 1)) {
2287 uwsgi_error("uwsgi_check_emperor()/setenv(UWSGI_EMPEROR_FD)");
2288 free(env_emperor_fd);
2289 int i;
2290 for (i = 0; i < count; i++)
2291 close(fds[i]);
2292 goto next;
2293 }
2294 free(env_emperor_fd);
2295 if (count > 1) {
2296 char *env_emperor_fd_config = uwsgi_num2str(fds[1]);
2297 if (setenv("UWSGI_EMPEROR_FD_CONFIG", env_emperor_fd_config, 1)) {
2298 uwsgi_error("uwsgi_check_emperor()/setenv(UWSGI_EMPEROR_FD_CONFIG)");
2299 free(env_emperor_fd_config);
2300 int i;
2301 for (i = 0; i < count; i++)
2302 close(fds[i]);
2303 goto next;
2304 }
2305 free(env_emperor_fd_config);
2306 }
2307 if (fds)
2308 free(fds);
2309 close(proxy_fd);
2310 break;
2311 }
2312 next:
2313 if (fds)
2314 free(fds);
2315 close(proxy_fd);
2316 sleep(1);
2317 }
2318 unsetenv("UWSGI_EMPEROR_PROXY");
2319 }
2320
2321 char *emperor_env = getenv("UWSGI_EMPEROR_FD");
2322 if (emperor_env) {
2323 uwsgi.has_emperor = 1;
2324 uwsgi.emperor_fd = atoi(emperor_env);
2325 uwsgi.master_process = 1;
2326 uwsgi_log("*** has_emperor mode detected (fd: %d) ***\n", uwsgi.emperor_fd);
2327
2328 if (getenv("UWSGI_EMPEROR_FD_CONFIG")) {
2329 uwsgi.emperor_fd_config = atoi(getenv("UWSGI_EMPEROR_FD_CONFIG"));
2330 }
2331 }
2332
2333 }
2334
uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner * ues,char * name,char * config,time_t ts,uid_t uid,gid_t gid,char * socket_name)2335 void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *ues, char *name, char *config, time_t ts, uid_t uid, gid_t gid, char *socket_name) {
2336
2337 if (!uwsgi_emperor_is_valid(name))
2338 return;
2339
2340 struct uwsgi_instance *ui_current = emperor_get(name);
2341
2342 if (ui_current) {
2343
2344 // skip in case the instance is going down...
2345 if (ui_current->status > 0)
2346 return;
2347
2348 // check if uid or gid are changed, in such case, stop the instance
2349 if (uwsgi.emperor_tyrant) {
2350 if (uid != ui_current->uid || gid != ui_current->gid) {
2351 uwsgi_log("[emperor-tyrant] !!! permissions of vassal %s changed. stopping the instance... !!!\n", name);
2352 emperor_stop(ui_current);
2353 return;
2354 }
2355 }
2356 // check if mtime is changed and the uWSGI instance must be reloaded
2357 if (ts > ui_current->last_mod) {
2358 // now we neeed a special check for allowing an instance to move to "on_demand" mode (and back)
2359 // allowing means "stoppping the instance"
2360 if ((!ui_current->socket_name && ui_current->on_demand_fd == -1) && socket_name) {
2361 uwsgi_log("[uwsgi-emperor] %s -> requested move to \"on demand\" mode for socket \"%s\" ...\n", name, socket_name);
2362 emperor_stop(ui_current);
2363 return;
2364 }
2365 else if ((ui_current->socket_name && ui_current->on_demand_fd > -1) && !socket_name) {
2366 uwsgi_log("[uwsgi-emperor] %s -> asked for leaving \"on demand\" mode for socket \"%s\" ...\n", name, ui_current->socket_name);
2367 emperor_stop(ui_current);
2368 return;
2369 }
2370
2371 // make a new config (free the old one) if needed
2372 if (config) {
2373 if (ui_current->config)
2374 free(ui_current->config);
2375 ui_current->config = uwsgi_str(config);
2376 ui_current->config_len = strlen(ui_current->config);
2377 }
2378 // reload the instance
2379 emperor_respawn(ui_current, ts);
2380 }
2381 }
2382 else {
2383 // make a copy of the config as it will be freed
2384 char *new_config = NULL;
2385 size_t new_config_len = 0;
2386 if (config) {
2387 new_config = uwsgi_str(config);
2388 new_config_len = strlen(new_config);
2389 }
2390 emperor_add(ues, name, ts, new_config, new_config_len, uid, gid, socket_name);
2391 }
2392 }
2393
uwsgi_master_manage_emperor()2394 void uwsgi_master_manage_emperor() {
2395 char byte;
2396 #ifdef UWSGI_EVENT_USE_PORT
2397 // special cose for port event system
2398 // place the socket in non-blocking mode
2399 uwsgi_socket_nb(uwsgi.emperor_fd);
2400 #endif
2401 ssize_t rlen = read(uwsgi.emperor_fd, &byte, 1);
2402 #ifdef UWSGI_EVENT_USE_PORT
2403 // special cose for port event system
2404 // and place back in blocking mode
2405 uwsgi_socket_b(uwsgi.emperor_fd);
2406 #endif
2407 if (rlen > 0) {
2408 uwsgi_log_verbose("received message %d from emperor\n", byte);
2409 // remove me
2410 if (byte == 0) {
2411 uwsgi_hooks_run(uwsgi.hook_emperor_stop, "emperor-stop", 0);
2412 close(uwsgi.emperor_fd);
2413 if (!uwsgi.status.brutally_reloading && !uwsgi.status.brutally_destroying) {
2414 kill_them_all(0);
2415 }
2416 }
2417 // reload me
2418 else if (byte == 1) {
2419 uwsgi_hooks_run(uwsgi.hook_emperor_reload, "emperor-reload", 0);
2420 // un-lazy the stack to trigger a real reload
2421 uwsgi.lazy = 0;
2422 uwsgi_block_signal(SIGHUP);
2423 grace_them_all(0);
2424 uwsgi_unblock_signal(SIGHUP);
2425 }
2426 // remove me gracefully
2427 else if (byte == 2) {
2428 uwsgi_hooks_run(uwsgi.hook_emperor_stop, "emperor-stop", 0);
2429 close(uwsgi.emperor_fd);
2430 if (!uwsgi.status.brutally_reloading && !uwsgi.status.brutally_destroying) {
2431 gracefully_kill_them_all(0);
2432 }
2433 }
2434 }
2435 #ifdef UWSGI_EVENT_USE_PORT
2436 // special cose for port event system
2437 else if (rlen < 0 && uwsgi_is_again()) {
2438 return;
2439 }
2440 #endif
2441 else {
2442 uwsgi_error("uwsgi_master_manage_emperor()/read()");
2443 uwsgi_log("lost connection with my emperor !!!\n");
2444 uwsgi_hooks_run(uwsgi.hook_emperor_lost, "emperor-lost", 0);
2445 close(uwsgi.emperor_fd);
2446 if (!uwsgi.status.brutally_reloading)
2447 kill_them_all(0);
2448 sleep(2);
2449 exit(1);
2450 }
2451
2452 }
2453
uwsgi_master_manage_emperor_proxy()2454 void uwsgi_master_manage_emperor_proxy() {
2455
2456 struct sockaddr_un epsun;
2457 socklen_t epsun_len = sizeof(struct sockaddr_un);
2458
2459 int ep_client = accept(uwsgi.emperor_fd_proxy, (struct sockaddr *) &epsun, &epsun_len);
2460 if (ep_client < 0) {
2461 uwsgi_error("uwsgi_master_manage_emperor_proxy()/accept()");
2462 return;
2463 }
2464
2465 int num_fds = 1;
2466 if (uwsgi.emperor_fd_config > -1)
2467 num_fds++;
2468
2469 struct msghdr ep_msg;
2470 void *ep_msg_control = uwsgi_malloc(CMSG_SPACE(sizeof(int) * num_fds));
2471 struct iovec ep_iov[2];
2472 struct cmsghdr *cmsg;
2473
2474 ep_iov[0].iov_base = "uwsgi-emperor";
2475 ep_iov[0].iov_len = 13;
2476 ep_iov[1].iov_base = &num_fds;
2477 ep_iov[1].iov_len = sizeof(int);
2478
2479 ep_msg.msg_name = NULL;
2480 ep_msg.msg_namelen = 0;
2481
2482 ep_msg.msg_iov = ep_iov;
2483 ep_msg.msg_iovlen = 2;
2484
2485 ep_msg.msg_flags = 0;
2486 ep_msg.msg_control = ep_msg_control;
2487 ep_msg.msg_controllen = CMSG_SPACE(sizeof(int) * num_fds);
2488
2489 cmsg = CMSG_FIRSTHDR(&ep_msg);
2490 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds);
2491 cmsg->cmsg_level = SOL_SOCKET;
2492 cmsg->cmsg_type = SCM_RIGHTS;
2493
2494 unsigned char *ep_fd_ptr = CMSG_DATA(cmsg);
2495
2496 memcpy(ep_fd_ptr, &uwsgi.emperor_fd, sizeof(int));
2497 if (num_fds > 1) {
2498 memcpy(ep_fd_ptr + sizeof(int), &uwsgi.emperor_fd_config, sizeof(int));
2499 }
2500
2501 if (sendmsg(ep_client, &ep_msg, 0) < 0) {
2502 uwsgi_error("uwsgi_master_manage_emperor_proxy()/sendmsg()");
2503 }
2504
2505 free(ep_msg_control);
2506
2507 close(ep_client);
2508 }
2509
emperor_notify_ready()2510 static void emperor_notify_ready() {
2511 if (!uwsgi.has_emperor)
2512 return;
2513 char byte = 1;
2514 if (write(uwsgi.emperor_fd, &byte, 1) != 1) {
2515 uwsgi_error("emperor_notify_ready()/write()");
2516 exit(1);
2517 }
2518 }
2519
uwsgi_setup_emperor()2520 void uwsgi_setup_emperor() {
2521 if (!uwsgi.has_emperor)
2522 return;
2523 uwsgi.notify_ready = emperor_notify_ready;
2524 }
2525