mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-06-16 02:15:48 +00:00
361 lines
9.8 KiB
C
361 lines
9.8 KiB
C
#include "uwsgi.h"
|
|
|
|
extern struct uwsgi_server uwsgi;
|
|
|
|
void uwsgi_init_default() {
|
|
|
|
uwsgi.cpus = 1;
|
|
|
|
uwsgi.backtrace_depth = 64;
|
|
uwsgi.max_apps = 64;
|
|
|
|
uwsgi.master_queue = -1;
|
|
|
|
uwsgi.signal_socket = -1;
|
|
uwsgi.my_signal_socket = -1;
|
|
uwsgi.cache_server_fd = -1;
|
|
uwsgi.cache_blocksize = UMAX16;
|
|
uwsgi.stats_fd = -1;
|
|
|
|
uwsgi.stats_pusher_default_freq = 3;
|
|
|
|
uwsgi.original_log_fd = -1;
|
|
|
|
uwsgi.emperor_fd_config = -1;
|
|
// default emperor scan frequency
|
|
uwsgi.emperor_freq = 3;
|
|
uwsgi.emperor_throttle = 1000;
|
|
uwsgi.emperor_heartbeat = 30;
|
|
// max 3 minutes throttling
|
|
uwsgi.emperor_max_throttle = 1000 * 180;
|
|
uwsgi.emperor_pid = -1;
|
|
|
|
uwsgi.subscribe_freq = 10;
|
|
uwsgi.subscription_tolerance = 17;
|
|
|
|
uwsgi.cluster_fd = -1;
|
|
uwsgi.cores = 1;
|
|
uwsgi.threads = 1;
|
|
|
|
uwsgi.offload_threads_events = 64;
|
|
|
|
uwsgi.default_app = -1;
|
|
|
|
uwsgi.buffer_size = 4096;
|
|
uwsgi.numproc = 1;
|
|
|
|
uwsgi.forkbomb_delay = 2;
|
|
|
|
uwsgi.async = 1;
|
|
uwsgi.listen_queue = 100;
|
|
|
|
uwsgi.cheaper_overload = 3;
|
|
|
|
uwsgi.log_master_bufsize = 8192;
|
|
|
|
uwsgi.max_vars = MAX_VARS;
|
|
uwsgi.vec_size = 4 + 1 + (4 * MAX_VARS);
|
|
|
|
uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] = 4;
|
|
uwsgi.shared->options[UWSGI_OPTION_LOGGING] = 1;
|
|
|
|
#ifdef UWSGI_SPOOLER
|
|
uwsgi.shared->spooler_frequency = 30;
|
|
|
|
uwsgi.shared->spooler_signal_pipe[0] = -1;
|
|
uwsgi.shared->spooler_signal_pipe[1] = -1;
|
|
#endif
|
|
uwsgi.shared->mule_signal_pipe[0] = -1;
|
|
uwsgi.shared->mule_signal_pipe[1] = -1;
|
|
|
|
uwsgi.shared->mule_queue_pipe[0] = -1;
|
|
uwsgi.shared->mule_queue_pipe[1] = -1;
|
|
|
|
uwsgi.shared->worker_log_pipe[0] = -1;
|
|
uwsgi.shared->worker_log_pipe[1] = -1;
|
|
|
|
#ifdef UWSGI_SSL
|
|
// 1 day of tolerance
|
|
uwsgi.subscriptions_sign_check_tolerance = 3600 * 24;
|
|
uwsgi.ssl_sessions_timeout = 300;
|
|
#endif
|
|
|
|
#ifdef UWSGI_ALARM
|
|
uwsgi.alarm_freq = 3;
|
|
#endif
|
|
|
|
|
|
#ifdef UWSGI_MULTICAST
|
|
uwsgi.multicast_ttl = 1;
|
|
uwsgi.multicast_loop = 1;
|
|
#endif
|
|
|
|
uwsgi.buffer_write_hook = uwsgi_buffer_write_simple;
|
|
uwsgi_websockets_init();
|
|
}
|
|
|
|
void uwsgi_setup_reload() {
|
|
|
|
char env_reload_buf[11];
|
|
|
|
char *env_reloads = getenv("UWSGI_RELOADS");
|
|
if (env_reloads) {
|
|
//convert env value to int
|
|
uwsgi.reloads = atoi(env_reloads);
|
|
uwsgi.reloads++;
|
|
//convert reloads to string
|
|
int rlen = snprintf(env_reload_buf, 10, "%u", uwsgi.reloads);
|
|
if (rlen > 0) {
|
|
env_reload_buf[rlen] = 0;
|
|
if (setenv("UWSGI_RELOADS", env_reload_buf, 1)) {
|
|
uwsgi_error("setenv()");
|
|
}
|
|
}
|
|
uwsgi.is_a_reload = 1;
|
|
}
|
|
else {
|
|
if (setenv("UWSGI_RELOADS", "0", 1)) {
|
|
uwsgi_error("setenv()");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void uwsgi_autoload_plugins_by_name(char *argv_zero) {
|
|
|
|
char *plugins_requested = NULL;
|
|
|
|
char *original_proc_name = getenv("UWSGI_ORIGINAL_PROC_NAME");
|
|
if (!original_proc_name) {
|
|
// here we use argv[0];
|
|
original_proc_name = argv_zero;
|
|
setenv("UWSGI_ORIGINAL_PROC_NAME", original_proc_name, 1);
|
|
}
|
|
char *p = strrchr(original_proc_name, '/');
|
|
if (p == NULL)
|
|
p = original_proc_name;
|
|
p = strstr(p, "uwsgi_");
|
|
if (p != NULL) {
|
|
plugins_requested = strtok(uwsgi_str(p + 6), "_");
|
|
while (plugins_requested) {
|
|
uwsgi_log("[uwsgi] implicit plugin requested %s\n", plugins_requested);
|
|
uwsgi_load_plugin(-1, plugins_requested, NULL);
|
|
plugins_requested = strtok(NULL, "_");
|
|
}
|
|
}
|
|
|
|
plugins_requested = getenv("UWSGI_PLUGINS");
|
|
if (plugins_requested) {
|
|
plugins_requested = uwsgi_concat2(plugins_requested, "");
|
|
char *p = strtok(plugins_requested, ",");
|
|
while (p != NULL) {
|
|
uwsgi_load_plugin(-1, p, NULL);
|
|
p = strtok(NULL, ",");
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void uwsgi_commandline_config() {
|
|
int i;
|
|
|
|
uwsgi.option_index = -1;
|
|
|
|
char *optname;
|
|
while ((i = getopt_long(uwsgi.argc, uwsgi.argv, uwsgi.short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
|
|
|
|
if (i == '?') {
|
|
uwsgi_log("getopt_long() error\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (uwsgi.option_index > -1) {
|
|
optname = (char *) uwsgi.long_options[uwsgi.option_index].name;
|
|
}
|
|
else {
|
|
optname = uwsgi_get_optname_by_index(i);
|
|
}
|
|
if (!optname) {
|
|
uwsgi_log("unable to parse command line options\n");
|
|
exit(1);
|
|
}
|
|
uwsgi.option_index = -1;
|
|
add_exported_option(optname, optarg, 0);
|
|
}
|
|
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_log("optind:%d argc:%d\n", optind, uwsgi.argc);
|
|
#endif
|
|
|
|
if (optind < uwsgi.argc) {
|
|
for (i = optind; i < uwsgi.argc; i++) {
|
|
char *lazy = uwsgi.argv[i];
|
|
if (lazy[0] != '[') {
|
|
uwsgi_opt_load(NULL, lazy, NULL);
|
|
// manage magic mountpoint
|
|
int magic = 0;
|
|
int j;
|
|
for (j = 0; j < uwsgi.gp_cnt; j++) {
|
|
if (uwsgi.gp[j]->magic) {
|
|
if (uwsgi.gp[j]->magic(NULL, lazy)) {
|
|
magic = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!magic) {
|
|
for (j = 0; j < 256; j++) {
|
|
if (uwsgi.p[j]->magic) {
|
|
if (uwsgi.p[j]->magic(NULL, lazy)) {
|
|
magic = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void uwsgi_setup_workers() {
|
|
int i, j;
|
|
// allocate shared memory for workers + master
|
|
uwsgi.workers = (struct uwsgi_worker *) uwsgi_calloc_shared(sizeof(struct uwsgi_worker) * (uwsgi.numproc + 1 + uwsgi.grunt));
|
|
|
|
for (i = 0; i <= uwsgi.numproc; i++) {
|
|
// allocate memory for apps
|
|
uwsgi.workers[i].apps = (struct uwsgi_app *) uwsgi_calloc_shared(sizeof(struct uwsgi_app) * uwsgi.max_apps);
|
|
|
|
// allocate memory for cores
|
|
uwsgi.workers[i].cores = (struct uwsgi_core *) uwsgi_calloc_shared(sizeof(struct uwsgi_core) * uwsgi.cores);
|
|
|
|
// this is a trick for avoiding too much memory areas
|
|
void *ts = uwsgi_calloc_shared(sizeof(void *) * uwsgi.max_apps * uwsgi.cores);
|
|
void *buffers = uwsgi_malloc_shared(uwsgi.buffer_size * uwsgi.cores);
|
|
void *hvec = uwsgi_malloc_shared(sizeof(struct iovec) * uwsgi.vec_size * uwsgi.cores);
|
|
void *post_buf = NULL;
|
|
if (uwsgi.post_buffering > 0)
|
|
post_buf = uwsgi_malloc_shared(uwsgi.post_buffering_bufsize * uwsgi.cores);
|
|
|
|
|
|
for (j = 0; j < uwsgi.cores; j++) {
|
|
// allocate shared memory for thread states (required for some language, like python)
|
|
uwsgi.workers[i].cores[j].ts = ts + ((sizeof(void *) * uwsgi.max_apps) * j);
|
|
// raw per-request buffer
|
|
uwsgi.workers[i].cores[j].buffer = buffers + (uwsgi.buffer_size * j);
|
|
// iovec for uwsgi vars
|
|
uwsgi.workers[i].cores[j].hvec = hvec + ((sizeof(struct iovec) * uwsgi.vec_size) * j);
|
|
if (post_buf)
|
|
uwsgi.workers[i].cores[j].post_buf = post_buf + (uwsgi.post_buffering_bufsize * j);
|
|
}
|
|
|
|
// master does not need to following steps...
|
|
if (i == 0)
|
|
continue;
|
|
uwsgi.workers[i].signal_pipe[0] = -1;
|
|
uwsgi.workers[i].signal_pipe[1] = -1;
|
|
snprintf(uwsgi.workers[i].name, 0xff, "uWSGI worker %d", i);
|
|
snprintf(uwsgi.workers[i].snapshot_name, 0xff, "uWSGI snapshot %d", i);
|
|
}
|
|
|
|
uint64_t total_memory = (sizeof(struct uwsgi_app) * uwsgi.max_apps) + (sizeof(struct uwsgi_core) * uwsgi.cores) + (sizeof(void *) * uwsgi.max_apps * uwsgi.cores) + (uwsgi.buffer_size * uwsgi.cores) + (sizeof(struct iovec) * uwsgi.vec_size * uwsgi.cores);
|
|
if (uwsgi.post_buffering > 0) {
|
|
total_memory += (uwsgi.post_buffering_bufsize * uwsgi.cores);
|
|
}
|
|
|
|
total_memory *= (uwsgi.numproc + uwsgi.master_process);
|
|
if (uwsgi.numproc > 0)
|
|
uwsgi_log("mapped %lu bytes (%lu KB) for %d cores\n", total_memory, total_memory / 1024, uwsgi.cores * uwsgi.numproc);
|
|
|
|
}
|
|
|
|
pid_t uwsgi_daemonize2() {
|
|
if (uwsgi.has_emperor) {
|
|
logto(uwsgi.daemonize2);
|
|
}
|
|
else {
|
|
if (!uwsgi.is_a_reload) {
|
|
uwsgi_log("*** daemonizing uWSGI ***\n");
|
|
daemonize(uwsgi.daemonize2);
|
|
}
|
|
else if (uwsgi.log_reopen) {
|
|
logto(uwsgi.daemonize2);
|
|
}
|
|
}
|
|
uwsgi.mypid = getpid();
|
|
|
|
uwsgi.workers[0].pid = uwsgi.mypid;
|
|
|
|
if (uwsgi.pidfile && !uwsgi.is_a_reload) {
|
|
uwsgi_write_pidfile(uwsgi.pidfile);
|
|
}
|
|
|
|
if (uwsgi.pidfile2 && !uwsgi.is_a_reload) {
|
|
uwsgi_write_pidfile(uwsgi.pidfile2);
|
|
}
|
|
|
|
return uwsgi.mypid;
|
|
}
|
|
|
|
// fix/check related options
|
|
void sanitize_args() {
|
|
|
|
if (uwsgi.async > 1) {
|
|
uwsgi.cores = uwsgi.async;
|
|
}
|
|
|
|
if (uwsgi.threads > 1) {
|
|
uwsgi.has_threads = 1;
|
|
uwsgi.cores = uwsgi.threads;
|
|
}
|
|
|
|
if (uwsgi.shared->options[UWSGI_OPTION_HARAKIRI] > 0) {
|
|
if (!uwsgi.post_buffering) {
|
|
uwsgi_log(" *** WARNING: you have enabled harakiri without post buffering. Slow upload could be rejected on post-unbuffered webservers *** \n");
|
|
}
|
|
}
|
|
|
|
if (uwsgi.write_errors_exception_only) {
|
|
uwsgi.ignore_sigpipe = 1;
|
|
uwsgi.ignore_write_errors = 1;
|
|
}
|
|
|
|
|
|
if (uwsgi.cheaper_count > 0 && uwsgi.cheaper_count >= uwsgi.numproc) {
|
|
uwsgi_log("invalid cheaper value: must be lower than processes\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (uwsgi.cheaper && uwsgi.cheaper_count) {
|
|
if (uwsgi.cheaper_initial) {
|
|
if (uwsgi.cheaper_initial < uwsgi.cheaper_count) {
|
|
uwsgi_log("warning: invalid cheaper-initial value (%d), must be equal or higher than cheaper (%d), using %d as initial number of workers\n",
|
|
uwsgi.cheaper_initial, uwsgi.cheaper_count, uwsgi.cheaper_count);
|
|
uwsgi.cheaper_initial = uwsgi.cheaper_count;
|
|
}
|
|
else if (uwsgi.cheaper_initial > uwsgi.numproc) {
|
|
uwsgi_log("warning: invalid cheaper-initial value (%d), must be lower or equal than worker count (%d), using %d as initial number of workers\n",
|
|
uwsgi.cheaper_initial, uwsgi.numproc, uwsgi.numproc);
|
|
uwsgi.cheaper_initial = uwsgi.numproc;
|
|
}
|
|
}
|
|
else {
|
|
uwsgi.cheaper_initial = uwsgi.cheaper_count;
|
|
}
|
|
}
|
|
|
|
if (uwsgi.auto_snapshot > 0 && uwsgi.auto_snapshot > uwsgi.numproc) {
|
|
uwsgi_log("invalid auto-snapshot value: must be <= than processes\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (uwsgi.static_cache_paths > 0 && !uwsgi.cache_max_items) {
|
|
uwsgi_log("caching of static paths requires uWSGI caching !!!\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|