1 #include "uwsgi.h"
2
3 extern struct uwsgi_server uwsgi;
4
5 /*
6
7 the --master-fifo option create a unix named pipe (fifo) you can use to send management
8 commands to the master:
9
10 echo r > myfifo
11
12 */
13
14 // this var can be accessed by plugins and hooks
15 void (*uwsgi_fifo_table[256])(int);
16
uwsgi_fifo_by_slot()17 static char *uwsgi_fifo_by_slot() {
18 int count = 0;
19 struct uwsgi_string_list *usl;
20 uwsgi_foreach(usl, uwsgi.master_fifo) {
21 if (count == uwsgi.master_fifo_slot) return usl->value;
22 count++;
23 }
24 return uwsgi.master_fifo->value;
25 }
26
27 #define announce_fifo uwsgi_log_verbose("active master fifo is now %s\n", uwsgi_fifo_by_slot())
28
uwsgi_fifo_set_slot_zero()29 static void uwsgi_fifo_set_slot_zero() { uwsgi.master_fifo_slot = 0; announce_fifo; }
uwsgi_fifo_set_slot_one()30 static void uwsgi_fifo_set_slot_one() { uwsgi.master_fifo_slot = 1; announce_fifo; }
uwsgi_fifo_set_slot_two()31 static void uwsgi_fifo_set_slot_two() { uwsgi.master_fifo_slot = 2; announce_fifo; }
uwsgi_fifo_set_slot_three()32 static void uwsgi_fifo_set_slot_three() { uwsgi.master_fifo_slot = 3; announce_fifo; }
uwsgi_fifo_set_slot_four()33 static void uwsgi_fifo_set_slot_four() { uwsgi.master_fifo_slot = 4; announce_fifo; }
uwsgi_fifo_set_slot_five()34 static void uwsgi_fifo_set_slot_five() { uwsgi.master_fifo_slot = 5; announce_fifo; }
uwsgi_fifo_set_slot_six()35 static void uwsgi_fifo_set_slot_six() { uwsgi.master_fifo_slot = 6; announce_fifo; }
uwsgi_fifo_set_slot_seven()36 static void uwsgi_fifo_set_slot_seven() { uwsgi.master_fifo_slot = 7; announce_fifo; }
uwsgi_fifo_set_slot_eight()37 static void uwsgi_fifo_set_slot_eight() { uwsgi.master_fifo_slot = 8; announce_fifo; }
uwsgi_fifo_set_slot_nine()38 static void uwsgi_fifo_set_slot_nine() { uwsgi.master_fifo_slot = 9; announce_fifo; }
39
subscriptions_blocker()40 static void subscriptions_blocker() {
41 if (uwsgi.subscriptions_blocked) {
42 uwsgi_log_verbose("subscriptions re-enabled\n");
43 uwsgi.subscriptions_blocked = 0;
44 }
45 else {
46 uwsgi.subscriptions_blocked = 1;
47 uwsgi_log_verbose("subscriptions blocked\n");
48 }
49 }
50
emperor_rescan()51 static void emperor_rescan() {
52 if (uwsgi.emperor_pid > 0) {
53 if (kill(uwsgi.emperor_pid, SIGWINCH)) {
54 uwsgi_error("emperor_rescan()/kill()");
55 }
56 }
57 }
58
59 /*
60
61 this is called as soon as possibile allowing plugins (or hooks) to override it
62
63 */
uwsgi_master_fifo_prepare()64 void uwsgi_master_fifo_prepare() {
65 int i;
66 for(i=0;i<256;i++) {
67 uwsgi_fifo_table[i] = NULL;
68 }
69
70 uwsgi_fifo_table['0'] = uwsgi_fifo_set_slot_zero;
71 uwsgi_fifo_table['1'] = uwsgi_fifo_set_slot_one;
72 uwsgi_fifo_table['2'] = uwsgi_fifo_set_slot_two;
73 uwsgi_fifo_table['3'] = uwsgi_fifo_set_slot_three;
74 uwsgi_fifo_table['4'] = uwsgi_fifo_set_slot_four;
75 uwsgi_fifo_table['5'] = uwsgi_fifo_set_slot_five;
76 uwsgi_fifo_table['6'] = uwsgi_fifo_set_slot_six;
77 uwsgi_fifo_table['7'] = uwsgi_fifo_set_slot_seven;
78 uwsgi_fifo_table['8'] = uwsgi_fifo_set_slot_eight;
79 uwsgi_fifo_table['9'] = uwsgi_fifo_set_slot_nine;
80
81 uwsgi_fifo_table['-'] = uwsgi_cheaper_decrease;
82 uwsgi_fifo_table['+'] = uwsgi_cheaper_increase;
83 uwsgi_fifo_table['B'] = vassal_sos;
84 uwsgi_fifo_table['c'] = uwsgi_chain_reload;
85 uwsgi_fifo_table['C'] = uwsgi_go_cheap;
86 uwsgi_fifo_table['E'] = emperor_rescan;
87 uwsgi_fifo_table['f'] = uwsgi_refork_master;
88 uwsgi_fifo_table['l'] = uwsgi_log_reopen;
89 uwsgi_fifo_table['L'] = uwsgi_log_rotate;
90 uwsgi_fifo_table['p'] = suspend_resume_them_all;
91 uwsgi_fifo_table['P'] = uwsgi_update_pidfiles;
92 uwsgi_fifo_table['q'] = gracefully_kill_them_all;
93 uwsgi_fifo_table['Q'] = kill_them_all;
94 uwsgi_fifo_table['r'] = grace_them_all;
95 uwsgi_fifo_table['R'] = reap_them_all;
96 uwsgi_fifo_table['s'] = stats;
97 uwsgi_fifo_table['S'] = subscriptions_blocker;
98 uwsgi_fifo_table['w'] = uwsgi_reload_workers;
99 uwsgi_fifo_table['W'] = uwsgi_brutally_reload_workers;
100
101 }
102
uwsgi_master_fifo()103 int uwsgi_master_fifo() {
104
105 char *path = uwsgi_fifo_by_slot();
106
107 if (unlink(path) != 0 && errno != ENOENT) {
108 uwsgi_error("uwsgi_master_fifo()/unlink()");
109 }
110
111 if (mkfifo(path, S_IRUSR|S_IWUSR)) {
112 uwsgi_error("uwsgi_master_fifo()/mkfifo()");
113 exit(1);
114 }
115
116 int fd = open(path, O_RDONLY|O_NONBLOCK);
117 if (fd < 0) {
118 uwsgi_error("uwsgi_master_fifo()/open()");
119 exit(1);
120 }
121
122 uwsgi_socket_nb(fd);
123
124 return fd;
125 }
126
uwsgi_master_fifo_manage(int fd)127 int uwsgi_master_fifo_manage(int fd) {
128 unsigned char cmd;
129 ssize_t rlen = read(fd, &cmd, 1);
130 if (rlen < 0) {
131 if (uwsgi_is_again()) return 0;
132 uwsgi_error("uwsgi_master_fifo_manage()/read()");
133 exit(1);
134 }
135 // fifo destroyed, recreate it
136 else if (rlen == 0) {
137 event_queue_del_fd(uwsgi.master_queue, uwsgi.master_fifo_fd, event_queue_read());
138 close(fd);
139 uwsgi.master_fifo_fd = uwsgi_master_fifo();
140 event_queue_add_fd_read(uwsgi.master_queue, uwsgi.master_fifo_fd);
141 return 0;
142 }
143
144 if (uwsgi_fifo_table[(int) cmd]) {
145 uwsgi_fifo_table[(int) cmd](0);
146 }
147
148 return 0;
149 }
150