Merge branch 'master' of github.com:unbit/uwsgi

This commit is contained in:
Unbit
2013-03-19 15:18:33 +01:00
6 changed files with 214 additions and 109 deletions
+127 -50
View File
@@ -175,7 +175,7 @@ void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *ues) {
}
}
else {
emperor_add(ues, de->d_name, st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
emperor_add(ues, de->d_name, st.st_mtime, NULL, 0, st.st_uid, st.st_gid, NULL);
}
}
closedir(dir);
@@ -250,7 +250,7 @@ void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *ues) {
}
}
else {
emperor_add(ues, g.gl_pathv[i], st.st_mtime, NULL, 0, st.st_uid, st.st_gid);
emperor_add(ues, g.gl_pathv[i], st.st_mtime, NULL, 0, st.st_uid, st.st_gid, NULL);
}
}
@@ -377,6 +377,22 @@ struct uwsgi_instance *emperor_get_by_fd(int fd) {
return NULL;
}
struct uwsgi_instance *emperor_get_by_socket_fd(int fd) {
struct uwsgi_instance *c_ui = ui;
while (c_ui->ui_next) {
c_ui = c_ui->ui_next;
// over engineering...
if (c_ui->on_demand_fd != -1 && c_ui->on_demand_fd == fd) {
return c_ui;
}
}
return NULL;
}
struct uwsgi_instance *emperor_get(char *name) {
@@ -478,17 +494,10 @@ void emperor_respawn(struct uwsgi_instance *c_ui, time_t mod) {
uwsgi_log("[emperor] reload the uwsgi instance %s\n", c_ui->name);
}
void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid) {
void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, char *config, uint32_t config_size, uid_t uid, gid_t gid, char *socket_name) {
struct uwsgi_instance *c_ui = ui;
struct uwsgi_instance *n_ui = NULL;
pid_t pid;
char **vassal_argv;
char *uef;
char **uenvs;
int counter;
char *colon = NULL;
int i;
struct timeval tv;
#ifdef UWSGI_DEBUG
@@ -544,8 +553,7 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
c_ui = c_ui->ui_next;
}
n_ui = uwsgi_malloc(sizeof(struct uwsgi_instance));
memset(n_ui, 0, sizeof(struct uwsgi_instance));
n_ui = uwsgi_calloc(sizeof(struct uwsgi_instance));
if (config) {
n_ui->use_config = 1;
@@ -576,10 +584,56 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
n_ui->first_run = uwsgi_now();
n_ui->last_run = n_ui->first_run;
n_ui->on_demand_fd = -1;
n_ui->pid = -1;
// ok here we check if we need to bind to the specified socket or continue with the activation
if (socket_name) {
char *tcp_port = strchr(socket_name, ':');
if (tcp_port) {
// disable deferred accept for this socket
int current_defer_accept = uwsgi.no_defer_accept;
uwsgi.no_defer_accept = 1;
n_ui->on_demand_fd = bind_to_tcp(socket_name, uwsgi.listen_queue, tcp_port);
uwsgi.no_defer_accept = current_defer_accept;
}
else {
n_ui->on_demand_fd = bind_to_unix(socket_name, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
}
if (n_ui->on_demand_fd < 0) {
uwsgi_error("emperor_add()/bind()");
free(n_ui);
c_ui->ui_next = NULL;
}
event_queue_add_fd_read(uwsgi.emperor_queue, n_ui->on_demand_fd);
uwsgi_log("[uwsgi-emperor] %s -> \"on demand\" instance detected, waiting for connections on socket \"%s\"...\n", name, socket_name);
return;
}
if (uwsgi_emperor_vassal_start(n_ui)) {
// clear the vassal
free(n_ui);
c_ui->ui_next = NULL;
}
}
int uwsgi_emperor_vassal_start(struct uwsgi_instance *n_ui) {
int i;
char *colon = NULL;
int counter;
char **uenvs;
char *uef;
char **vassal_argv;
pid_t pid;
if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe)) {
uwsgi_error("socketpair()");
goto clear;
return -1;
}
event_queue_add_fd_read(uwsgi.emperor_queue, n_ui->pipe[0]);
@@ -587,7 +641,7 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
if (n_ui->use_config) {
if (socketpair(AF_UNIX, SOCK_STREAM, 0, n_ui->pipe_config)) {
uwsgi_error("socketpair()");
goto clear;
return -1;
}
}
@@ -606,6 +660,11 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
n_ui->pid = pid;
// close the right side of the pipe
close(n_ui->pipe[1]);
// close the "on demand" socket
if (n_ui->on_demand_fd > -1) {
close(n_ui->on_demand_fd);
n_ui->on_demand_fd = -1;
}
if (n_ui->use_config) {
close(n_ui->pipe_config[1]);
}
@@ -625,13 +684,13 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
}
}
return;
return 0;
}
else {
if (uwsgi.emperor_tyrant) {
uwsgi_log("[emperor-tyrant] dropping privileges to %d %d for instance %s\n", (int) uid, (int) gid, name);
if (setgid(gid)) {
uwsgi_log("[emperor-tyrant] dropping privileges to %d %d for instance %s\n", (int) n_ui->uid, (int) n_ui->gid, n_ui->name);
if (setgid(n_ui->gid)) {
uwsgi_error("setgid()");
exit(1);
}
@@ -640,7 +699,7 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
exit(1);
}
if (setuid(uid)) {
if (setuid(n_ui->uid)) {
uwsgi_error("setuid()");
exit(1);
}
@@ -720,7 +779,7 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
vassal_argv[0] = uwsgi.binary_path;
if (uwsgi.emperor_broodlord) {
colon = strchr(name, ':');
colon = strchr(n_ui->name, ':');
if (colon) {
colon[0] = 0;
}
@@ -728,17 +787,17 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
// initialize to a default value
vassal_argv[1] = "--inherit";
if (!strcmp(name + (strlen(name) - 4), ".xml"))
if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".xml"))
vassal_argv[1] = "--xml";
if (!strcmp(name + (strlen(name) - 4), ".ini"))
if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".ini"))
vassal_argv[1] = "--ini";
if (!strcmp(name + (strlen(name) - 4), ".yml"))
if (!strcmp(n_ui->name + (strlen(n_ui->name) - 4), ".yml"))
vassal_argv[1] = "--yaml";
if (!strcmp(name + (strlen(name) - 5), ".yaml"))
if (!strcmp(n_ui->name + (strlen(n_ui->name) - 5), ".yaml"))
vassal_argv[1] = "--yaml";
if (!strcmp(name + (strlen(name) - 3), ".js"))
if (!strcmp(n_ui->name + (strlen(n_ui->name) - 3), ".js"))
vassal_argv[1] = "--json";
if (!strcmp(name + (strlen(name) - 5), ".json"))
if (!strcmp(n_ui->name + (strlen(n_ui->name) - 5), ".json"))
vassal_argv[1] = "--json";
if (colon) {
@@ -746,16 +805,16 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
}
vassal_argv[2] = name;
vassal_argv[2] = n_ui->name;
if (uwsgi.emperor_magic_exec) {
if (!access(name, R_OK | X_OK)) {
vassal_argv[2] = uwsgi_concat2("exec://", name);
if (!access(n_ui->name, R_OK | X_OK)) {
vassal_argv[2] = uwsgi_concat2("exec://", n_ui->name);
}
}
if (n_ui->use_config) {
vassal_argv[2] = uwsgi_concat2("emperor://", name);
vassal_argv[2] = uwsgi_concat2("emperor://", n_ui->name);
}
counter = 3;
@@ -768,18 +827,29 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
}
vassal_argv[counter] = NULL;
// disable stdin
int stdin_fd = open("/dev/null", O_RDONLY);
if (stdin_fd < 0) {
uwsgi_error_open("/dev/null");
exit(1);
// disable stdin OR map it to the "on demand" socket
if (n_ui->on_demand_fd > -1) {
if (n_ui->on_demand_fd != 0) {
if (dup2(n_ui->on_demand_fd, 0) < 0) {
uwsgi_error("dup2()");
exit(1);
}
close(n_ui->on_demand_fd);
}
}
if (stdin_fd != 0) {
if (dup2(stdin_fd, 0) < 0) {
uwsgi_error("dup2()");
else {
int stdin_fd = open("/dev/null", O_RDONLY);
if (stdin_fd < 0) {
uwsgi_error_open("/dev/null");
exit(1);
}
close(stdin_fd);
if (stdin_fd != 0) {
if (dup2(stdin_fd, 0) < 0) {
uwsgi_error("dup2()");
exit(1);
}
close(stdin_fd);
}
}
// close all of the unneded fd
@@ -813,11 +883,7 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
exit(UWSGI_EXILE_CODE);
}
clear:
free(n_ui);
c_ui->ui_next = NULL;
return -1;
}
void uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner *ues) {
@@ -1087,14 +1153,23 @@ void emperor_loop() {
else if (byte == 30 && uwsgi.emperor_broodlord > 0 && uwsgi.emperor_broodlord_count < uwsgi.emperor_broodlord) {
uwsgi_log("[emperor] going in broodlord mode: launching zergs for %s\n", ui_current->name);
char *zerg_name = uwsgi_concat3(ui_current->name, ":", "zerg");
emperor_add(ui_current->scanner, zerg_name, uwsgi_now(), NULL, 0, ui_current->uid, ui_current->gid);
emperor_add(ui_current->scanner, zerg_name, uwsgi_now(), NULL, 0, ui_current->uid, ui_current->gid, NULL);
free(zerg_name);
}
}
}
else {
uwsgi_log("[emperor] unrecognized vassal event on fd %d\n", interesting_fd);
close(interesting_fd);
ui_current = emperor_get_by_socket_fd(interesting_fd);
if (ui_current) {
event_queue_del_fd(uwsgi.emperor_queue, ui_current->on_demand_fd, event_queue_read());
if (uwsgi_emperor_vassal_start(ui_current)) {
emperor_del(ui_current);
}
}
else {
uwsgi_log("[emperor] unrecognized vassal event on fd %d\n", interesting_fd);
close(interesting_fd);
}
}
}
@@ -1120,7 +1195,9 @@ void emperor_loop() {
has_children = 0;
while (ui_current->ui_next) {
ui_current = ui_current->ui_next;
has_children++;
if (ui_current->pid > -1) {
has_children++;
}
}
if (uwsgi.notify) {
@@ -1172,7 +1249,7 @@ void emperor_loop() {
}
else {
// UNSAFE
emperor_add(ui_current->scanner, ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len, ui_current->uid, ui_current->gid);
emperor_add(ui_current->scanner, ui_current->name, ui_current->last_mod, ui_current->config, ui_current->config_len, ui_current->uid, ui_current->gid, NULL);
emperor_del(ui_current);
}
break;
@@ -1436,7 +1513,7 @@ void uwsgi_check_emperor() {
}
void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *ues, char *name, char *config, time_t ts, uid_t uid, gid_t gid) {
void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *ues, char *name, char *config, time_t ts, uid_t uid, gid_t gid, char *socket_name) {
if (!uwsgi_emperor_is_valid(name))
return;
@@ -1473,6 +1550,6 @@ void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *ues, char *name, char
new_config = uwsgi_str(config);
new_config_len = strlen(new_config);
}
emperor_add(ues, name, ts, new_config, new_config_len, uid, gid);
emperor_add(ues, name, ts, new_config, new_config_len, uid, gid, socket_name);
}
}
+2 -2
View File
@@ -49,7 +49,7 @@ void uwsgi_imperial_monitor_amqp_event(struct uwsgi_emperor_scanner *ues) {
}
if (msgsize > 0) {
emperor_add(ues, amqp_routing_key, uwsgi_now(), config, msgsize, 0, 0);
emperor_add(ues, amqp_routing_key, uwsgi_now(), config, msgsize, 0, 0, NULL);
}
end0:
@@ -88,7 +88,7 @@ end0:
emperor_respawn(ui_current, uwsgi_now());
}
else {
emperor_add(ues, config_file, uwsgi_now(), NULL, 0, 0, 0);
emperor_add(ues, config_file, uwsgi_now(), NULL, 0, 0, 0, NULL);
}
free(config_file);
+3 -1
View File
@@ -60,7 +60,9 @@ extern "C" void uwsgi_imperial_monitor_mongodb(struct uwsgi_emperor_scanner *ues
vassal_gid = tmp_gid;
}
uwsgi_emperor_simple_do(ues, (char *) name, (char *) config, vassal_ts/1000, vassal_uid, vassal_gid);
const char *socket_name = p.getStringField("socket");
uwsgi_emperor_simple_do(ues, (char *) name, (char *) config, vassal_ts/1000, vassal_uid, vassal_gid, (char *) socket_name);
}
+5 -1
View File
@@ -68,7 +68,11 @@ void uwsgi_imperial_monitor_pg(struct uwsgi_emperor_scanner *ues) {
vassal_uid = uwsgi_str_num(q_uid, strlen(q_uid));
vassal_gid = uwsgi_str_num(q_gid, strlen(q_gid));
}
uwsgi_emperor_simple_do(ues, name, config, uwsgi_str_num(ts, len), vassal_uid, vassal_gid);
char *socket_name = NULL;
if (PQnfields(res) > 5) {
socket_name = PQgetvalue(res, i, 5);
}
uwsgi_emperor_simple_do(ues, name, config, uwsgi_str_num(ts, len), vassal_uid, vassal_gid, socket_name);
}
}
+23 -4
View File
@@ -64,15 +64,16 @@ static void uwsgi_imperial_monitor_zeromq_cmd(struct uwsgi_emperor_scanner *ues)
int64_t more = 0;
size_t more_size = sizeof(more);
int i;
zmq_msg_t msg[5];
zmq_msg_t msg[6];
zmq_msg_init(&msg[0]);
zmq_msg_init(&msg[1]);
zmq_msg_init(&msg[2]);
zmq_msg_init(&msg[3]);
zmq_msg_init(&msg[4]);
zmq_msg_init(&msg[5]);
for(i=0;i<5;i++) {
for(i=0;i<6;i++) {
#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3,0,0)
zmq_recvmsg(ues->data, &msg[i], ZMQ_DONTWAIT);
#else
@@ -105,6 +106,11 @@ static void uwsgi_imperial_monitor_zeromq_cmd(struct uwsgi_emperor_scanner *ues)
char *ez_gid = NULL;
size_t ez_gid_len = 0;
char *ez_socket_name = NULL;
size_t ez_socket_name_len = 0;
char *socket_name = NULL;
// config
if (i > 1) {
ez_config = zmq_msg_data(&msg[2]);
@@ -123,6 +129,12 @@ static void uwsgi_imperial_monitor_zeromq_cmd(struct uwsgi_emperor_scanner *ues)
ez_gid_len = zmq_msg_size(&msg[4]);
}
// gid
if (i > 4) {
ez_socket_name = zmq_msg_data(&msg[5]);
ez_socket_name_len = zmq_msg_size(&msg[5]);
}
char *name = uwsgi_concat2n(ez_name, ez_name_len, "", 0);
// ok let's start checking commands
@@ -142,10 +154,16 @@ static void uwsgi_imperial_monitor_zeromq_cmd(struct uwsgi_emperor_scanner *ues)
vassal_gid = uwsgi_str_num(ez_gid, ez_gid_len);
}
uwsgi_emperor_simple_do(ues, name, config, uwsgi_now(), vassal_uid, vassal_gid);
if (ez_socket_name) {
socket_name = uwsgi_concat2n(ez_socket_name, ez_socket_name_len, "", 0);
}
uwsgi_emperor_simple_do(ues, name, config, uwsgi_now(), vassal_uid, vassal_gid, socket_name);
if (config) {
free(config);
}
if (socket_name) {
free(socket_name);
}
}
// destroy an instance
else if (!uwsgi_strncmp(ez_cmd, ez_cmd_len, "destroy", 6)) {
@@ -158,7 +176,7 @@ static void uwsgi_imperial_monitor_zeromq_cmd(struct uwsgi_emperor_scanner *ues)
}
}
else {
uwsgi_log("[emperor-zeromq] unkonwn command \"%.*s\"\n", (int)ez_cmd_len, ez_cmd);
uwsgi_log("[emperor-zeromq] unknown command \"%.*s\"\n", (int)ez_cmd_len, ez_cmd);
}
free(name);
@@ -168,6 +186,7 @@ static void uwsgi_imperial_monitor_zeromq_cmd(struct uwsgi_emperor_scanner *ues)
zmq_msg_close(&msg[2]);
zmq_msg_close(&msg[3]);
zmq_msg_close(&msg[4]);
zmq_msg_close(&msg[5]);
}
// this is the event manager
+54 -51
View File
@@ -3517,79 +3517,81 @@ struct uwsgi_stats_pusher * uwsgi_register_stats_pusher(char *, void (*)(struct
// an instance (called vassal) is a uWSGI stack running
// it is identified by the name of its config file
// a vassal is 'loyal' as soon as it manages a request
struct uwsgi_instance {
struct uwsgi_instance *ui_prev;
struct uwsgi_instance *ui_next;
struct uwsgi_instance {
struct uwsgi_instance *ui_prev;
struct uwsgi_instance *ui_next;
char name[0xff];
pid_t pid;
char name[0xff];
pid_t pid;
int status;
time_t born;
time_t last_mod;
time_t last_loyal;
int status;
time_t born;
time_t last_mod;
time_t last_loyal;
time_t last_run;
time_t first_run;
time_t last_run;
time_t first_run;
time_t last_heartbeat;
time_t last_heartbeat;
uint64_t respawns;
int use_config;
uint64_t respawns;
int use_config;
int pipe[2];
int pipe_config[2];
int pipe[2];
int pipe_config[2];
char *config;
uint32_t config_len;
char *config;
uint32_t config_len;
int loyal;
int loyal;
int zerg;
int zerg;
struct uwsgi_emperor_scanner *scanner;
struct uwsgi_emperor_scanner *scanner;
uid_t uid;
gid_t gid;
};
uid_t uid;
gid_t gid;
struct uwsgi_instance *emperor_get_by_fd(int);
struct uwsgi_instance *emperor_get(char *);
void emperor_stop(struct uwsgi_instance *);
void emperor_respawn(struct uwsgi_instance *, time_t);
void emperor_add(struct uwsgi_emperor_scanner *, char *, time_t, char *, uint32_t, uid_t, gid_t);
int on_demand_fd;
};
void uwsgi_exec_command_with_args(char *);
struct uwsgi_instance *emperor_get_by_fd(int);
struct uwsgi_instance *emperor_get(char *);
void emperor_stop(struct uwsgi_instance *);
void emperor_respawn(struct uwsgi_instance *, time_t);
void emperor_add(struct uwsgi_emperor_scanner *, char *, time_t, char *, uint32_t, uid_t, gid_t, char *);
void uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner *);
void uwsgi_imperial_monitor_directory_init(struct uwsgi_emperor_scanner *);
void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *);
void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *);
void uwsgi_exec_command_with_args(char *);
void uwsgi_register_clock(struct uwsgi_clock *);
void uwsgi_set_clock(char *name);
void uwsgi_imperial_monitor_glob_init(struct uwsgi_emperor_scanner *);
void uwsgi_imperial_monitor_directory_init(struct uwsgi_emperor_scanner *);
void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *);
void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *);
void uwsgi_init_default(void);
void uwsgi_setup_reload(void);
void uwsgi_autoload_plugins_by_name(char *);
void uwsgi_commandline_config(void);
void uwsgi_register_clock(struct uwsgi_clock *);
void uwsgi_set_clock(char *name);
void uwsgi_setup_log(void);
void uwsgi_setup_log_master(void);
void uwsgi_init_default(void);
void uwsgi_setup_reload(void);
void uwsgi_autoload_plugins_by_name(char *);
void uwsgi_commandline_config(void);
void uwsgi_setup_shared_sockets(void);
void uwsgi_setup_log(void);
void uwsgi_setup_log_master(void);
void uwsgi_setup_mules_and_farms(void);
void uwsgi_setup_shared_sockets(void);
void uwsgi_setup_workers(void);
void uwsgi_map_sockets(void);
void uwsgi_setup_mules_and_farms(void);
void uwsgi_set_cpu_affinity(void);
void uwsgi_setup_workers(void);
void uwsgi_map_sockets(void);
void uwsgi_emperor_start(void);
void uwsgi_set_cpu_affinity(void);
void uwsgi_bind_sockets(void);
void uwsgi_set_sockets_protocols(void);
void uwsgi_emperor_start(void);
void uwsgi_bind_sockets(void);
void uwsgi_set_sockets_protocols(void);
struct uwsgi_buffer *uwsgi_buffer_new(size_t);
int uwsgi_buffer_append(struct uwsgi_buffer *, char *, size_t);
@@ -3631,7 +3633,7 @@ void uwsgi_master_cleanup_hooks(void);
pid_t uwsgi_daemonize2();
void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *, char *, char *, time_t, uid_t, gid_t);
void uwsgi_emperor_simple_do(struct uwsgi_emperor_scanner *, char *, char *, time_t, uid_t, gid_t, char *);
#if defined(__linux__)
#define UWSGI_ELF
@@ -3928,6 +3930,7 @@ int uwsgi_cache_magic_clear(char *);
void uwsgi_cache_magic_context_hook(char *, uint16_t, char *, uint16_t, void *);
char *uwsgi_legion_scrolls(char *, uint64_t *);
int uwsgi_emperor_vassal_start(struct uwsgi_instance *);
#ifdef UWSGI_ZLIB
#include <zlib.h>