From 4badecdbbc13b92e357de8f899db54ca3d26e3fc Mon Sep 17 00:00:00 2001 From: "roberto@goyle" Date: Fri, 18 Feb 2011 16:11:24 +0100 Subject: [PATCH] --attach-daemon option --- master.c | 16 +++++++++++++++- utils.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- uwsgi.c | 30 ++++++++++++++++++++++++++++++ uwsgi.h | 5 +++++ 4 files changed, 99 insertions(+), 4 deletions(-) diff --git a/master.c b/master.c index cec2b9b0..bf2d5faf 100644 --- a/master.c +++ b/master.c @@ -346,7 +346,7 @@ void master_loop(char **argv, char **environ) { // locking is not needed as daemons can only increase (for now) for(i=0;idaemons_cnt;i++) { if (!ushared->daemons[i].registered) { - uwsgi_log("running daemon %s\n", ushared->daemons[i].command); + uwsgi_log("spawning daemon %s\n", ushared->daemons[i].command); spawn_daemon(&ushared->daemons[i]); ushared->daemons[i].registered = 1; } @@ -695,6 +695,20 @@ void master_loop(char **argv, char **environ) { } if (pid_found) continue; + + /* 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]); + pid_found = 1; + break; + } + } + + if (pid_found) continue; + #ifdef UWSGI_PROXY if (uwsgi.proxy_socket_name && uwsgi.shared->proxy_pid > 0) { if (diedpid == uwsgi.shared->proxy_pid) { diff --git a/utils.c b/utils.c index 615e740c..d5af0614 100644 --- a/utils.c +++ b/utils.c @@ -1532,7 +1532,16 @@ int uwsgi_attach_daemon(char *command) { void spawn_daemon(struct uwsgi_daemon *ud) { - char *argv[2]; + int i; + char *argv[64]; + char *a; + int cnt = 1; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, ud->pipe)) { + uwsgi_error("socketpair()"); + return; + } + pid_t pid = fork(); if (pid < 0) { uwsgi_error("fork()"); @@ -1540,6 +1549,7 @@ void spawn_daemon(struct uwsgi_daemon *ud) { } if (pid > 0) { + close(ud->pipe[1]); ud->pid = pid; ud->status = 1; if (ud->respawns == 0) { @@ -1551,8 +1561,44 @@ void spawn_daemon(struct uwsgi_daemon *ud) { } else { - argv[0] = ud->command; - argv[1] = NULL; + + // close uwsgi sockets + for(i=0;ipipe[0]); + + // stdin will become the pipe + if (ud->pipe[1] != 0) { + if (dup2(ud->pipe[1], 0)) { + uwsgi_error("dup2()"); + exit(1); + } + } + +#ifdef __linux__ + if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0,0,0)) { + uwsgi_error("prctl()"); + } +#endif + memcpy(ud->tmp_command, ud->command, 0xff); + + a = strtok(ud->tmp_command, " "); + if (a) { + argv[0] = a; + while (a != NULL) { + a = strtok(NULL, " "); + if (a) { + argv[cnt] = a; + cnt++; + } + } + } + else { + argv[0] = ud->tmp_command; + } + + argv[cnt] = NULL; if (execvp(argv[0], argv)) { uwsgi_error("execvp()"); diff --git a/uwsgi.c b/uwsgi.c index abb49107..10d9235a 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -151,6 +151,7 @@ static struct option long_base_options[] = { #endif {"loop", required_argument, 0, LONG_ARGS_LOOP}, {"worker-exec", required_argument, 0, LONG_ARGS_WORKER_EXEC}, + {"attach-daemon", required_argument, 0, LONG_ARGS_ATTACH_DAEMON}, {"plugins", required_argument, 0, LONG_ARGS_PLUGINS}, {"remap-modifier", required_argument, 0, LONG_ARGS_REMAP_MODIFIER}, {"dump-options", no_argument, &uwsgi.dump_options, 1}, @@ -220,6 +221,10 @@ void kill_them_all() for (i = 0; i <= uwsgi.gateways_cnt; i++) { kill(uwsgi.gateways[i].pid, SIGKILL); } + + for (i = 0; i <= uwsgi.shared->daemons_cnt; i++) { + kill(uwsgi.shared->daemons[i].pid, SIGKILL); + } } void grace_them_all() @@ -230,6 +235,10 @@ void grace_them_all() for (i = 1; i <= uwsgi.numproc; i++) { kill(uwsgi.workers[i].pid, SIGHUP); } + + for (i = 0; i <= uwsgi.shared->daemons_cnt; i++) { + kill(uwsgi.shared->daemons[i].pid, SIGKILL); + } } void reap_them_all() @@ -240,6 +249,10 @@ void reap_them_all() for (i = 1; i <= uwsgi.numproc; i++) { kill(uwsgi.workers[i].pid, SIGTERM); } + + for (i = 0; i <= uwsgi.shared->daemons_cnt; i++) { + kill(uwsgi.shared->daemons[i].pid, SIGKILL); + } } void harakiri() @@ -1148,6 +1161,15 @@ int uwsgi_start(void *v_argv) { uwsgi_log("*** Cache subsystem initialized: %dMB preallocated ***\n", ((sizeof(uint64_t) * UMAX16) + (sizeof(uint64_t) * uwsgi.cache_max_items) + (uwsgi.cache_blocksize * uwsgi.cache_max_items) + (sizeof(struct uwsgi_cache_item) * uwsgi.cache_max_items)) / (1024*1024)); } + // attach startup daemons + if (uwsgi.master_process) { + for(i=0;iinit) { @@ -1935,6 +1957,14 @@ end: uwsgi.check_static = optarg; uwsgi.check_static_len = strlen(uwsgi.check_static); return 1; + case LONG_ARGS_ATTACH_DAEMON: + if (uwsgi.startup_daemons_cnt < 63) { + 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); + } + return 1; #ifdef __linux__ case LONG_ARGS_CGROUP: uwsgi.cgroup = optarg; diff --git a/uwsgi.h b/uwsgi.h index dc290569..e915f424 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -224,12 +224,14 @@ struct uwsgi_gateway { struct uwsgi_daemon { char command[0xff]; + char tmp_command[0xff]; pid_t pid; uint64_t respawns; time_t born; time_t last_spawn; int status; int registered; + int pipe[2]; }; struct uwsgi_queue_item { @@ -340,6 +342,7 @@ struct uwsgi_opt { #define LONG_ARGS_CACHE_BLOCKSIZE 17074 #define LONG_ARGS_QUEUE 17075 #define LONG_ARGS_QUEUE_BLOCKSIZE 17076 +#define LONG_ARGS_ATTACH_DAEMON 17077 @@ -948,6 +951,8 @@ struct uwsgi_server { void *daemon_table_lock; + char *startup_daemons[MAX_DAEMONS]; + int startup_daemons_cnt; };