diff --git a/master.c b/master.c index 7a2ef296..e595f926 100644 --- a/master.c +++ b/master.c @@ -454,6 +454,17 @@ int master_loop(char **argv, char **environ) { } } + // spawn daemons + struct uwsgi_daemon *ud = uwsgi.daemons; + while(ud) { + if (!ud->registered) { + spawn_daemon(ud); + ud->registered = 1; + } + ud = ud->next; + } + + // first subscription struct uwsgi_string_list *subscriptions = uwsgi.subscriptions; while(subscriptions) { @@ -634,7 +645,7 @@ healthy: if ((uwsgi.cheap || ready_to_die >= uwsgi.numproc) && uwsgi.to_hell) { // 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++) { + for(i=0;i<(uwsgi.gateways_cnt+uwsgi.daemons_cnt+uwsgi.mules_cnt);i++) { diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG); } @@ -643,7 +654,7 @@ healthy: } if ( (uwsgi.cheap || ready_to_reload >= uwsgi.numproc) && uwsgi.to_heaven) { // 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++) { + for(i=0;i<(uwsgi.gateways_cnt+uwsgi.daemons_cnt+uwsgi.mules_cnt);i++) { diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG); } @@ -711,7 +722,7 @@ healthy: if (!uwsgi.cheap) { - if (uwsgi.numproc > 0 || uwsgi.gateways_cnt > 0 || ushared->daemons_cnt > 0) { + if (uwsgi.numproc > 0 || uwsgi.gateways_cnt > 0 || uwsgi.daemons_cnt > 0) { master_has_children = 1; } #ifdef UWSGI_SPOOLER @@ -762,16 +773,6 @@ healthy: } } - // add unregistered daemons - // locking is not needed as daemons can only increase (for now) - for(i=0;idaemons_cnt;i++) { - if (!ushared->daemons[i].registered) { - uwsgi_log("spawning daemon %s\n", ushared->daemons[i].command); - spawn_daemon(&ushared->daemons[i]); - ushared->daemons[i].registered = 1; - } - } - // add unregistered timers // locking is not needed as timers can only increase @@ -1463,12 +1464,14 @@ healthy: /* reload the daemons */ // TODO reload_gateway(diedpid); pid_found = 0; - for(i=0;idaemons_cnt;i++) { - if (uwsgi.shared->daemons[i].pid == diedpid) { - spawn_daemon(&uwsgi.shared->daemons[i]); + struct uwsgi_daemon *ud = uwsgi.daemons; + while(ud) { + if (ud->pid == diedpid) { + spawn_daemon(ud); pid_found = 1; break; } + ud = ud->next; } if (pid_found) continue; @@ -1511,11 +1514,13 @@ healthy: } } - for(i=0;idaemons_cnt;i++) { - if (uwsgi.shared->daemons[i].pid == diedpid) { - uwsgi_log("daemon %d (pid: %d) annihilated\n", i+1, (int) diedpid); + struct uwsgi_daemon *ud = uwsgi.daemons; + while(ud) { + if (ud->pid == diedpid) { + uwsgi_log("daemon \"%s\" (pid: %d) annihilated\n", ud->command, (int) diedpid); goto next; } + ud = ud->next; } if (WIFEXITED(waitpid_status)) { diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index 2bdad70d..b6f8e924 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -464,23 +464,6 @@ PyObject *py_uwsgi_register_rpc(PyObject * self, PyObject * args) { return Py_True; } -PyObject *py_uwsgi_attach_daemon(PyObject * self, PyObject * args) { - - char *command = NULL; - - if (!PyArg_ParseTuple(args, "s:attach_daemon", &command)) { - return NULL; - } - - if (uwsgi_attach_daemon(command)) { - Py_INCREF(Py_None); - return Py_None; - } - - Py_INCREF(Py_True); - return Py_True; -} - PyObject *py_uwsgi_signal_registered(PyObject * self, PyObject * args) { uint8_t uwsgi_signal; @@ -3021,8 +3004,6 @@ static PyMethodDef uwsgi_advanced_methods[] = { {"listen_queue", py_uwsgi_listen_queue, METH_VARARGS, ""}, - {"attach_daemon", py_uwsgi_attach_daemon, METH_VARARGS, ""}, - {"register_signal", py_uwsgi_register_signal, METH_VARARGS, ""}, {"signal", py_uwsgi_signal, METH_VARARGS, ""}, {"signal_wait", py_uwsgi_signal_wait, METH_VARARGS, ""}, diff --git a/utils.c b/utils.c index 8587e6b8..871b27a7 100644 --- a/utils.c +++ b/utils.c @@ -2236,32 +2236,6 @@ char *uwsgi_get_last_char(char *what, char c) { return ptr; } -int uwsgi_attach_daemon(char *command) { - - struct uwsgi_daemon *d; - int ret = -1; - - uwsgi_lock(uwsgi.daemon_table_lock); - - if (uwsgi.shared->daemons_cnt < MAX_DAEMONS) { - d = &uwsgi.shared->daemons[uwsgi.shared->daemons_cnt]; - - memcpy(d->command, command, UMIN(strlen(command), 0xff - 1)); - d->registered = 0; - d->status = 0; - - uwsgi.shared->daemons_cnt++; - - ret = 0; - uwsgi_log("registered daemon %s\n", command); - } - - uwsgi_unlock(uwsgi.daemon_table_lock); - - return ret; - -} - void spawn_daemon(struct uwsgi_daemon *ud) { char *argv[64]; @@ -2318,7 +2292,11 @@ void spawn_daemon(struct uwsgi_daemon *ud) { uwsgi_error("prctl()"); } #endif - memcpy(ud->tmp_command, ud->command, 0xff); + + // free the old area + if (ud->tmp_command) free(ud->tmp_command); + + ud->tmp_command = uwsgi_str(ud->command); a = strtok(ud->tmp_command, " "); if (a) { @@ -2338,14 +2316,15 @@ void spawn_daemon(struct uwsgi_daemon *ud) { argv[cnt] = NULL; if (throttle) { - uwsgi_log_verbose("throttling %s for %d seconds\n", argv[0], throttle); + uwsgi_log("[uwsgi-daemons] throttling \"%s\" (%s) for %d seconds\n", ud->command, argv[0], throttle); sleep(throttle); } - uwsgi_log_verbose("running %s\n", argv[0]); + uwsgi_log("[uwsgi-daemons] spawning \"%s\" (%s)\n", ud->command, argv[0]); if (execvp(argv[0], argv)) { uwsgi_error("execvp()"); } + uwsgi_log("[uwsgi-daemons] unable to spawn \"%s\" (%s)\n", ud->command, argv[0]); // never here; exit(1); @@ -2658,6 +2637,39 @@ char *uwsgi_netstring(char *buf, size_t len, char **netstring, size_t *netstring return NULL; } +struct uwsgi_daemon *uwsgi_daemon_new(struct uwsgi_daemon **ud, char *command) { + + struct uwsgi_daemon *uwsgi_ud = *ud, *old_ud; + + if (!uwsgi_ud) { + *ud = uwsgi_malloc(sizeof(struct uwsgi_daemon)); + uwsgi_ud = *ud; + } + else { + while(uwsgi_ud) { + old_ud = uwsgi_ud; + uwsgi_ud = uwsgi_ud->next; + } + + uwsgi_ud = uwsgi_malloc(sizeof(struct uwsgi_daemon)); + old_ud->next = uwsgi_ud; + } + + uwsgi_ud->command = command; + uwsgi_ud->tmp_command = NULL; + uwsgi_ud->pid = 0; + uwsgi_ud->status = 0; + uwsgi_ud->registered = 0; + uwsgi_ud->next = NULL; + uwsgi_ud->respawns = 0; + uwsgi_ud->last_spawn = 0; + + uwsgi.daemons_cnt++; + + return uwsgi_ud; +} + + struct uwsgi_dyn_dict *uwsgi_dyn_dict_new(struct uwsgi_dyn_dict **dd, char *key, int keylen, char *val, int vallen) { struct uwsgi_dyn_dict *uwsgi_dd = *dd, *old_dd; diff --git a/uwsgi.c b/uwsgi.c index ec0196f6..e2c7aecd 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -558,9 +558,11 @@ void kill_them_all(int signum) { } - for (i = 0; i < uwsgi.shared->daemons_cnt; i++) { - if (uwsgi.shared->daemons[i].pid > 0) - kill(-uwsgi.shared->daemons[i].pid, SIGKILL); + struct uwsgi_daemon *ud = uwsgi.daemons; + while(ud) { + if (ud->pid > 0) + kill(-ud->pid, SIGKILL); + ud = ud->next; } for (i = 0; i < uwsgi.gateways_cnt; i++) { @@ -606,10 +608,12 @@ void grace_them_all(int signum) { uwsgi_log("killing the emperor with pid %d\n", uwsgi.emperor_pid); } - for (i = 0; i < uwsgi.shared->daemons_cnt; i++) { - if (uwsgi.shared->daemons[i].pid > 0) - kill(-uwsgi.shared->daemons[i].pid, SIGKILL); - } + struct uwsgi_daemon *ud = uwsgi.daemons; + while(ud) { + if (ud->pid > 0) + kill(-ud->pid, SIGKILL); + ud = ud->next; + } for (i = 0; i < uwsgi.gateways_cnt; i++) { if (uwsgi.gateways[i].pid > 0) @@ -686,10 +690,12 @@ void reap_them_all(int signum) { uwsgi.to_heaven = 1; else uwsgi.to_outworld = 1; - for (i = 0; i < uwsgi.shared->daemons_cnt; i++) { - if (uwsgi.shared->daemons[i].pid > 0) - kill(-uwsgi.shared->daemons[i].pid, SIGKILL); - } + struct uwsgi_daemon *ud = uwsgi.daemons; + while(ud) { + if (ud->pid > 0) + kill(-ud->pid, SIGKILL); + ud = ud->next; + } for (i = 0; i < uwsgi.gateways_cnt; i++) { if (uwsgi.gateways[i].pid > 0) @@ -1849,10 +1855,6 @@ int uwsgi_start(void *v_argv) { uwsgi.rb_timer_table_lock = uwsgi_mmap_shared_lock(); uwsgi_lock_init(uwsgi.rb_timer_table_lock); - // daemons table lock - uwsgi.daemon_table_lock = uwsgi_mmap_shared_lock(); - uwsgi_lock_init(uwsgi.daemon_table_lock); - // cron table lock uwsgi.cron_table_lock = uwsgi_mmap_shared_lock(); uwsgi_lock_init(uwsgi.cron_table_lock); @@ -1892,17 +1894,9 @@ int uwsgi_start(void *v_argv) { uwsgi_init_cache(); } - // attach startup daemons - if (uwsgi.master_process) { - for (i = 0; i < uwsgi.startup_daemons_cnt; i++) { - if (uwsgi_attach_daemon(uwsgi.startup_daemons[i])) { - uwsgi_log("!!! unable to attach daemon %s !!!\n", uwsgi.startup_daemons[i]); - } - } - // create the cache server - if (uwsgi.cache_server) { - uwsgi.cache_server_fd = uwsgi_cache_server(uwsgi.cache_server, uwsgi.cache_server_threads); - } + // create the cache server + if (uwsgi.master_process && uwsgi.cache_server) { + uwsgi.cache_server_fd = uwsgi_cache_server(uwsgi.cache_server, uwsgi.cache_server_threads); } /* plugin initialization */ @@ -3364,13 +3358,7 @@ static int manage_base_opt(int i, char *optarg) { signal_pidfile(SIGTSTP, optarg); exit(0); case LONG_ARGS_ATTACH_DAEMON: - if (uwsgi.startup_daemons_cnt < MAX_DAEMONS) { - uwsgi.startup_daemons[uwsgi.startup_daemons_cnt] = optarg; - uwsgi.startup_daemons_cnt++; - } - else { - uwsgi_log("you can specify at most %d --attach-daemons options\n", MAX_DAEMONS); - } + uwsgi_daemon_new(&uwsgi.daemons, optarg); return 1; case LONG_ARGS_SUBSCRIBE_TO: uwsgi.master_process = 1; diff --git a/uwsgi.h b/uwsgi.h index c17a2578..92189219 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -39,7 +39,6 @@ extern "C" { #define MAX_GENERIC_PLUGINS 64 #define MAX_RPC 64 #define MAX_GATEWAYS 64 -#define MAX_DAEMONS 8 #define MAX_CRONS 64 #ifndef UWSGI_LOAD_EMBEDDED_PLUGINS @@ -326,8 +325,8 @@ struct uwsgi_gateway { // Daemons are external processes maintained by the master struct uwsgi_daemon { - char command[0xff]; - char tmp_command[0xff]; + char *command; + char *tmp_command; pid_t pid; uint64_t respawns; time_t born; @@ -335,6 +334,8 @@ struct uwsgi_daemon { int status; int registered; //int pipe[2]; + + struct uwsgi_daemon *next; }; struct uwsgi_queue_header { @@ -1158,6 +1159,9 @@ struct uwsgi_server { int build_mime_dict; char *mime_file; + struct uwsgi_daemon *daemons; + int daemons_cnt; + struct uwsgi_dyn_dict *static_maps; struct uwsgi_dyn_dict *check_static; struct uwsgi_dyn_dict *mimetypes; @@ -1509,11 +1513,6 @@ struct uwsgi_server { void *spooler_lock; #endif - void *daemon_table_lock; - - char *startup_daemons[MAX_DAEMONS]; - int startup_daemons_cnt; - // subscription client int subscribe_freq; int subscription_tolerance; @@ -1663,8 +1662,6 @@ struct uwsgi_shared { int worker_log_pipe[2]; - struct uwsgi_daemon daemons[MAX_DAEMONS]; - int daemons_cnt; #ifdef __linux__ struct tcp_info ti; #endif @@ -2102,7 +2099,6 @@ ssize_t fcgi_send_record(int, uint8_t, uint16_t, char *); ssize_t fcgi_send_param(int, char *, uint16_t, char *, uint16_t); uint16_t fcgi_get_record(int, char *); -int uwsgi_attach_daemon(char *); void spawn_daemon(struct uwsgi_daemon *); void emperor_loop(void); @@ -2475,6 +2471,8 @@ void uwsgi_send_subscription(char *, char *, size_t , char *, size_t, uint8_t); void uwsgi_subscribe(char *, uint8_t); +struct uwsgi_daemon *uwsgi_daemon_new(struct uwsgi_daemon **, char *); + #ifdef __linux__ #ifdef MADV_MERGEABLE void uwsgi_linux_ksm_map(void);