From cd2ff0e585134c2d9475a2bcb667f6cbdee3bb88 Mon Sep 17 00:00:00 2001 From: Unbit Date: Thu, 26 Sep 2013 07:51:13 +0200 Subject: [PATCH] emperor proxy --- core/emperor.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ core/init.c | 1 + core/master.c | 45 +++++++---------------- core/master_events.c | 5 +++ core/uwsgi.c | 4 ++- uwsgi.h | 4 +++ 6 files changed, 111 insertions(+), 34 deletions(-) diff --git a/core/emperor.c b/core/emperor.c index af537246..ac27e61e 100644 --- a/core/emperor.c +++ b/core/emperor.c @@ -1958,3 +1958,89 @@ void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *ues, char *name, char emperor_add(ues, name, ts, new_config, new_config_len, uid, gid, socket_name); } } + +void uwsgi_master_manage_emperor() { + char byte; + ssize_t rlen = read(uwsgi.emperor_fd, &byte, 1); + if (rlen > 0) { + uwsgi_log_verbose("received message %d from emperor\n", byte); + // remove me + if (byte == 0) { + close(uwsgi.emperor_fd); + if (!uwsgi.status.brutally_reloading) + kill_them_all(0); + } + // reload me + else if (byte == 1) { + // un-lazy the stack to trigger a real reload + uwsgi.lazy = 0; + uwsgi_block_signal(SIGHUP); + grace_them_all(0); + uwsgi_unblock_signal(SIGHUP); + } + } + else { + uwsgi_log("lost connection with my emperor !!!\n"); + close(uwsgi.emperor_fd); + if (!uwsgi.status.brutally_reloading) + kill_them_all(0); + sleep(2); + exit(1); + } + +} + +void uwsgi_master_manage_emperor_proxy() { + + struct sockaddr_un epsun; + socklen_t epsun_len = sizeof(struct sockaddr_un); + + int ep_client = accept(uwsgi.emperor_fd_proxy, (struct sockaddr *) &epsun, &epsun_len); + if (ep_client < 0) { + uwsgi_error("uwsgi_master_manage_emperor_proxy()/accept()"); + return; + } + + int num_fds = 1; + if (uwsgi.emperor_fd_config > -1) num_fds++; + + struct msghdr ep_msg; + void *ep_msg_control = uwsgi_malloc(CMSG_SPACE(sizeof(int) * num_fds)); + struct iovec ep_iov[2]; + struct cmsghdr *cmsg; + + ep_iov[0].iov_base = "uwsgi-emperor"; + ep_iov[0].iov_len = 13; + ep_iov[1].iov_base = &num_fds; + ep_iov[1].iov_len = sizeof(int); + + ep_msg.msg_name = NULL; + ep_msg.msg_namelen = 0; + + ep_msg.msg_iov = ep_iov; + ep_msg.msg_iovlen = 2; + + ep_msg.msg_flags = 0; + ep_msg.msg_control = ep_msg_control; + ep_msg.msg_controllen = CMSG_SPACE(sizeof(int) * num_fds); + + cmsg = CMSG_FIRSTHDR(&ep_msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + + unsigned char *ep_fd_ptr = CMSG_DATA(cmsg); + + memcpy(ep_fd_ptr, &uwsgi.emperor_fd, sizeof(int)); + if (num_fds > 1) { + memcpy(ep_fd_ptr + sizeof(int), &uwsgi.emperor_fd_config, sizeof(int)); + } + + if (sendmsg(ep_client, &ep_msg, 0) < 0) { + uwsgi_error("uwsgi_master_manage_emperor_proxy()/sendmsg()"); + } + + free(ep_msg_control); + + close(ep_client); +} diff --git a/core/init.c b/core/init.c index 935fec93..d2a34ff7 100644 --- a/core/init.c +++ b/core/init.c @@ -75,6 +75,7 @@ void uwsgi_init_default() { uwsgi.original_log_fd = -1; uwsgi.emperor_fd_config = -1; + uwsgi.emperor_fd_proxy = -1; // default emperor scan frequency uwsgi.emperor_freq = 3; uwsgi.emperor_throttle = 1000; diff --git a/core/master.c b/core/master.c index d6c61bcf..6b001643 100644 --- a/core/master.c +++ b/core/master.c @@ -77,38 +77,6 @@ void uwsgi_master_manage_udp(int udp_fd) { } } -void uwsgi_master_manage_emperor() { - char byte; - ssize_t rlen = read(uwsgi.emperor_fd, &byte, 1); - if (rlen > 0) { - uwsgi_log_verbose("received message %d from emperor\n", byte); - // remove me - if (byte == 0) { - close(uwsgi.emperor_fd); - if (!uwsgi.status.brutally_reloading) - kill_them_all(0); - } - // reload me - else if (byte == 1) { - // un-lazy the stack to trigger a real reload - uwsgi.lazy = 0; - uwsgi_block_signal(SIGHUP); - grace_them_all(0); - uwsgi_unblock_signal(SIGHUP); - } - } - else { - uwsgi_log("lost connection with my emperor !!!\n"); - close(uwsgi.emperor_fd); - if (!uwsgi.status.brutally_reloading) - kill_them_all(0); - sleep(2); - exit(1); - } - -} - - void uwsgi_master_restore_snapshot() { int i, waitpid_status; uwsgi_log("[snapshot] restoring workers...\n"); @@ -387,7 +355,18 @@ int master_loop(char **argv, char **environ) { uwsgi.wsgi_req->buffer = uwsgi.workers[0].cores[0].buffer; if (uwsgi.has_emperor) { - event_queue_add_fd_read(uwsgi.master_queue, uwsgi.emperor_fd); + if (uwsgi.emperor_proxy) { + uwsgi.emperor_fd_proxy = bind_to_unix(uwsgi.emperor_proxy, uwsgi.listen_queue, 0, 0); + if (uwsgi.emperor_fd_proxy < 0) exit(1); + if (chmod(uwsgi.emperor_proxy, S_IRUSR|S_IWUSR)) { + uwsgi_error("[emperor-proxy] chmod()"); + exit(1); + } + event_queue_add_fd_read(uwsgi.master_queue, uwsgi.emperor_fd_proxy); + } + else { + event_queue_add_fd_read(uwsgi.master_queue, uwsgi.emperor_fd); + } } if (uwsgi.zerg_server) { diff --git a/core/master_events.c b/core/master_events.c index e4b78e8e..79cb1901 100644 --- a/core/master_events.c +++ b/core/master_events.c @@ -40,6 +40,11 @@ int uwsgi_master_manage_events(int interesting_fd) { // emperor event ? if (uwsgi.has_emperor) { + if (uwsgi.emperor_fd_proxy > -1 && interesting_fd == uwsgi.emperor_fd_proxy) { + uwsgi_master_manage_emperor_proxy(); + return 0; + } + if (interesting_fd == uwsgi.emperor_fd) { uwsgi_master_manage_emperor(); return 0; diff --git a/core/uwsgi.c b/core/uwsgi.c index 506f0268..d56b018c 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -173,6 +173,7 @@ static struct uwsgi_option uwsgi_base_options[] = { {"master", no_argument, 'M', "enable master process", uwsgi_opt_true, &uwsgi.master_process, 0}, {"honour-stdin", no_argument, 0, "do not remap stdin to /dev/null", uwsgi_opt_true, &uwsgi.honour_stdin, 0}, {"emperor", required_argument, 0, "run the Emperor", uwsgi_opt_add_string_list, &uwsgi.emperor, 0}, + {"emperor-proxy-socket", required_argument, 0, "force the vassal to became an Emperor proxy", uwsgi_opt_set_str, &uwsgi.emperor_proxy, 0}, {"emperor-wrapper", required_argument, 0, "set a binary wrapper for vassals", uwsgi_opt_set_str, &uwsgi.emperor_wrapper, 0}, {"emperor-nofollow", no_argument, 0, "do not follow symlinks when checking for mtime", uwsgi_opt_true, &uwsgi.emperor_nofollow, 0}, {"emperor-procname", required_argument, 0, "set the Emperor process name", uwsgi_opt_set_str, &uwsgi.emperor_procname, 0}, @@ -2765,7 +2766,8 @@ int uwsgi_start(void *v_argv) { !uwsgi.emperor && !uwsgi.command_mode && !uwsgi.daemons_cnt && - !uwsgi.crons + !uwsgi.crons && + !uwsgi.emperor_proxy #ifdef UWSGI_SSL && !uwsgi.legions #endif diff --git a/uwsgi.h b/uwsgi.h index 44251a22..628b001c 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1758,7 +1758,9 @@ struct uwsgi_server { // true if run under the emperor int has_emperor; char *emperor_procname; + char *emperor_proxy; int emperor_fd; + int emperor_fd_proxy; int emperor_queue; int emperor_nofollow; int emperor_tyrant; @@ -4352,6 +4354,8 @@ void uwsgi_go_cheap(); char **uwsgi_split_quoted(char *, size_t, char *, size_t *); +void uwsgi_master_manage_emperor_proxy(); + #ifdef __cplusplus } #endif