Compare commits

...
23 Commits
Author SHA1 Message Date
roberto@gambit b361248ff6 fixed add_exported_opts 2011-10-23 08:35:15 +02:00
roberto@debian32 e9c42ceaa5 support for multiple values in options 2011-10-22 18:32:32 +02:00
roberto@debian32 5d7029744a PATH_INFO is correctly escaped in http modes 2011-10-22 09:35:01 +02:00
roberto@gambit 1084a3afa8 fixed mule patch loading 2011-10-20 10:38:59 +02:00
roberto@gambit ed254bffee fixed mule process name 2011-10-20 10:20:44 +02:00
roberto@djangocloud 733784d7dd another procname fix... 2011-10-19 16:13:10 +10:00
roberto@djangocloud cb5b26bcb4 another bunch of procname fixes 2011-10-19 14:26:07 +10:00
roberto@djangocloud 0065152bb1 daemons throttling subsystem 2011-10-18 18:53:22 +10:00
roberto@djangocloud 03266203fd another fix for environ 2011-10-18 18:30:13 +10:00
roberto@djangocloud 4a5f68f9d8 fixed environ 2011-10-18 18:12:39 +10:00
roberto@djangocloud 83e31a1c27 another setprocname fix 2011-10-18 16:20:33 +10:00
roberto@djangocloud 0efed5ef9c various emperor procname fixes 2011-10-18 16:15:06 +10:00
roberto@djangocloud cdfef1281d fixed another spooler compilation bug 2011-10-18 15:12:59 +10:00
roberto@debian32 e00907e142 --spooler-harakiri 2011-10-17 19:07:12 +02:00
roberto@app1 6dcbcf39e3 fixed compilation when spooler is disabled 2011-10-17 03:16:55 -05:00
roberto@debian32 044579a8e0 more verbose annihilation report 2011-10-16 11:16:13 +02:00
roberto@debian32 d2b52b4663 added uwsgi.setprocname() 2011-10-16 10:37:26 +02:00
roberto@debian32 7f75b2c02c added --procname and --procname-master 2011-10-16 10:18:45 +02:00
roberto@freebsd64 24a3f671e5 freebsd setproctitle 2011-10-16 10:06:08 +02:00
roberto@debian32 875100e3c8 check for mules before nuke 2011-10-16 09:58:37 +02:00
roberto@mrspurr 34bc7c0cfd check for procname 2011-10-16 09:54:35 +02:00
roberto@debian32 b39a10ff7c procname initial management 2011-10-16 09:45:41 +02:00
roberto@debian32 02331904de uWSGI 1.0-rc1 2011-10-15 08:47:00 +02:00
17 changed files with 547 additions and 94 deletions
+1
View File
@@ -32,3 +32,4 @@ f4d3c4dcd7a63e21fcc9d8d567374c69935178bd 0.9.8.3
fb168b0b86169219aa9b8e40f0caa6297cf34dbc 0.9.9-rc1
6aa667612019fcff8e68af9469f73aff6fa378a8 0.9.9-rc2
376ffd8f190623e5e2521fe9fa64bf03c31e71be 0.9.9
7048ae11cfc8453c6bb599af3c0dfacd7ebae43c 1.0-rc1
+13 -13
View File
@@ -179,7 +179,7 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
struct uwsgi_instance *c_ui = ui;
struct uwsgi_instance *n_ui = NULL;
pid_t pid;
char **argv;
char **vassal_argv;
char *uef;
char **uenvs;
int counter;
@@ -340,9 +340,9 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
uct = uct->next;
}
argv = uwsgi_malloc(sizeof(char *) * counter);
vassal_argv = uwsgi_malloc(sizeof(char *) * counter);
// set args
argv[0] = uwsgi.binary_path;
vassal_argv[0] = uwsgi.binary_path;
if (uwsgi.emperor_broodlord) {
colon = strchr(name, ':');
@@ -351,29 +351,29 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
}
}
if (!strcmp(name + (strlen(name) - 4), ".xml"))
argv[1] = "--xml";
vassal_argv[1] = "--xml";
if (!strcmp(name + (strlen(name) - 4), ".ini"))
argv[1] = "--ini";
vassal_argv[1] = "--ini";
if (!strcmp(name + (strlen(name) - 4), ".yml"))
argv[1] = "--yaml";
vassal_argv[1] = "--yaml";
if (!strcmp(name + (strlen(name) - 5), ".yaml"))
argv[1] = "--yaml";
vassal_argv[1] = "--yaml";
if (!strcmp(name + (strlen(name) - 3), ".js"))
argv[1] = "--json";
vassal_argv[1] = "--json";
if (colon) {
colon[0] = ':';
}
argv[2] = name;
vassal_argv[2] = name;
counter = 3;
uct = uwsgi.vassals_templates;
while(uct) {
argv[counter] = "--inherit";
argv[counter+1] = uct->filename;
vassal_argv[counter] = "--inherit";
vassal_argv[counter+1] = uct->filename;
counter+=2;
uct = uct->next;
}
argv[counter] = NULL;
vassal_argv[counter] = NULL;
// close all of the unneded fd
for(i=3;i<sysconf(_SC_OPEN_MAX);i++) {
@@ -392,7 +392,7 @@ void emperor_add(char *name, time_t born, char *config, uint32_t config_size, ui
}
// start !!!
if (execvp(argv[0], argv)) {
if (execvp(vassal_argv[0], vassal_argv)) {
uwsgi_error("execvp()");
}
uwsgi_log("is the uwsgi binary in your system PATH ?\n");
+5 -5
View File
@@ -47,7 +47,7 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop)(void)) {
}
}
gw_pid = fork();
gw_pid = uwsgi_fork(name);
if (gw_pid < 0) {
uwsgi_error("fork()");
return NULL;
@@ -90,7 +90,7 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop)(void)) {
ug->loop = loop;
ug->num = num;
uwsgi_log( "spawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) ug->pid);
uwsgi_log( "spawned %s %d (pid: %d)\n", ug->name, ug->num, (int) ug->pid);
uwsgi.gateways_cnt++;
@@ -103,7 +103,7 @@ void gateway_respawn(int id) {
pid_t gw_pid;
struct uwsgi_gateway *ug = &uwsgi.gateways[id];
gw_pid = fork();
gw_pid = uwsgi_fork(ug->name);
if (gw_pid < 0) {
uwsgi_error("fork()");
return;
@@ -124,10 +124,10 @@ void gateway_respawn(int id) {
ug->pid = gw_pid;
ug->respawns++;
if (ug->respawns == 1) {
uwsgi_log( "spawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
uwsgi_log( "spawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
}
else {
uwsgi_log( "respawned uWSGI %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
uwsgi_log( "respawned %s %d (pid: %d)\n", ug->name, ug->num, (int) gw_pid);
}
}
+57 -4
View File
@@ -294,6 +294,18 @@ int master_loop(char **argv, char **environ) {
struct uwsgi_rb_timer *min_timeout;
struct rb_root *rb_timers = uwsgi_init_rb_timer();
if (uwsgi.procname_master) {
uwsgi_set_processname(uwsgi.procname_master);
}
else if (uwsgi.procname) {
uwsgi_set_processname(uwsgi.procname);
}
else if (uwsgi.auto_procname) {
uwsgi_set_processname("uWSGI master");
}
uwsgi.current_time = time(NULL);
uwsgi_unix_signal(SIGHUP, grace_them_all);
@@ -661,8 +673,8 @@ healthy:
if ((uwsgi.cheap || ready_to_die >= uwsgi.numproc) && uwsgi.to_hell) {
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
// call a series of waitpid to ensure all processes (gateways, mules and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt+uwsgi.mules_cnt);i++) {
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
}
@@ -670,8 +682,8 @@ healthy:
exit(0);
}
if ( (uwsgi.cheap || ready_to_reload >= uwsgi.numproc) && uwsgi.to_heaven) {
// call a series of waitpid to ensure all processes (gateways and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt);i++) {
// call a series of waitpid to ensure all processes (gateways, mules and daemons) are dead
for(i=0;i<(uwsgi.gateways_cnt+ushared->daemons_cnt+uwsgi.mules_cnt);i++) {
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
}
@@ -1364,6 +1376,15 @@ healthy:
}
}
}
#ifdef UWSGI_SPOOLER
if (uwsgi.shared->spooler_pid > 0 && uwsgi.shared->spooler_harakiri > 0) {
if (uwsgi.shared->spooler_harakiri < (time_t) uwsgi.current_time) {
uwsgi_log("*** HARAKIRI ON THE SPOOLER (pid: %d) ***\n", uwsgi.shared->spooler_pid);
kill(uwsgi.shared->spooler_pid, SIGKILL);
uwsgi.shared->spooler_harakiri = 0;
}
}
#endif
#ifdef UWSGI_UDP
// check for cluster nodes
@@ -1488,6 +1509,37 @@ healthy:
uwsgi.mywid = find_worker_id(diedpid);
if (uwsgi.mywid <= 0) {
// check spooler, mules, gateways and daemons
#ifdef UWSGI_SPOOLER
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
if (diedpid == uwsgi.shared->spooler_pid) {
uwsgi_log("spooler (pid: %d) annihilated\n", (int) diedpid);
goto next;
}
}
#endif
for(i=0;i<uwsgi.mules_cnt;i++) {
if (uwsgi.mules[i].pid == diedpid) {
uwsgi_log("mule %d (pid: %d) annihilated\n", i+1, (int) diedpid);
goto next;
}
}
for(i=0;i<uwsgi.gateways_cnt;i++) {
if (uwsgi.gateways[i].pid == diedpid) {
uwsgi_log("gateway %d (pid: %d) annihilated\n", i+1, (int) diedpid);
goto next;
}
}
for(i=0;i<uwsgi.shared->daemons_cnt;i++) {
if (uwsgi.shared->daemons[i].pid == diedpid) {
uwsgi_log("daemon %d (pid: %d) annihilated\n", i+1, (int) diedpid);
goto next;
}
}
if (WIFEXITED(waitpid_status)) {
uwsgi_log("subprocess %d exited with code %d\n", (int) diedpid, WEXITSTATUS(waitpid_status));
}
@@ -1497,6 +1549,7 @@ healthy:
else if (WIFSTOPPED(waitpid_status)) {
uwsgi_log("subprocess %d stopped\n", (int) diedpid);
}
next:
continue;
}
else {
+1 -1
View File
@@ -81,7 +81,7 @@ int uwsgi_respawn_worker(int wid) {
int respawns = uwsgi.workers[wid].respawn_count;
int i;
pid_t pid = fork();
pid_t pid = uwsgi_fork(uwsgi.workers[wid].name);
if (pid == 0) {
signal(SIGWINCH, worker_wakeup);
+2 -2
View File
@@ -16,7 +16,7 @@ void uwsgi_mule(int id) {
int i;
pid_t pid = fork();
pid_t pid = uwsgi_fork(uwsgi.mules[id-1].name);
if (pid == 0) {
uwsgi.muleid = id;
// avoid race conditions
@@ -44,10 +44,10 @@ void uwsgi_mule(int id) {
if (uwsgi.mules[id-1].patch) {
uwsgi_log("loading patch %s\n", uwsgi.mules[id-1].patch);
for (i = 0; i < 0xFF; i++) {
if (uwsgi.p[i]->mule) {
if (uwsgi.p[i]->mule(uwsgi.mules[id-1].patch) == 1) {
uwsgi_log("loaded mule patch %s\n", uwsgi.mules[id-1].patch);
break;
}
}
+1 -1
View File
@@ -422,7 +422,7 @@ int erlang_init() {
uwsgi_log("Erlang C-Node %s registered on port %d\n", ei_thisnodename(&uerl.cnode), ntohs(sin.sin_port));
if (register_fat_gateway("erlang", erlang_loop) == NULL) {
if (register_fat_gateway("uWSGI erlang c-node", erlang_loop) == NULL) {
uwsgi_log("unable to register the erlang gateway\n");
exit(1);
}
+2 -2
View File
@@ -701,13 +701,13 @@ int fastrouter_init() {
if (!ufr.nevents) ufr.nevents = 64;
if (ufr.code_string_code && ufr.code_string_function) {
if (register_fat_gateway("fastrouter", fastrouter_loop) == NULL) {
if (register_fat_gateway("uWSGI fastrouter", fastrouter_loop) == NULL) {
uwsgi_log("unable to register the fastrouter gateway\n");
exit(1);
}
}
else {
if (register_gateway("fastrouter", fastrouter_loop) == NULL) {
if (register_gateway("uWSGI fastrouter", fastrouter_loop) == NULL) {
uwsgi_log("unable to register the fastrouter gateway\n");
exit(1);
}
+11 -3
View File
@@ -136,6 +136,8 @@ struct http_session {
char uss[MAX_HTTP_VEC*2];
char buffer[UMAX16];
char path_info[UMAX16];
uint16_t path_info_len;
struct uwsgi_subscriber_name *un;
@@ -325,13 +327,19 @@ int http_parse(struct http_session *h_session) {
base = ptr;
while(ptr < watermark) {
if (*ptr == '?' && !query_string) {
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, base, ptr-base, &c);
// PATH_INFO must be url-decoded !!!
h_session->path_info_len = ptr-base;
http_url_decode(base, &h_session->path_info_len, h_session->path_info);
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, h_session->path_info, h_session->path_info_len, &c);
query_string = ptr+1;
}
else if (*ptr == ' ') {
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "REQUEST_URI", 11, base, ptr-base, &c);
if (!query_string) {
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, base, ptr-base, &c);
// PATH_INFO must be url-decoded !!!
h_session->path_info_len = ptr-base;
http_url_decode(base, &h_session->path_info_len, h_session->path_info);
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "PATH_INFO", 9, h_session->path_info, h_session->path_info_len, &c);
h_session->uh.pktsize += http_add_uwsgi_var(h_session->iov, h_session->uss+c, h_session->uss+c+2, "QUERY_STRING", 12, "", 0, &c);
}
else {
@@ -883,7 +891,7 @@ int http_init() {
uhttp.server = bind_to_tcp(uhttp.socket_name, uwsgi.listen_queue, strchr(uhttp.socket_name,':'));
if (register_gateway("http", http_loop) == NULL) {
if (register_gateway("uWSGI http", http_loop) == NULL) {
uwsgi_log("unable to register the http gateway\n");
exit(1);
}
+16
View File
@@ -1072,6 +1072,19 @@ PyObject *py_uwsgi_embedded_data(PyObject * self, PyObject * args) {
}
PyObject *py_uwsgi_setprocname(PyObject * self, PyObject * args) {
char *name = NULL;
if (!PyArg_ParseTuple(args, "s:setprocname", &name)) {
return NULL;
}
uwsgi_set_processname(name);
Py_INCREF(Py_None);
return Py_None;
}
PyObject *py_uwsgi_mule_msg(PyObject * self, PyObject * args) {
char *message = NULL;
@@ -2636,6 +2649,7 @@ PyObject *py_uwsgi_grunt(PyObject * self, PyObject * args) {
goto clear;
}
// use a normal fork here
grunt_pid = fork();
if (grunt_pid < 0) {
uwsgi_error("fork()");
@@ -2809,6 +2823,8 @@ static PyMethodDef uwsgi_advanced_methods[] = {
{"unlock", py_uwsgi_unlock, METH_VARARGS, ""},
{"cl", py_uwsgi_cl, METH_VARARGS, ""},
{"setprocname", py_uwsgi_setprocname, METH_VARARGS, ""},
{"listen_queue", py_uwsgi_listen_queue, METH_VARARGS, ""},
{"attach_daemon", py_uwsgi_attach_daemon, METH_VARARGS, ""},
+24 -6
View File
@@ -124,9 +124,18 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
base = ptr;
while (ptr < watermark) {
if (*ptr == '?' && !query_string) {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
if (watermark + (ptr - base) < (char *)(wsgi_req->proto_parser_buf + uwsgi.buffer_size)) {
wsgi_req->path_info = watermark;
wsgi_req->path_info_len = ptr - base;
http_url_decode(base, &wsgi_req->path_info_len, wsgi_req->path_info);
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info, wsgi_req->path_info_len);
}
else {
uwsgi_log("not enough space in wsgi_req http proto_parser_buf to encode PATH_INFO, consider tuning it with --buffer-size\n");
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
}
wsgi_req->path_info_pos = 3;
query_string = ptr + 1;
}
@@ -136,9 +145,18 @@ static int http_parse(struct wsgi_request *wsgi_req, char *watermark) {
wsgi_req->uri_len = ptr - base;
if (!query_string) {
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
if (watermark + (ptr - base) < (char *)(wsgi_req->proto_parser_buf + uwsgi.buffer_size)) {
wsgi_req->path_info = watermark;
wsgi_req->path_info_len = ptr - base;
http_url_decode(base, &wsgi_req->path_info_len, wsgi_req->path_info);
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info, wsgi_req->path_info_len);
}
else {
uwsgi_log("not enough space in wsgi_req http proto_parser_buf to encode PATH_INFO, consider tuning it with --buffer-size\n");
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "PATH_INFO", 9, base, ptr - base);
wsgi_req->path_info = (wsgi_req->buffer + wsgi_req->uh.pktsize) - (ptr - base);
wsgi_req->path_info_len = ptr - base;
}
wsgi_req->path_info_pos = 5;
wsgi_req->uh.pktsize += proto_base_add_uwsgi_var(wsgi_req, "QUERY_STRING", 12, "", 0);
}
+17 -1
View File
@@ -30,6 +30,13 @@ int uwsgi_signal_handler(uint8_t sig) {
set_mule_harakiri(uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI]);
}
}
#ifdef UWSGI_SPOOLER
else if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0 && (getpid() == uwsgi.shared->spooler_pid)) {
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]);
}
}
#endif
int ret = uwsgi.p[use->modifier1]->signal_handler(sig, use->handler);
@@ -39,12 +46,19 @@ int uwsgi_signal_handler(uint8_t sig) {
set_harakiri(0);
}
}
if (uwsgi.muleid > 0) {
else if (uwsgi.muleid > 0) {
uwsgi.mules[uwsgi.muleid-1].sig = 0;
if(uwsgi.mules[uwsgi.muleid-1].harakiri > 0) {
set_mule_harakiri(0);
}
}
#ifdef UWSGI_SPOOLER
else if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0 && (getpid() == uwsgi.shared->spooler_pid)) {
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(0);
}
}
#endif
return ret;
}
@@ -221,6 +235,7 @@ void uwsgi_route_signal(uint8_t sig) {
else if (!strcmp(use->receiver, "subscribed")) {
}
// route to spooler
#ifdef UWSGI_SPOOLER
else if (!strcmp(use->receiver, "spooler")) {
if (ushared->worker_signal_pipe[0] != -1) {
if (write(ushared->spooler_signal_pipe[0], &sig, 1) != 1) {
@@ -229,6 +244,7 @@ void uwsgi_route_signal(uint8_t sig) {
}
}
}
#endif
else if (!strcmp(use->receiver, "mules")) {
for(i=0;i<uwsgi.mules_cnt;i++) {
if (write(uwsgi.mules[i].signal_pipe[0], &sig, 1) != 1) {
+7 -1
View File
@@ -16,7 +16,7 @@ pid_t spooler_start() {
int i;
pid_t pid = fork();
pid_t pid = uwsgi_fork("uWSGI spooler");
if (pid < 0) {
uwsgi_error("fork()");
exit(1);
@@ -413,7 +413,13 @@ void spooler_manage_task(char *dir, char *task) {
for(i=0;i<0xff;i++) {
if (uwsgi.p[i]->spooler) {
time_t now = time(NULL);
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]);
}
ret = uwsgi.p[i]->spooler(task, spool_buf, uh.pktsize, body, body_len);
if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) {
set_spooler_harakiri(0);
}
if (body) {
free(body);
}
+212 -15
View File
@@ -2,6 +2,7 @@
extern struct uwsgi_server uwsgi;
extern char **environ;
/* statistically ordered */
struct http_status_codes hsc[] = {
@@ -121,6 +122,20 @@ void set_mule_harakiri(int sec) {
}
}
#ifdef UWSGI_SPOOLER
void set_spooler_harakiri(int sec) {
if (sec == 0) {
uwsgi.shared->spooler_harakiri = 0;
}
else {
uwsgi.shared->spooler_harakiri = time(NULL) + sec;
}
if (!uwsgi.master_process) {
alarm(sec);
}
}
#endif
void daemonize(char *logfile) {
pid_t pid;
@@ -1697,24 +1712,45 @@ int uwsgi_read_whole_body(struct wsgi_request *wsgi_req, char *buf, size_t len)
return 0;
}
void add_exported_option(char *key, char *value, int configured) {
void _add_exported_option(char *key, char *value, int configured) {
if (!uwsgi.exported_opts) {
uwsgi.exported_opts = uwsgi_malloc(sizeof(struct uwsgi_opt *));
}
else {
uwsgi.exported_opts = realloc(uwsgi.exported_opts, sizeof(struct uwsgi_opt *) * (uwsgi.exported_opts_cnt + 1));
if (!uwsgi.exported_opts) {
uwsgi_error("realloc()");
exit(1);
}
uwsgi.exported_opts = uwsgi_malloc(sizeof(struct uwsgi_opt *));
}
else {
uwsgi.exported_opts = realloc(uwsgi.exported_opts, sizeof(struct uwsgi_opt *) * (uwsgi.exported_opts_cnt + 1));
if (!uwsgi.exported_opts) {
uwsgi_error("realloc()");
exit(1);
}
}
uwsgi.exported_opts[uwsgi.exported_opts_cnt] = uwsgi_malloc(sizeof(struct uwsgi_opt));
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->key = key;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->value = value;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->configured = configured;
uwsgi.exported_opts_cnt++;
}
void add_exported_option(char *key, char *value, int configured) {
char *v = value;
if (value && strchr(value, ';')) {
v = uwsgi_str(value);
}
uwsgi.exported_opts[uwsgi.exported_opts_cnt] = uwsgi_malloc(sizeof(struct uwsgi_opt));
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->key = key;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->value = value;
uwsgi.exported_opts[uwsgi.exported_opts_cnt]->configured = configured;
uwsgi.exported_opts_cnt++;
if (v == NULL) {
_add_exported_option(key, v, configured);
return;
}
char *p = strtok(v, ";");
while(p != NULL) {
_add_exported_option(key, p, configured);
p = strtok(NULL, ";");
}
}
@@ -2225,8 +2261,13 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
char *a;
int cnt = 1;
int devnull = -1;
int throttle = 0;
pid_t pid = fork();
if (uwsgi.current_time - ud->last_spawn <= 3) {
throttle = ud->respawns - (uwsgi.current_time-ud->last_spawn);
}
pid_t pid = uwsgi_fork("uWSGI external daemon");
if (pid < 0) {
uwsgi_error("fork()");
return;
@@ -2289,6 +2330,12 @@ void spawn_daemon(struct uwsgi_daemon *ud) {
argv[cnt] = NULL;
if (throttle) {
uwsgi_log_verbose("throttling %s for %d seconds\n", argv[0], throttle);
sleep(throttle);
}
uwsgi_log_verbose("running %s\n", argv[0]);
if (execvp(argv[0], argv)) {
uwsgi_error("execvp()");
}
@@ -2417,6 +2464,37 @@ int uwsgi_list_has_str(char *list, char *str) {
return 0;
}
char hex2num(char *str) {
char val = 0;
val <<= 4;
if (str[0] >= '0' && str[0] <= '9') {
val += str[0] & 0x0F;
}
else if ( str[0] >= 'A' && str[0] <= 'F') {
val += (str[0] & 0x0F) + 9;
}
else {
return 0;
}
val <<= 4;
if (str[1] >= '0' && str[1] <= '9') {
val += str[1] & 0x0F;
}
else if ( str[1] >= 'A' && str[1] <= 'F') {
val += (str[1] & 0x0F) + 9;
}
else {
return 0;
}
return val;
}
int uwsgi_str2_num(char *str) {
int num = 0;
@@ -3187,3 +3265,122 @@ void uwsgi_apply_config_pass(char symbol, char*(*hook)(char *) ) {
}
}
void uwsgi_set_processname(char *name) {
#if defined(__linux__) || defined(__sun__)
size_t amount = 0;
// prepare for strncat
*uwsgi.orig_argv[0] = 0;
if (uwsgi.procname_prefix) {
amount += strlen(uwsgi.procname_prefix);
if ((int)amount > uwsgi.max_procname-1) return;
strncat(uwsgi.orig_argv[0], uwsgi.procname_prefix, uwsgi.max_procname-(amount+1));
}
amount += strlen(name);
if ((int)amount > uwsgi.max_procname-1) return;
strncat(uwsgi.orig_argv[0], name, (uwsgi.max_procname-amount+1));
if (uwsgi.procname_append) {
amount += strlen(uwsgi.procname_append);
if ((int)amount > uwsgi.max_procname-1) return;
strncat(uwsgi.orig_argv[0], uwsgi.procname_append, uwsgi.max_procname-(amount+1));
}
memset(uwsgi.orig_argv[0]+amount+1, ' ', uwsgi.max_procname-(amount-1));
#elif defined(__FreeBSD__)
if (uwsgi.procname_prefix) {
if (!uwsgi.procname_append) {
setproctitle("-%s%s", uwsgi.procname_prefix, name);
}
else {
setproctitle("-%s%s%s", uwsgi.procname_prefix, name, uwsgi.procname_append);
}
}
else if (uwsgi.procname_append) {
if (!uwsgi.procname_prefix) {
setproctitle("-%s%s", name, uwsgi.procname_append);
}
else {
setproctitle("-%s%s%s", uwsgi.procname_prefix, name, uwsgi.procname_append);
}
}
else {
setproctitle("-%s", name);
}
#endif
}
// this is a wrapper for fork restoring original argv
pid_t uwsgi_fork(char *name) {
pid_t pid = fork();
if (pid == 0) {
#if defined(__linux__) || defined(__sun__)
int i;
for(i=0;i<uwsgi.argc;i++) {
strcpy(uwsgi.orig_argv[i],uwsgi.argv[i]);
}
#endif
if (uwsgi.auto_procname && name) {
if (uwsgi.procname) {
uwsgi_set_processname(uwsgi.procname);
}
else {
uwsgi_set_processname(name);
}
}
}
return pid;
}
void http_url_decode(char *buf, uint16_t *len, char *dst) {
uint16_t i;
int percent = 0;
char value[2];
size_t new_len = 0;
char *ptr = dst;
value[0] = '0';
value[1] = '0';
for(i=0;i<*len;i++) {
if (buf[i] == '%') {
if (percent == 0) {
percent = 1;
}
else {
*ptr++= '%';
new_len++;
percent = 0;
}
}
else {
if (percent == 1) {
value[0] = buf[i];
percent = 2;
}
else if (percent == 2) {
value[1] = buf[i];
*ptr++= hex2num(value);
percent = 0;
new_len++;
}
else {
*ptr++= buf[i];
new_len++;
}
}
}
*len = new_len;
}
+144 -40
View File
@@ -78,6 +78,11 @@ static struct option long_base_options[] = {
#ifdef UWSGI_THREADING
{"enable-threads", no_argument, 0, 'T'},
#endif
{"auto-procname", no_argument, &uwsgi.auto_procname, 1},
{"procname-prefix", required_argument, 0, LONG_ARGS_PROCNAME_PREFIX},
{"procname-append", required_argument, 0, LONG_ARGS_PROCNAME_APPEND},
{"procname", required_argument, 0, LONG_ARGS_PROCNAME},
{"procname-master", required_argument, 0, LONG_ARGS_PROCNAME_MASTER},
{"single-interpreter", no_argument, 0, 'i'},
{"master", no_argument, 0, 'M'},
{"emperor", required_argument, 0, LONG_ARGS_EMPEROR},
@@ -510,7 +515,7 @@ void kill_them_all(int signum) {
#ifdef UWSGI_SPOOLER
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
kill(uwsgi.shared->spooler_pid, SIGKILL);
uwsgi_log("killed the spooler with pid %d\n", uwsgi.shared->spooler_pid);
uwsgi_log("killing the spooler with pid %d\n", uwsgi.shared->spooler_pid);
}
#endif
@@ -518,7 +523,7 @@ void kill_them_all(int signum) {
if (uwsgi.emperor_pid >= 0) {
kill(uwsgi.emperor_pid, SIGKILL);
waitpid(uwsgi.emperor_pid, &i, 0);
uwsgi_log("killed the emperor with pid %d\n", uwsgi.emperor_pid);
uwsgi_log("killing the emperor with pid %d\n", uwsgi.emperor_pid);
}
@@ -560,14 +565,14 @@ void grace_them_all(int signum) {
#ifdef UWSGI_SPOOLER
if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) {
kill(uwsgi.shared->spooler_pid, SIGKILL);
uwsgi_log("killed the spooler with pid %d\n", uwsgi.shared->spooler_pid);
uwsgi_log("killing the spooler with pid %d\n", uwsgi.shared->spooler_pid);
}
#endif
if (uwsgi.emperor_pid >= 0) {
kill(uwsgi.emperor_pid, SIGKILL);
waitpid(uwsgi.emperor_pid, &i, 0);
uwsgi_log("killed the emperor with pid %d\n", uwsgi.emperor_pid);
uwsgi_log("killing the emperor with pid %d\n", uwsgi.emperor_pid);
}
for (i = 0; i < uwsgi.shared->daemons_cnt; i++) {
@@ -653,6 +658,7 @@ void reap_them_all(int signum) {
}
for (i = 0; i < uwsgi.mules_cnt; i++) {
if (!uwsgi.mules) break;
if (uwsgi.mules[i].pid > 0)
kill(uwsgi.mules[i].pid, SIGKILL);
}
@@ -660,7 +666,7 @@ void reap_them_all(int signum) {
if (uwsgi.emperor_pid >= 0) {
kill(uwsgi.emperor_pid, SIGKILL);
waitpid(uwsgi.emperor_pid, &i, 0);
uwsgi_log("killed the emperor with pid %d\n", uwsgi.emperor_pid);
uwsgi_log("killing the emperor with pid %d\n", uwsgi.emperor_pid);
}
if (!uwsgi.workers)
@@ -847,6 +853,56 @@ void signal_pidfile(int sig, char *filename) {
}
}
void fixup_argv_and_environ(int argc, char **argv, char **environ) {
uwsgi.orig_argv = argv;
uwsgi.argv = argv;
uwsgi.argc = argc;
uwsgi.environ = environ;
#if defined(__linux__) || defined(__sun__)
int i;
int env_count = 0;
uwsgi.argv = uwsgi_malloc( sizeof(char *) * argc);
for(i=0;i<argc;i++) {
if (i==0 || argv[0] + uwsgi.max_procname + 1 == argv[i]) {
uwsgi.max_procname += strlen(argv[i]) + 1;
}
uwsgi.argv[i] = strdup(argv[i]);
}
uwsgi.max_procname++;
for (i = 0; environ[i] != NULL; i++) {
// useless
//if ((environ[0] + uwsgi.max_procname + 1) == environ[i]) {
uwsgi.max_procname += strlen(environ[i]) + 1;
//}
env_count++;
}
uwsgi.environ = uwsgi_malloc(sizeof(char *) * env_count);
for(i=0;i<env_count;i++) {
uwsgi.environ[i] = strdup(environ[i]);
#ifdef UWSGI_DEBUG
uwsgi_log("ENVIRON: %s\n", uwsgi.environ[i]);
#endif
environ[i] = uwsgi.environ[i];
}
#ifdef UWSGI_DEBUG
uwsgi_log("max space for custom process name = %d\n", uwsgi.max_procname);
#endif
//environ = uwsgi.environ;
#endif
}
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int argc, char *argv[], char *envp[]) {
@@ -886,6 +942,7 @@ int main(int argc, char *argv[], char *envp[]) {
signal(SIGTERM, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
//initialize masterpid with a default value
masterpid = getpid();
@@ -1024,6 +1081,9 @@ int main(int argc, char *argv[], char *envp[]) {
uwsgi.page_size = getpagesize();
uwsgi.binary_path = uwsgi_get_binary_path(argv[0]);
// ok we can now safely play with argv and environ
fixup_argv_and_environ(argc, argv, environ);
//initialize embedded plugins
UWSGI_LOAD_EMBEDDED_PLUGINS
// now a bit of magic, if the executable basename contains a 'uwsgi_' string,
@@ -1067,7 +1127,7 @@ int main(int argc, char *argv[], char *envp[]) {
#endif
uwsgi.option_index = -1;
while ((i = getopt_long(argc, argv, short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
while ((i = getopt_long(uwsgi.argc, uwsgi.argv, short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
if (uwsgi.option_index > -1) {
optname = (char *) uwsgi.long_options[uwsgi.option_index].name;
@@ -1091,8 +1151,8 @@ int main(int argc, char *argv[], char *envp[]) {
#endif
if (optind < argc) {
for(i=optind;i<argc;i++) {
char *lazy = argv[i];
for(i=optind;i<uwsgi.argc;i++) {
char *lazy = uwsgi.argv[i];
if (lazy[0] != '[') {
if (0) {
}
@@ -1159,7 +1219,6 @@ int main(int argc, char *argv[], char *envp[]) {
}
}
struct uwsgi_string_list *config_file;
#ifdef UWSGI_XML
if (uwsgi.xml_config != NULL) {
@@ -1169,6 +1228,7 @@ int main(int argc, char *argv[], char *envp[]) {
}
#endif
#ifdef UWSGI_INI
struct uwsgi_string_list *config_file;
if (uwsgi.ini != NULL) {
config_file = uwsgi.ini;
while(config_file) {
@@ -1337,8 +1397,8 @@ int main(int argc, char *argv[], char *envp[]) {
//call after_opt hooks
if (uwsgi.binary_path == argv[0]) {
uwsgi.binary_path = uwsgi_str(argv[0]);
if (uwsgi.binary_path == uwsgi.argv[0]) {
uwsgi.binary_path = uwsgi_str(uwsgi.argv[0]);
}
if (!uwsgi.no_initial_output) {
@@ -1433,7 +1493,7 @@ int main(int argc, char *argv[], char *envp[]) {
exit(1);
}
uwsgi.emperor_pid = fork();
uwsgi.emperor_pid = uwsgi_fork("uWSGI Emperor");
if (uwsgi.emperor_pid < 0) {
uwsgi_error("pid()");
exit(1);
@@ -1454,7 +1514,7 @@ int main(int argc, char *argv[], char *envp[]) {
// call jail systems
for (i = 0; i < uwsgi.gp_cnt; i++) {
if (uwsgi.gp[i]->jail) {
uwsgi.gp[i]->jail(uwsgi_start, argv);
uwsgi.gp[i]->jail(uwsgi_start, uwsgi.argv);
}
}
@@ -1462,12 +1522,12 @@ int main(int argc, char *argv[], char *envp[]) {
// TODO pluginize basic Linux namespace support
#ifdef __linux__
if (uwsgi.ns) {
linux_namespace_start((void *) argv);
linux_namespace_start((void *) uwsgi.argv);
// never here
}
else {
#endif
uwsgi_start((void *) argv);
uwsgi_start((void *) uwsgi.argv);
#ifdef __linux__
}
#endif
@@ -1479,8 +1539,6 @@ int main(int argc, char *argv[], char *envp[]) {
int uwsgi_start(void *v_argv) {
char **argv = v_argv;
#ifdef UWSGI_DEBUG
int so_bufsize;
socklen_t so_bufsize_len;
@@ -1590,7 +1648,7 @@ int uwsgi_start(void *v_argv) {
exit(1);
}
uwsgi.emperor_pid = fork();
uwsgi.emperor_pid = uwsgi_fork("uWSGI Emperor");
if (uwsgi.emperor_pid < 0) {
uwsgi_error("pid()");
exit(1);
@@ -2154,6 +2212,7 @@ skipzero:
for(i=1;i<=uwsgi.numproc;i++) {
uwsgi.workers[i].signal_pipe[0] = - 1;
uwsgi.workers[i].signal_pipe[1] = - 1;
snprintf(uwsgi.workers[i].name, 0xff, "uWSGI worker %d", i);
}
if (uwsgi.master_process) {
@@ -2193,6 +2252,8 @@ skipzero:
uwsgi_error("socketpair()");
exit(1);
}
snprintf(uwsgi.mules[i].name, 0xff, "uWSGI mule %d", i+1);
}
}
@@ -2370,15 +2431,14 @@ skipzero:
}
}
if (getpid() == masterpid && uwsgi.master_process == 1) {
#ifdef UWSGI_AS_SHARED_LIBRARY
int ml_ret = master_loop(argv, environ);
int ml_ret = master_loop(uwsgi.argv, uwsgi.environ);
if (ml_ret == -1) {
return 0;
}
#else
(void) master_loop(argv, environ);
(void) master_loop(uwsgi.argv, uwsgi.environ);
#endif
//from now on the process is a real worker
}
@@ -2799,6 +2859,22 @@ static int manage_base_opt(int i, char *optarg) {
case 0:
return 1;
case LONG_ARGS_PROCNAME_PREFIX:
uwsgi.auto_procname = 1;
uwsgi.procname_prefix = optarg;
return 1;
case LONG_ARGS_PROCNAME_APPEND:
uwsgi.auto_procname = 1;
uwsgi.procname_append = optarg;
return 1;
case LONG_ARGS_PROCNAME:
uwsgi.auto_procname = 1;
uwsgi.procname = optarg;
return 1;
case LONG_ARGS_PROCNAME_MASTER:
uwsgi.auto_procname = 1;
uwsgi.procname_master = optarg;
return 1;
#ifdef UWSGI_UDP
case LONG_ARGS_CLUSTER_RELOAD:
send_udp_message(98, optarg, "", 0);
@@ -3521,12 +3597,14 @@ static int manage_base_opt(int i, char *optarg) {
case 't':
uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] = atoi(optarg);
return 1;
#ifdef UWSGI_SPOOLER
case LONG_ARGS_SPOOLER_HARAKIRI:
uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] = atoi(optarg);
return 1;
case LONG_ARGS_SPOOLER_CHDIR:
uwsgi.spooler_chdir = optarg;
return 1;
#endif
case LONG_ARGS_MULE_HARAKIRI:
uwsgi.shared->options[UWSGI_OPTION_MULE_HARAKIRI] = atoi(optarg);
return 1;
@@ -3601,32 +3679,58 @@ static int manage_base_opt(int i, char *optarg) {
return 0;
}
void manage_opt(int i, char *optarg) {
int _manage_opt(int i, char *p) {
int j;
if (manage_base_opt(i, optarg)) {
if (manage_base_opt(i, p)) {
return 1;
}
for (j = 0; j < 0xFF; j++) {
if (uwsgi.p[j]->manage_opt) {
if (uwsgi.p[j]->manage_opt(i, p)) {
return 1;
}
}
}
for (j = 0; j < uwsgi.gp_cnt; j++) {
if (uwsgi.gp[j]->manage_opt) {
if (uwsgi.gp[j]->manage_opt(i, p)) {
return 1;
}
}
}
return 0;
}
void manage_opt(int i, char *optarg) {
char *value = optarg;
if (value && strchr(optarg, ';')) {
value = uwsgi_str(optarg);
}
if (!value) {
if (!_manage_opt(i, NULL)) {
exit(1);
}
return;
}
for (j = 0; j < 0xFF; j++) {
if (uwsgi.p[j]->manage_opt) {
if (uwsgi.p[j]->manage_opt(i, optarg)) {
return;
}
}
char *p = strtok(value, ";");
while(p != NULL) {
if (_manage_opt(i, p)) goto next;
exit(1);
next:
p = strtok(NULL, ";");
}
for (j = 0; j < uwsgi.gp_cnt; j++) {
if (uwsgi.gp[j]->manage_opt) {
if (uwsgi.gp[j]->manage_opt(i, optarg)) {
return;
}
}
}
//never here
exit(1);
return;
}
+24
View File
@@ -528,6 +528,10 @@ struct uwsgi_opt {
#define LONG_ARGS_EMPEROR_STATS 17150
#define LONG_ARGS_SPOOLER_CHDIR 17151
#define LONG_ARGS_LOCKS 17152
#define LONG_ARGS_PROCNAME_PREFIX 17153
#define LONG_ARGS_PROCNAME_APPEND 17154
#define LONG_ARGS_PROCNAME 17155
#define LONG_ARGS_PROCNAME_MASTER 17156
#define UWSGI_OK 0
@@ -966,6 +970,17 @@ struct uwsgi_server {
char hostname[256];
int hostname_len;
char **orig_argv;
char **argv;
int argc;
int max_procname;
int auto_procname;
char **environ;
char *procname_prefix;
char *procname_append;
char *procname_master;
char *procname;
// quiet startup
int no_initial_output;
@@ -1594,6 +1609,7 @@ struct uwsgi_shared {
#ifdef UWSGI_SPOOLER
pid_t spooler_pid;
int spooler_frequency;
time_t spooler_harakiri;
#endif
#ifdef UWSGI_SNMP
@@ -1712,6 +1728,7 @@ struct uwsgi_worker {
uint64_t avg_response_time;
char name[0xff];
};
struct uwsgi_mule {
@@ -1787,6 +1804,7 @@ pid_t spooler_start(void);
void set_harakiri(int);
void set_mule_harakiri(int);
void set_spooler_harakiri(int);
void inc_harakiri(int);
#ifdef __BIG_ENDIAN__
@@ -2371,6 +2389,12 @@ char *uwsgi_string_get_list(struct uwsgi_string_list **, int, size_t *);
void uwsgi_fixup_fds(int, int);
void uwsgi_set_processname(char *);
void http_url_decode(char *, uint16_t *, char *);
pid_t uwsgi_fork(char *);
#ifdef UWSGI_CAP
void uwsgi_build_cap(char *);
#endif
+10
View File
@@ -2,6 +2,7 @@ import uwsgi
import os
import gc
import sys
from uwsgidecorators import *
gc.set_debug(gc.DEBUG_SAVEALL)
print os.environ
@@ -42,10 +43,19 @@ routes['/logo'] = serve_logo
routes['/config'] = serve_config
routes['/options'] = serve_options
@postfork
def setprocname():
if uwsgi.worker_id() > 0:
uwsgi.setprocname("i am the worker %d" % uwsgi.worker_id())
def application(env, start_response):
uwsgi.mule_msg(env['REQUEST_URI'], 1)
req = uwsgi.workers()[uwsgi.worker_id()-1]['requests']
uwsgi.setprocname("worker %d managed %d requests" % (uwsgi.worker_id(), req))
gc.collect(2)
if DEBUG:
print env['wsgi.input'].fileno()