diff options
author | Jérôme Loyet <fat@php.net> | 2010-04-21 22:56:33 +0000 |
---|---|---|
committer | Jérôme Loyet <fat@php.net> | 2010-04-21 22:56:33 +0000 |
commit | 3defa292f261d13ba01f6a18e37ee512ea556dbd (patch) | |
tree | 40354f5bf48fd74b187e242e72b24edcbe6085df | |
parent | 9d395a4a2b34ad7ed2ec37976bc33117cb3ec554 (diff) | |
download | php-git-3defa292f261d13ba01f6a18e37ee512ea556dbd.tar.gz |
switch the configuration syntax from xml to ini
It's been describe in the RFC: http://wiki.php.net/rfc/fpm/ini_syntax
-rw-r--r-- | sapi/fpm/config.m4 | 11 | ||||
-rw-r--r-- | sapi/fpm/fpm/fastcgi.c | 3 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_children.c | 8 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_conf.c | 843 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_conf.h | 57 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_env.c | 6 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_php.c | 4 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_process_ctl.c | 16 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_sockets.c | 38 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_status.c | 18 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_unix.c | 21 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_worker_pool.c | 3 | ||||
-rw-r--r-- | sapi/fpm/fpm/fpm_worker_pool.h | 1 | ||||
-rw-r--r-- | sapi/fpm/fpm/xml_config.c | 275 | ||||
-rw-r--r-- | sapi/fpm/fpm/xml_config.h | 47 | ||||
-rw-r--r-- | sapi/fpm/php-fpm.conf.in | 499 |
16 files changed, 920 insertions, 930 deletions
diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index dba3f85f99..d3ffc67ddf 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -8,11 +8,6 @@ minimum_libevent_version="1.4.11" PHP_ARG_ENABLE(fpm,, [ --enable-fpm EXPERIMENTAL: Enable building of the fpm SAPI executable], no, no) -if test -z "$PHP_LIBXML_DIR"; then - PHP_ARG_WITH(libxml-dir, libxml2 install dir, - [ --with-libxml-dir=DIR FPM: libxml2 install prefix], no, no) -fi - dnl libevent check function {{{ dnl @synopsis AC_LIB_EVENT([MINIMUM-VERSION]) dnl @@ -515,11 +510,6 @@ if test "$PHP_FPM" != "no"; then AC_MSG_ERROR([build test failed. Please check the config.log for details.]) ], $LIBEVENT_LIBS) - PHP_SETUP_LIBXML(FPM_SHARED_LIBADD, [ - ], [ - AC_MSG_ERROR([xml2-config not found. Please check your libxml2 installation.]) - ]) - AC_FPM_STDLIBS AC_FPM_PRCTL AC_FPM_CLOCK @@ -593,7 +583,6 @@ if test "$PHP_FPM" != "no"; then fpm/fpm_stdio.c \ fpm/fpm_unix.c \ fpm/fpm_worker_pool.c \ - fpm/xml_config.c \ fpm/zlog.c \ " diff --git a/sapi/fpm/fpm/fastcgi.c b/sapi/fpm/fpm/fastcgi.c index 85322c786d..94b2a9104c 100644 --- a/sapi/fpm/fpm/fastcgi.c +++ b/sapi/fpm/fpm/fastcgi.c @@ -373,7 +373,7 @@ void fcgi_set_allowed_clients(char *ip) } allowed_clients[n] = inet_addr(cur); if (allowed_clients[n] == INADDR_NONE) { - fprintf(stderr, "Wrong IP address '%s' in FCGI_WEB_SERVER_ADDRS\n", cur); + fprintf(stderr, "Wrong IP address '%s' in FCGI_WEB_SERVER_ADDRS or listen.allowed_clients\n", cur); } n++; cur = end; @@ -383,6 +383,7 @@ void fcgi_set_allowed_clients(char *ip) } } +//TODO static int is_port_number(const char *bindpath) { while (*bindpath) { diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c index 294f82a6bd..d303cfb038 100644 --- a/sapi/fpm/fpm/fpm_children.c +++ b/sapi/fpm/fpm/fpm_children.c @@ -143,7 +143,7 @@ static struct fpm_child_s *fpm_child_find(pid_t pid) /* {{{ */ static void fpm_child_init(struct fpm_worker_pool_s *wp) /* {{{ */ { - fpm_globals.max_requests = wp->config->max_requests; + fpm_globals.max_requests = wp->config->pm_max_requests; if (0 > fpm_stdio_init_child(wp) || 0 > fpm_status_init_child(wp) || @@ -355,14 +355,14 @@ int fpm_children_make(struct fpm_worker_pool_s *wp, int in_event_loop, int nb_to struct fpm_child_s *child; int max; - if (wp->config->pm->style == PM_STYLE_DYNAMIC) { + if (wp->config->pm == PM_STYLE_DYNAMIC) { if (!in_event_loop) { /* starting */ - max = wp->config->pm->dynamic.start_servers; + max = wp->config->pm_start_servers; } else { max = wp->running_children + nb_to_spawn; } } else { /* PM_STYLE_STATIC */ - max = wp->config->pm->max_children; + max = wp->config->pm_max_children; } while (!enough && fpm_pctl_can_spawn_children() && wp->running_children < max) { diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index fe685bea11..f3edc9f05d 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -16,10 +16,22 @@ #else # include <stdint.h> #endif +#ifdef HAVE_GLOB +# ifndef PHP_WIN32 +# include <glob.h> +# else +# include "win32/glob.h" +# endif +#endif #include <stdio.h> #include <unistd.h> +#include "php.h" +#include "zend_ini_scanner.h" +#include "zend_globals.h" +#include "zend_stream.h" + #include "fpm.h" #include "fpm_conf.h" #include "fpm_stdio.h" @@ -29,91 +41,195 @@ #include "fpm_sockets.h" #include "fpm_shm.h" #include "fpm_status.h" -#include "xml_config.h" #include "zlog.h" -struct fpm_global_config_s fpm_global_config; +static int fpm_conf_load_ini_file(char *filename); +static char *fpm_conf_set_integer(zval *value, void **config, intptr_t offset); +static char *fpm_conf_set_time(zval *value, void **config, intptr_t offset); +static char *fpm_conf_set_boolean(zval *value, void **config, intptr_t offset); +static char *fpm_conf_set_string(zval *value, void **config, intptr_t offset); +static char *fpm_conf_set_log_level(zval *value, void **config, intptr_t offset); +static char *fpm_conf_set_rlimit_core(zval *value, void **config, intptr_t offset); +static char *fpm_conf_set_pm(zval *value, void **config, intptr_t offset); + +struct fpm_global_config_s fpm_global_config = { 0, 0, 0, 1, NULL, NULL}; +static struct fpm_worker_pool_s *current_wp = NULL; +static int ini_recursion = 0; +static char *ini_filename = NULL; +static int ini_lineno = 0; +static char *ini_include = NULL; + +static struct ini_value_parser_s ini_fpm_global_options[] = { + { "emergency_restart_threshold", &fpm_conf_set_integer, offsetof(struct fpm_global_config_s, emergency_restart_threshold) }, + { "emergency_restart_interval", &fpm_conf_set_time, offsetof(struct fpm_global_config_s, emergency_restart_interval) }, + { "process_control_timeout", &fpm_conf_set_time, offsetof(struct fpm_global_config_s, process_control_timeout) }, + { "daemonize", &fpm_conf_set_boolean, offsetof(struct fpm_global_config_s, daemonize) }, + { "pid", &fpm_conf_set_string, offsetof(struct fpm_global_config_s, pid_file) }, + { "error_log", &fpm_conf_set_string, offsetof(struct fpm_global_config_s, error_log) }, + { "log_level", &fpm_conf_set_log_level, 0 }, + { 0, 0, 0 } +}; -static void *fpm_global_config_ptr() /* {{{ */ +static struct ini_value_parser_s ini_fpm_pool_options[] = { + { "user", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, user) }, + { "group", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, group) }, + { "chroot", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, chroot) }, + { "chdir", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, chdir) }, + { "request_terminate_timeout", &fpm_conf_set_time, offsetof(struct fpm_worker_pool_config_s, request_terminate_timeout) }, + { "request_slowlog_timeout", &fpm_conf_set_time, offsetof(struct fpm_worker_pool_config_s, request_slowlog_timeout) }, + { "slowlog", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, slowlog) }, + { "rlimit_files", &fpm_conf_set_integer, offsetof(struct fpm_worker_pool_config_s, rlimit_files) }, + { "rlimit_core", &fpm_conf_set_rlimit_core, offsetof(struct fpm_worker_pool_config_s, rlimit_core) }, + { "catch_workers_output", &fpm_conf_set_boolean, offsetof(struct fpm_worker_pool_config_s, catch_workers_output) }, + { "listen", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, listen_address) }, + { "listen.owner", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, listen_owner) }, + { "listen.group", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, listen_group) }, + { "listen.mode", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, listen_mode) }, + { "listen.backlog", &fpm_conf_set_integer, offsetof(struct fpm_worker_pool_config_s, listen_backlog) }, + { "listen.allowed_clients", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, listen_allowed_clients) }, + { "pm", &fpm_conf_set_pm, offsetof(struct fpm_worker_pool_config_s, pm) }, + { "pm.max_requests", &fpm_conf_set_integer, offsetof(struct fpm_worker_pool_config_s, pm_max_requests) }, + { "pm.max_children", &fpm_conf_set_integer, offsetof(struct fpm_worker_pool_config_s, pm_max_children) }, + { "pm.start_servers", &fpm_conf_set_integer, offsetof(struct fpm_worker_pool_config_s, pm_start_servers) }, + { "pm.min_spare_servers", &fpm_conf_set_integer, offsetof(struct fpm_worker_pool_config_s, pm_min_spare_servers) }, + { "pm.max_spare_servers", &fpm_conf_set_integer, offsetof(struct fpm_worker_pool_config_s, pm_max_spare_servers) }, + { "pm.status_path", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, pm_status_path) }, + { "ping.path", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, ping_path) }, + { "ping.response", &fpm_conf_set_string, offsetof(struct fpm_worker_pool_config_s, ping_response) }, + { 0, 0, 0 } +}; + +static char *fpm_conf_set_boolean(zval *value, void **config, intptr_t offset) /* {{{ */ { - return &fpm_global_config; + char *val = Z_STRVAL_P(value); + long value_y = !strcasecmp(val, "yes") || !strcmp(val, "1") || !strcasecmp(val, "on") || !strcasecmp(val, "true"); + long value_n = !strcasecmp(val, "no") || !strcmp(val, "0") || !strcasecmp(val, "off") || !strcasecmp(val, "false"); + + if (!value_y && !value_n) { + return "invalid boolean value"; + } + + * (int *) ((char *) *config + offset) = value_y ? 1 : 0; + return NULL; } /* }}} */ -static char *fpm_conf_set_log_level(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ +static char *fpm_conf_set_string(zval *value, void **config, intptr_t offset) /* {{{ */ { - char *value = vv; + char *new; + char **old = (char **) ((char *) *config + offset); + if (*old) { + return "it's already been defined. Can't do that twice."; + } - if (!strcmp(value, "debug")) { - fpm_globals.log_level = ZLOG_DEBUG; - } else if (!strcmp(value, "notice")) { - fpm_globals.log_level = ZLOG_NOTICE; - } else if (!strcmp(value, "warn")) { - fpm_globals.log_level = ZLOG_WARNING; - } else if (!strcmp(value, "error")) { - fpm_globals.log_level = ZLOG_ERROR; - } else if (!strcmp(value, "alert")) { - fpm_globals.log_level = ZLOG_ALERT; - } else { - return "invalid value for 'log_level'"; + new = strdup(Z_STRVAL_P(value)); + if (!new) { + return "fpm_conf_set_string(): strdup() failed"; } + *old = new; return NULL; } /* }}} */ -static struct xml_conf_section xml_section_fpm_global_options = { - .conf = &fpm_global_config_ptr, - .path = "/configuration/global_options", - .parsers = (struct xml_value_parser []) { - { XML_CONF_SCALAR, "emergency_restart_threshold", &xml_conf_set_slot_integer, offsetof(struct fpm_global_config_s, emergency_restart_threshold) }, - { XML_CONF_SCALAR, "emergency_restart_interval", &xml_conf_set_slot_time, offsetof(struct fpm_global_config_s, emergency_restart_interval) }, - { XML_CONF_SCALAR, "process_control_timeout", &xml_conf_set_slot_time, offsetof(struct fpm_global_config_s, process_control_timeout) }, - { XML_CONF_SCALAR, "daemonize", &xml_conf_set_slot_boolean, offsetof(struct fpm_global_config_s, daemonize) }, - { XML_CONF_SCALAR, "pid_file", &xml_conf_set_slot_string, offsetof(struct fpm_global_config_s, pid_file) }, - { XML_CONF_SCALAR, "error_log", &xml_conf_set_slot_string, offsetof(struct fpm_global_config_s, error_log) }, - { XML_CONF_SCALAR, "log_level", &fpm_conf_set_log_level, 0 }, - { 0, 0, 0, 0 } +static char *fpm_conf_set_integer(zval *value, void **config, intptr_t offset) /* {{{ */ +{ + int i; + char *val = Z_STRVAL_P(value); + + for (i=0; i<strlen(val); i++) { + if ( i == 0 && val[i] == '-' ) continue; + if (val[i] < '0' || val[i] > '9') { + return("is not a valid number (greater or equal than zero"); + } } -}; + * (int *) ((char *) *config + offset) = atoi(val); + return(NULL); +} +/* }}} */ -static char *fpm_conf_set_pm_style(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ +static char *fpm_conf_set_time(zval *value, void **config, intptr_t offset) /* {{{ */ { - char *value = vv; - struct fpm_pm_s *c = *conf; + char *val = Z_STRVAL_P(value); + int len = strlen(val); + char suffix; + int seconds; + if (!len) { + return "invalid time value"; + } + + suffix = val[len-1]; + switch (suffix) { + case 'm' : + val[len-1] = '\0'; + seconds = 60 * atoi(val); + break; + case 'h' : + val[len-1] = '\0'; + seconds = 60 * 60 * atoi(val); + break; + case 'd' : + val[len-1] = '\0'; + seconds = 24 * 60 * 60 * atoi(val); + break; + case 's' : /* s is the default suffix */ + val[len-1] = '\0'; + suffix = '0'; + default : + if (suffix < '0' || suffix > '9') { + return "unknown suffix used in time value"; + } + seconds = atoi(val); + break; + } - if (!strcmp(value, "static")) { - c->style = PM_STYLE_STATIC; - } else if (!strcmp(value, "dynamic")) { - c->style = PM_STYLE_DYNAMIC; + * (int *) ((char *) *config + offset) = seconds; + return NULL; +} +/* }}} */ + +static char *fpm_conf_set_log_level(zval *value, void **config, intptr_t offset) /* {{{ */ +{ + char *val = Z_STRVAL_P(value); + + if (!strcmp(val, "debug")) { + fpm_globals.log_level = ZLOG_DEBUG; + } else if (!strcasecmp(val, "notice")) { + fpm_globals.log_level = ZLOG_NOTICE; + } else if (!strcasecmp(val, "warn")) { + fpm_globals.log_level = ZLOG_WARNING; + } else if (!strcasecmp(val, "error")) { + fpm_globals.log_level = ZLOG_ERROR; + } else if (!strcasecmp(val, "alert")) { + fpm_globals.log_level = ZLOG_ALERT; } else { - return "invalid value for 'style'"; + return "invalid value for 'log_level'"; } return NULL; } /* }}} */ -static char *fpm_conf_set_rlimit_core(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ +static char *fpm_conf_set_rlimit_core(zval *value, void **config, intptr_t offset) /* {{{ */ { - char *value = vv; - struct fpm_worker_pool_config_s *c = *conf; + char *val = Z_STRVAL_P(value); + struct fpm_worker_pool_config_s *c = *config; - if (!strcmp(value, "unlimited")) { + if (!strcmp(val, "unlimited")) { c->rlimit_core = -1; } else { int int_value; void *subconf = &int_value; char *error; - error = xml_conf_set_slot_integer(&subconf, name, vv, 0); + error = fpm_conf_set_integer(value, &subconf, 0); if (error) { return error; } if (int_value < 0) { - return "invalid value for 'rlimit_core'"; + return "must be greater than zero or 'unlimited'"; } c->rlimit_core = int_value; @@ -123,107 +239,27 @@ static char *fpm_conf_set_rlimit_core(void **conf, char *name, void *vv, intptr_ } /* }}} */ -static char *fpm_conf_set_catch_workers_output(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ +static char *fpm_conf_set_pm(zval *value, void **config, intptr_t offset) /* {{{ */ { - struct fpm_worker_pool_config_s *c = *conf; - int int_value; - void *subconf = &int_value; - char *error; - - error = xml_conf_set_slot_boolean(&subconf, name, vv, 0); - - if (error) { - return error; + char *val = Z_STRVAL_P(value); + struct fpm_worker_pool_config_s *c = *config; + if (!strcmp(val, "static")) { + c->pm = PM_STYLE_STATIC; + } else if (!strcmp(val, "dynamic")) { + c->pm = PM_STYLE_DYNAMIC; + } else { + return "invalid process manager (static or dynamic)"; } - - c->catch_workers_output = int_value; return NULL; } /* }}} */ -static struct xml_conf_section fpm_conf_set_dynamic_subsection_conf = { - .path = "dynamic somewhere", /* fixme */ - .parsers = (struct xml_value_parser []) { - { XML_CONF_SCALAR, "start_servers", &xml_conf_set_slot_integer, offsetof(struct fpm_pm_s, dynamic.start_servers) }, - { XML_CONF_SCALAR, "min_spare_servers", &xml_conf_set_slot_integer, offsetof(struct fpm_pm_s, dynamic.min_spare_servers) }, - { XML_CONF_SCALAR, "max_spare_servers", &xml_conf_set_slot_integer, offsetof(struct fpm_pm_s, dynamic.max_spare_servers) }, - { 0, 0, 0, 0 } - } -}; - -static char *fpm_conf_set_dynamic_subsection(void **conf, char *name, void *xml_node, intptr_t offset) /* {{{ */ +static char *fpm_conf_set_array(zval *key, zval *value, void **config, int convert_to_bool) /* {{{ */ { - return xml_conf_parse_section(conf, &fpm_conf_set_dynamic_subsection_conf, xml_node); -} -/* }}} */ - -static struct xml_conf_section fpm_conf_set_listen_options_subsection_conf = { - .path = "listen options somewhere", /* fixme */ - .parsers = (struct xml_value_parser []) { - { XML_CONF_SCALAR, "backlog", &xml_conf_set_slot_integer, offsetof(struct fpm_listen_options_s, backlog) }, - { XML_CONF_SCALAR, "owner", &xml_conf_set_slot_string, offsetof(struct fpm_listen_options_s, owner) }, - { XML_CONF_SCALAR, "group", &xml_conf_set_slot_string, offsetof(struct fpm_listen_options_s, group) }, - { XML_CONF_SCALAR, "mode", &xml_conf_set_slot_string, offsetof(struct fpm_listen_options_s, mode) }, - { 0, 0, 0, 0 } - } -}; - -static char *fpm_conf_set_listen_options_subsection(void **conf, char *name, void *xml_node, intptr_t offset) /* {{{ */ -{ - void *subconf = (char *) *conf + offset; - struct fpm_listen_options_s *lo; - - lo = malloc(sizeof(*lo)); - - if (!lo) { - return "malloc() failed"; - } - - memset(lo, 0, sizeof(*lo)); - lo->backlog = -1; - * (struct fpm_listen_options_s **) subconf = lo; - subconf = lo; - - return xml_conf_parse_section(&subconf, &fpm_conf_set_listen_options_subsection_conf, xml_node); -} -/* }}} */ - -static struct xml_conf_section fpm_conf_set_pm_subsection_conf = { - .path = "pm settings somewhere", /* fixme */ - .parsers = (struct xml_value_parser []) { - { XML_CONF_SCALAR, "style", &fpm_conf_set_pm_style, 0 }, - { XML_CONF_SCALAR, "max_children", &xml_conf_set_slot_integer, offsetof(struct fpm_pm_s, max_children) }, - { XML_CONF_SCALAR, "status", &xml_conf_set_slot_string, offsetof(struct fpm_pm_s, status) }, - { XML_CONF_SCALAR, "ping", &xml_conf_set_slot_string, offsetof(struct fpm_pm_s, ping) }, - { XML_CONF_SCALAR, "pong", &xml_conf_set_slot_string, offsetof(struct fpm_pm_s, pong) }, - { XML_CONF_SUBSECTION, "dynamic", &fpm_conf_set_dynamic_subsection, offsetof(struct fpm_pm_s, dynamic) }, - { 0, 0, 0, 0 } - } -}; - -static char *fpm_conf_set_pm_subsection(void **conf, char *name, void *xml_node, intptr_t offset) /* {{{ */ -{ - void *subconf = (char *) *conf + offset; - struct fpm_pm_s *pm; - - pm = malloc(sizeof(*pm)); - - if (!pm) { - return "fpm_conf_set_pm_subsection(): malloc failed"; - } - - memset(pm, 0, sizeof(*pm)); - *(struct fpm_pm_s **) subconf = pm; - subconf = pm; - return xml_conf_parse_section(&subconf, &fpm_conf_set_pm_subsection_conf, xml_node); -} -/* }}} */ - -static char *xml_conf_set_slot_key_value_pair(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ -{ - char *value = vv; struct key_value_s *kv; - struct key_value_s ***parent = (struct key_value_s ***) conf; + struct key_value_s ***parent = (struct key_value_s ***) config; + int b; + void *subconf = &b; kv = malloc(sizeof(*kv)); @@ -232,67 +268,33 @@ static char *xml_conf_set_slot_key_value_pair(void **conf, char *name, void *vv, } memset(kv, 0, sizeof(*kv)); - kv->key = strdup(name); - kv->value = strdup(value); - - if (!kv->key || !kv->value) { - return "xml_conf_set_slot_key_value_pair(): strdup() failed"; - } - - kv->next = **parent; - **parent = kv; - return NULL; -} -/* }}} */ - -static char *xml_conf_set_slot_key_value_pair_bool(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ -{ - int value; - void *subconf = &value; - char *error; + kv->key = strdup(Z_STRVAL_P(key)); - error = xml_conf_set_slot_boolean(&subconf, name, vv, 0); - if (error) { - return error; + if (!kv->key) { + return "fpm_conf_set_array: strdup(key) failed"; } - return(xml_conf_set_slot_key_value_pair(conf, name, value ? "On" : "Off", offset)); -} -/* }}} */ - -static struct xml_conf_section fpm_conf_set_key_value_pairs_subsection_conf = { - .path = "key_value_pairs somewhere", /* fixme */ - .parsers = (struct xml_value_parser []) { - { XML_CONF_SCALAR, 0, &xml_conf_set_slot_key_value_pair, 0 }, - { 0, 0, 0, 0 } + if (convert_to_bool) { + char *err = fpm_conf_set_boolean(value, &subconf, 0); + if (err) return(err); + kv->value = strdup(b ? "On" : "Off"); + } else { + kv->value = strdup(Z_STRVAL_P(value)); } -}; -static struct xml_conf_section fpm_conf_set_key_value_pairs_subsection_conf_bool = { - .path = "key_value_pairs somewhere", /* fixme */ - .parsers = (struct xml_value_parser []) { - { XML_CONF_SCALAR, 0, &xml_conf_set_slot_key_value_pair_bool, 0 }, - { 0, 0, 0, 0 } + if (!kv->value) { + free(kv->key); + return "fpm_conf_set_array: strdup(value) failed"; } -}; - -static char *fpm_conf_set_key_value_pairs_subsection(void **conf, char *name, void *xml_node, intptr_t offset) /* {{{ */ -{ - void *next_kv = (char *) *conf + offset; - return xml_conf_parse_section(&next_kv, &fpm_conf_set_key_value_pairs_subsection_conf, xml_node); -} -/* }}} */ -static char *fpm_conf_set_key_value_pairs_subsection_bool(void **conf, char *name, void *xml_node, intptr_t offset) /* {{{ */ -{ - void *next_kv = (char *) *conf + offset; - return xml_conf_parse_section(&next_kv, &fpm_conf_set_key_value_pairs_subsection_conf_bool, xml_node); + kv->next = **parent; + **parent = kv; + return NULL; } /* }}} */ static void *fpm_worker_pool_config_alloc() /* {{{ */ { - static struct fpm_worker_pool_s *current_wp = 0; struct fpm_worker_pool_s *wp; wp = fpm_worker_pool_alloc(); @@ -308,9 +310,19 @@ static void *fpm_worker_pool_config_alloc() /* {{{ */ } memset(wp->config, 0, sizeof(struct fpm_worker_pool_config_s)); + wp->config->listen_backlog = -1; - if (current_wp) { - current_wp->next = wp; + if (!fpm_worker_all_pools) { + fpm_worker_all_pools = wp; + } else { + struct fpm_worker_pool_s *tmp = fpm_worker_all_pools; + while (tmp) { + if (!tmp->next) { + tmp->next = wp; + break; + } + tmp = tmp->next; + } } current_wp = wp; @@ -323,16 +335,13 @@ int fpm_worker_pool_config_free(struct fpm_worker_pool_config_s *wpc) /* {{{ */ struct key_value_s *kv, *kv_next; free(wpc->name); + free(wpc->pm_status_path); + free(wpc->ping_path); + free(wpc->ping_response); free(wpc->listen_address); - free(wpc->pm->status); - free(wpc->pm->ping); - free(wpc->pm->pong); - if (wpc->listen_options) { - free(wpc->listen_options->owner); - free(wpc->listen_options->group); - free(wpc->listen_options->mode); - free(wpc->listen_options); - } + free(wpc->listen_owner); + free(wpc->listen_group); + free(wpc->listen_mode); for (kv = wpc->php_values; kv; kv = kv_next) { kv_next = kv->next; free(kv->key); @@ -345,59 +354,23 @@ int fpm_worker_pool_config_free(struct fpm_worker_pool_config_s *wpc) /* {{{ */ free(kv->value); free(kv); } - for (kv = wpc->environment; kv; kv = kv_next) { + for (kv = wpc->env; kv; kv = kv_next) { kv_next = kv->next; free(kv->key); free(kv->value); free(kv); } - free(wpc->pm); + free(wpc->listen_allowed_clients); free(wpc->user); free(wpc->group); free(wpc->chroot); free(wpc->chdir); - free(wpc->allowed_clients); free(wpc->slowlog); return 0; } /* }}} */ -static struct xml_conf_section xml_section_fpm_worker_pool_config = { - .conf = &fpm_worker_pool_config_alloc, - .path = "/configuration/workers/pool", - .parsers = (struct xml_value_parser []) { - { XML_CONF_SCALAR, "name", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, name) }, - { XML_CONF_SCALAR, "listen_address", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, listen_address) }, - { XML_CONF_SUBSECTION, "listen_options", &fpm_conf_set_listen_options_subsection, offsetof(struct fpm_worker_pool_config_s, listen_options) }, - { XML_CONF_SUBSECTION, "php_value", &fpm_conf_set_key_value_pairs_subsection, offsetof(struct fpm_worker_pool_config_s, php_values) }, - { XML_CONF_SUBSECTION, "php_flag", &fpm_conf_set_key_value_pairs_subsection_bool, offsetof(struct fpm_worker_pool_config_s, php_values) }, - { XML_CONF_SUBSECTION, "php_admin_value", &fpm_conf_set_key_value_pairs_subsection, offsetof(struct fpm_worker_pool_config_s, php_admin_values) }, - { XML_CONF_SUBSECTION, "php_admin_flag", &fpm_conf_set_key_value_pairs_subsection_bool, offsetof(struct fpm_worker_pool_config_s, php_admin_values) }, - { XML_CONF_SCALAR, "user", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, user) }, - { XML_CONF_SCALAR, "group", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, group) }, - { XML_CONF_SCALAR, "chroot", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, chroot) }, - { XML_CONF_SCALAR, "chdir", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, chdir) }, - { XML_CONF_SCALAR, "allowed_clients", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, allowed_clients) }, - { XML_CONF_SUBSECTION, "environment", &fpm_conf_set_key_value_pairs_subsection, offsetof(struct fpm_worker_pool_config_s, environment) }, - { XML_CONF_SCALAR, "request_terminate_timeout", &xml_conf_set_slot_time, offsetof(struct fpm_worker_pool_config_s, request_terminate_timeout) }, - { XML_CONF_SCALAR, "request_slowlog_timeout", &xml_conf_set_slot_time, offsetof(struct fpm_worker_pool_config_s, request_slowlog_timeout) }, - { XML_CONF_SCALAR, "slowlog", &xml_conf_set_slot_string, offsetof(struct fpm_worker_pool_config_s, slowlog) }, - { XML_CONF_SCALAR, "rlimit_files", &xml_conf_set_slot_integer, offsetof(struct fpm_worker_pool_config_s, rlimit_files) }, - { XML_CONF_SCALAR, "rlimit_core", &fpm_conf_set_rlimit_core, 0 }, - { XML_CONF_SCALAR, "max_requests", &xml_conf_set_slot_integer, offsetof(struct fpm_worker_pool_config_s, max_requests) }, - { XML_CONF_SCALAR, "catch_workers_output", &fpm_conf_set_catch_workers_output, 0 }, - { XML_CONF_SUBSECTION, "pm", &fpm_conf_set_pm_subsection, offsetof(struct fpm_worker_pool_config_s, pm) }, - { 0, 0, 0, 0 } - } -}; - -static struct xml_conf_section *fpm_conf_all_sections[] = { - &xml_section_fpm_global_options, - &xml_section_fpm_worker_pool_config, - 0 -}; - static int fpm_evaluate_full_path(char **path) /* {{{ */ { if (**path != '/') { @@ -436,7 +409,13 @@ static int fpm_conf_process_all_pools() /* {{{ */ fpm_evaluate_full_path(&wp->config->listen_address); } } else { - wp->is_template = 1; + zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] no listen address have been defined!", wp->config->name); + return -1; + } + + if (!wp->config->user) { + zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] user has not been defined", wp->config->name); + return -1; } if (wp->config->pm == NULL) { @@ -444,36 +423,41 @@ static int fpm_conf_process_all_pools() /* {{{ */ return -1; } - if (wp->config->pm->style == PM_STYLE_DYNAMIC) { - struct fpm_pm_s *pm = wp->config->pm; + if (wp->config->pm_max_children < 1) { + zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] pm_max_children must be a positiive value", wp->config->name); + return -1; + } + + if (wp->config->pm == PM_STYLE_DYNAMIC) { + struct fpm_worker_pool_config_s *config = wp->config; - if (pm->dynamic.min_spare_servers <= 0) { - zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] min_spare_servers(%d) must be a positive value", wp->config->name, pm->dynamic.min_spare_servers); + if (config->pm_min_spare_servers <= 0) { + zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] min_spare_servers(%d) must be a positive value", wp->config->name, config->pm_min_spare_servers); return -1; } - if (pm->dynamic.max_spare_servers <= 0) { - zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] max_spare_servers(%d) must be a positive value", wp->config->name, pm->dynamic.max_spare_servers); + if (config->pm_max_spare_servers <= 0) { + zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] max_spare_servers(%d) must be a positive value", wp->config->name, config->pm_max_spare_servers); return -1; } - if (pm->dynamic.min_spare_servers > pm->max_children || - pm->dynamic.max_spare_servers > pm->max_children) { + if (config->pm_max_spare_servers > config->pm_max_children || + config->pm_max_spare_servers > config->pm_max_children) { zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] min_spare_servers(%d) and max_spare_servers(%d) cannot be greater than max_children(%d)", - wp->config->name, pm->dynamic.min_spare_servers, pm->dynamic.max_spare_servers, pm->max_children); + wp->config->name, config->pm_max_spare_servers, config->pm_max_spare_servers, config->pm_max_children); return -1; } - if (pm->dynamic.max_spare_servers < pm->dynamic.min_spare_servers) { - zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] max_spare_servers(%d) must not be less than min_spare_servers(%d)", wp->config->name, pm->dynamic.max_spare_servers, pm->dynamic.min_spare_servers); + if (config->pm_max_spare_servers < config->pm_max_spare_servers) { + zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] max_spare_servers(%d) must not be less than min_spare_servers(%d)", wp->config->name, config->pm_max_spare_servers, config->pm_max_spare_servers); return -1; } - if (pm->dynamic.start_servers <= 0) { - pm->dynamic.start_servers = pm->dynamic.min_spare_servers + ((pm->dynamic.max_spare_servers - pm->dynamic.min_spare_servers) / 2); - zlog(ZLOG_STUFF, ZLOG_NOTICE, "[pool %s] start_servers has been set to %d", wp->config->name, pm->dynamic.start_servers); - } else if (pm->dynamic.start_servers < pm->dynamic.min_spare_servers || pm->dynamic.start_servers > pm->dynamic.max_spare_servers) { - zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] start_servers(%d) must not be less than min_spare_servers(%d) and not greater than max_spare_servers(%d)", wp->config->name, pm->dynamic.start_servers, pm->dynamic.min_spare_servers, pm->dynamic.max_spare_servers); + if (config->pm_start_servers <= 0) { + config->pm_start_servers = config->pm_min_spare_servers + ((config->pm_max_spare_servers - config->pm_min_spare_servers) / 2); + zlog(ZLOG_STUFF, ZLOG_WARNING, "[pool %s] start_servers is not set. It's been set to %d.", wp->config->name, config->pm_start_servers); + } else if (config->pm_start_servers < config->pm_max_spare_servers || config->pm_start_servers > config->pm_max_spare_servers) { + zlog(ZLOG_STUFF, ZLOG_ALERT, "[pool %s] start_servers(%d) must not be less than min_spare_servers(%d) and not greater than max_spare_servers(%d)", wp->config->name, config->pm_start_servers, config->pm_max_spare_servers, config->pm_max_spare_servers); return -1; } } @@ -482,16 +466,14 @@ static int fpm_conf_process_all_pools() /* {{{ */ if (wp->config->request_slowlog_timeout) { #if HAVE_FPM_TRACE if (! (wp->config->slowlog && *wp->config->slowlog)) { - zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] 'slowlog' must be specified for use with 'request_slowlog_timeout'", - wp->config->name); + zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] 'slowlog' must be specified for use with 'request_slowlog_timeout'", wp->config->name); return -1; } #else static int warned = 0; if (!warned) { - zlog(ZLOG_STUFF, ZLOG_WARNING, "[pool %s] 'request_slowlog_timeout' is not supported on your system", - wp->config->name); + zlog(ZLOG_STUFF, ZLOG_WARNING, "[pool %s] 'request_slowlog_timeout' is not supported on your system", wp->config->name); warned = 1; } @@ -515,60 +497,60 @@ static int fpm_conf_process_all_pools() /* {{{ */ } } - if (wp->config->pm->ping && *wp->config->pm->ping) { - char *ping = wp->config->pm->ping; + if (wp->config->ping_path && *wp->config->ping_path) { + char *ping = wp->config->ping_path; int i; if (*ping != '/') { - zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the ping page '%s' must start with a '/'", wp->config->name, ping); + zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the ping path '%s' must start with a '/'", wp->config->name, ping); return -1; } if (strlen(ping) < 2) { - zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the ping page '%s' is not long enough", wp->config->name, ping); + zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the ping path '%s' is not long enough", wp->config->name, ping); return -1; } for (i=0; i<strlen(ping); i++) { if (!isalnum(ping[i]) && ping[i] != '/' && ping[i] != '-' && ping[i] != '_' && ping[i] != '.') { - zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the ping page '%s' must containt only the following characters '[alphanum]/_-.'", wp->config->name, ping); + zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the ping path '%s' must containt only the following characters '[alphanum]/_-.'", wp->config->name, ping); return -1; } } - if (!wp->config->pm->pong) { - wp->config->pm->pong = strdup("pong"); + if (!wp->config->ping_response) { + wp->config->ping_response = strdup("pong"); } else { - if (strlen(wp->config->pm->pong) < 1) { - zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the ping response page '%s' is not long enough", wp->config->name, wp->config->pm->pong); + if (strlen(wp->config->ping_response) < 1) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the ping response page '%s' is not long enough", wp->config->name, wp->config->ping_response); return -1; } } } else { - if (wp->config->pm->pong) { - free(wp->config->pm->pong); - wp->config->pm->pong = NULL; + if (wp->config->ping_response) { + free(wp->config->ping_response); + wp->config->ping_response = NULL; } } - if (wp->config->pm->status && *wp->config->pm->status) { + if (wp->config->pm_status_path && *wp->config->pm_status_path) { int i; - char *status = wp->config->pm->status; + char *status = wp->config->pm_status_path; /* struct fpm_status_s fpm_status; */ if (*status != '/') { - zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the status page '%s' must start with a '/'", wp->config->name, status); + zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the status path '%s' must start with a '/'", wp->config->name, status); return -1; } if (strlen(status) < 2) { - zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the status page '%s' is not long enough", wp->config->name, status); + zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the status path '%s' is not long enough", wp->config->name, status); return -1; } for (i=0; i<strlen(status); i++) { if (!isalnum(status[i]) && status[i] != '/' && status[i] != '-' && status[i] != '_' && status[i] != '.') { - zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the status page '%s' must containt only the following characters '[alphanum]/_-.'", wp->config->name, status); + zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] the status path '%s' must containt only the following characters '[alphanum]/_-.'", wp->config->name, status); return -1; } } @@ -579,7 +561,7 @@ static int fpm_conf_process_all_pools() /* {{{ */ } fpm_status_update_accepted_conn(wp->shm_status, 0); fpm_status_update_activity(wp->shm_status, -1, -1, -1, 1); - fpm_status_set_pm(wp->shm_status, wp->config->pm->style); + fpm_status_set_pm(wp->shm_status, wp->config->pm); /* memset(&fpm_status.last_update, 0, sizeof(fpm_status.last_update)); */ } } @@ -660,34 +642,321 @@ static void fpm_conf_cleanup(int which, void *arg) /* {{{ */ } /* }}} */ -int fpm_conf_init_main() /* {{{ */ +static void fpm_conf_ini_parser_include(char *inc, void *arg TSRMLS_DC) /* {{{ */ { - char *filename = fpm_globals.config; - char *err; + char *filename; + int *error = (int *)arg;; + glob_t g; + int i; + + if (!inc || !arg) return; + if (*error) return; /* We got already an error. Switch to the end. */ + spprintf(&filename, 0, "%s", ini_filename); + +#ifdef HAVE_GLOB + { + g.gl_offs = 0; + if ((i = glob(inc, GLOB_ERR | GLOB_MARK | GLOB_NOSORT, NULL, &g)) != 0) { +#ifdef GLOB_NOMATCH + if (i == GLOB_NOMATCH) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "Nothing match the include pattern '%s' from %s at line %d.", inc, filename, ini_lineno); + *error = 1; + return; + } +#endif /* GLOB_NOMATCH */ + zlog(ZLOG_STUFF, ZLOG_ERROR, "Unable to globalize '%s' (ret=%d) from %s at line %d.", inc, i, filename, ini_lineno); + *error = 1; + return; + } + + for(i=0; i<g.gl_pathc; i++) { + int len = strlen(g.gl_pathv[i]); + if (len < 1) continue; + if (g.gl_pathv[i][len - 1] == '/') continue; /* don't parse directories */ + if (0 > fpm_conf_load_ini_file(g.gl_pathv[i])) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "Unable to include %s from %s at line %d", g.gl_pathv[i], filename, ini_lineno); + *error = 1; + return; + } + } + globfree(&g); + } +#else /* HAVE_GLOB */ + if (0 > fpm_conf_load_ini_file(inc)) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "Unable to include %s from %s at line %d", inc, filename, ini_lineno); + *error = 1; + return; + } +#endif /* HAVE_GLOB */ +} +/* }}} */ + +static void fpm_conf_ini_parser_section(zval *section, void *arg TSRMLS_DC) /* {{{ */ +{ + struct fpm_worker_pool_s *wp; + struct fpm_worker_pool_config_s *config; + int *error = (int *)arg; + + /* switch to global conf */ + if (!strcasecmp(Z_STRVAL_P(section), "global")) { + current_wp = NULL; + return; + } + + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { + if (!wp->config) continue; + if (!wp->config->name) continue; + if (!strcasecmp(wp->config->name, Z_STRVAL_P(section))) { + /* Found a wp with the same name. Bring it back */ + current_wp = wp; + return; + } + } + + /* it's a new pool */ + config = (struct fpm_worker_pool_config_s *)fpm_worker_pool_config_alloc(); + if (!current_wp || !config) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] Unable to alloc a new WorkerPool for worker '%s'", ini_filename, ini_lineno, Z_STRVAL_P(section)); + *error = 1; + return; + } + config->name = strdup(Z_STRVAL_P(section)); + if (!config->name) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] Unable to alloc memory for configuration name for worker '%s'", ini_filename, ini_lineno, Z_STRVAL_P(section)); + *error = 1; + return; + } +} +/* }}} */ + +static void fpm_conf_ini_parser_entry(zval *name, zval *value, void *arg TSRMLS_DC) /* {{{ */ +{ + struct ini_value_parser_s *parser; + void *config = NULL; + + int *error = (int *)arg; + if (!value) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] value is NULL for a ZEND_INI_PARSER_ENTRY", ini_filename, ini_lineno); + *error = 1; + return; + } + + if (!strcmp(Z_STRVAL_P(name), "include")) { + // fpm_conf_ini_parser_include(value, error); + if (ini_include) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] two includes at the same time !", ini_filename, ini_lineno); + *error = 1; + return; + } + ini_include = strdup(Z_STRVAL_P(value)); + return; + } + + if (!current_wp) { /* we are in the global section */ + parser = ini_fpm_global_options; + config = &fpm_global_config; + } else { + parser = ini_fpm_pool_options; + config = current_wp->config; + } + + for (;parser->name; parser++) { + if (!strcasecmp(parser->name, Z_STRVAL_P(name))) { + char *ret; + if (!parser->parser) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] the parser for entry '%s' is not defined", ini_filename, ini_lineno, parser->name); + *error = 1; + return; + } + + ret = parser->parser(value, &config, parser->offset); + if (ret) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] unable to parse value for entry '%s': %s", ini_filename, ini_lineno, parser->name, ret); + *error = 1; + return; + } + + /* all is good ! */ + return; + } + } + + /* nothing has been found if we got here */ + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] unknown entry '%s'", ini_filename, ini_lineno, Z_STRVAL_P(name)); + *error = 1; +} +/* }}} */ + +static void fpm_conf_ini_parser_array(zval *name, zval *key, zval *value, void *arg TSRMLS_DC) /* {{{ */ +{ + int *error = (int *)arg; + char *err = NULL; + void *config; - if (0 > xml_conf_sections_register(fpm_conf_all_sections)) { + if (!Z_STRVAL_P(key) || !Z_STRVAL_P(value) || !*Z_STRVAL_P(key) || !*Z_STRVAL_P(value)) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] Mispell array ?", ini_filename, ini_lineno); + *error = 1; + return; + } + if (!current_wp || !current_wp->config) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] Array are not allowed in the global section", ini_filename, ini_lineno); + *error = 1; + return; + } + + if (!strcmp("env", Z_STRVAL_P(name))) { + config = (char *)current_wp->config + offsetof(struct fpm_worker_pool_config_s, env); + err = fpm_conf_set_array(key, value, &config, 0); + + } else if (!strcmp("php_value", Z_STRVAL_P(name))) { + config = (char *)current_wp->config + offsetof(struct fpm_worker_pool_config_s, php_values); + err = fpm_conf_set_array(key, value, &config, 0); + + } else if (!strcmp("php_admin_value", Z_STRVAL_P(name))) { + config = (char *)current_wp->config + offsetof(struct fpm_worker_pool_config_s, php_admin_values); + err = fpm_conf_set_array(key, value, &config, 0); + + } else if (!strcmp("php_flag", Z_STRVAL_P(name))) { + config = (char *)current_wp->config + offsetof(struct fpm_worker_pool_config_s, php_values); + err = fpm_conf_set_array(key, value, &config, 1); + + } else if (!strcmp("php_admin_flag", Z_STRVAL_P(name))) { + config = (char *)current_wp->config + offsetof(struct fpm_worker_pool_config_s, php_admin_values); + err = fpm_conf_set_array(key, value, &config, 1); + + } else { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] unknown directive '%s'", ini_filename, ini_lineno, Z_STRVAL_P(name)); + *error = 1; + return; + } + + if (err) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] error while parsing '%s[%s]' : %s", ini_filename, ini_lineno, Z_STRVAL_P(name), Z_STRVAL_P(key), err); + *error = 1; + return; + } +} +/* }}} */ + +static void fpm_conf_ini_parser(zval *arg1, zval *arg2, zval *arg3, int callback_type, void *arg TSRMLS_DC) /* {{{ */ +{ + int *error; + + if (!arg1 || !arg) return; + error = (int *)arg; + if (*error) return; /* We got already an error. Switch to the end. */ + + switch(callback_type) { + case ZEND_INI_PARSER_ENTRY: + fpm_conf_ini_parser_entry(arg1, arg2, error); + break;; + case ZEND_INI_PARSER_SECTION: + fpm_conf_ini_parser_section(arg1, error); + break;; + case ZEND_INI_PARSER_POP_ENTRY: + fpm_conf_ini_parser_array(arg1, arg3, arg2, error); + break;; + default: + zlog(ZLOG_STUFF, ZLOG_ERROR, "[%s:%d] Unknown INI syntax", ini_filename, ini_lineno); + *error = 1; + break;; + } +} +/* }}} */ + +int fpm_conf_load_ini_file(char *filename) /* {{{ */ +{ + int error = 0; + char buf[1024+1]; + int fd, n; + int nb_read = 1; + char c = '*'; + + int ret = 1; + + if (!filename || !filename[0]) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "Configuration file is empty"); + return -1; + } + + fd = open(filename, O_RDONLY, 0); + if (fd < 0) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "Unable to open file '%s', errno=%d", filename, errno); + return -1; + } + + if (ini_recursion++ > 4) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "You can include more than 5 files recusively"); return -1; } + ini_lineno = 0; + while (nb_read > 0) { + int tmp; + memset(buf, 0, sizeof(char) * (1024 + 1)); + for (n=0; n<1024 && (nb_read = read(fd, &c, sizeof(char))) == sizeof(char) && c != '\n'; n++) { + buf[n] = c; + } + if (c == '\n') { + buf[n++] = c; + } + ini_lineno++; + ini_filename = filename; + tmp = zend_parse_ini_string(buf, 1, ZEND_INI_SCANNER_RAW, (zend_ini_parser_cb_t)fpm_conf_ini_parser, &error TSRMLS_CC); + ini_filename = filename; + if (error || tmp == FAILURE) { + if (ini_include) free(ini_include); + ini_recursion--; + close(fd); + return -1; + } + if (ini_include) { + char *tmp = ini_include; + ini_include = NULL; + fpm_conf_ini_parser_include(tmp, &error TSRMLS_CC); + if (error) { + free(tmp); + ini_recursion--; + close(fd); + ret = -1; + } + free(tmp); + } + } + + ini_recursion--; + close(fd); + return ret; + +} +/* }}} */ + +int fpm_conf_init_main() /* {{{ */ +{ + char *filename = fpm_globals.config; + int free = 0; + int ret; + if (filename == NULL) { spprintf(&filename, 0, "%s/php-fpm.conf", PHP_SYSCONFDIR); - err = xml_conf_load_file(filename); - efree(filename); - } else { - err = xml_conf_load_file(filename); + free = 1; } - if (err) { - zlog(ZLOG_STUFF, ZLOG_ERROR, "failed to load configuration file: %s", err); + ret = fpm_conf_load_ini_file(filename); + + if (0 > ret) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "failed to load configuration file '%s'", filename); + if (free) efree(filename); return -1; } + if (free) efree(filename); + if (0 > fpm_conf_post_process()) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "failed to post process the configuration"); return -1; } - xml_conf_clean(); - if (0 > fpm_cleanup_add(FPM_CLEANUP_ALL, fpm_conf_cleanup, 0)) { return -1; } diff --git a/sapi/fpm/fpm/fpm_conf.h b/sapi/fpm/fpm/fpm_conf.h index 9ee16fd1e2..aace7811eb 100644 --- a/sapi/fpm/fpm/fpm_conf.h +++ b/sapi/fpm/fpm/fpm_conf.h @@ -5,6 +5,9 @@ #ifndef FPM_CONF_H #define FPM_CONF_H 1 +#include <stdint.h> +#include "php.h" + #define FPM_CONF_MAX_PONG_LENGTH 64 struct key_value_s; @@ -26,46 +29,42 @@ struct fpm_global_config_s { extern struct fpm_global_config_s fpm_global_config; -struct fpm_pm_s { - int style; - int max_children; - char *status; - char *ping; - char *pong; - struct { - int start_servers; - int min_spare_servers; - int max_spare_servers; - } dynamic; -}; - -struct fpm_listen_options_s { - int backlog; - char *owner; - char *group; - char *mode; -}; - struct fpm_worker_pool_config_s { char *name; - char *listen_address; - struct fpm_listen_options_s *listen_options; - struct key_value_s *php_values; - struct key_value_s *php_admin_values; char *user; char *group; char *chroot; char *chdir; - char *allowed_clients; - struct key_value_s *environment; - struct fpm_pm_s *pm; int request_terminate_timeout; int request_slowlog_timeout; char *slowlog; - int max_requests; int rlimit_files; int rlimit_core; - unsigned catch_workers_output:1; + int catch_workers_output; + int pm; + int pm_max_children; + char *pm_status_path; + int pm_max_requests; + int pm_start_servers; + int pm_min_spare_servers; + int pm_max_spare_servers; + char *ping_path; + char *ping_response; + char *listen_address; + int listen_backlog; + char *listen_owner; + char *listen_group; + char *listen_mode; + char *listen_allowed_clients; + struct key_value_s *env; + struct key_value_s *php_admin_values; + struct key_value_s *php_values; +}; + +struct ini_value_parser_s { + char *name; + char *(*parser)(zval *, void **, intptr_t); + intptr_t offset; }; enum { PM_STYLE_STATIC = 1, PM_STYLE_DYNAMIC = 2 }; diff --git a/sapi/fpm/fpm/fpm_env.c b/sapi/fpm/fpm/fpm_env.c index 3bf514e51d..ddc4705ecb 100644 --- a/sapi/fpm/fpm/fpm_env.c +++ b/sapi/fpm/fpm/fpm_env.c @@ -117,7 +117,7 @@ int fpm_env_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ clearenv(); - for (kv = wp->config->environment; kv; kv = kv->next) { + for (kv = wp->config->env; kv; kv = kv->next) { setenv(kv->key, kv->value, 1); } @@ -137,9 +137,7 @@ static int fpm_env_conf_wp(struct fpm_worker_pool_s *wp) /* {{{ */ { struct key_value_s *kv; - kv = wp->config->environment; - - for (kv = wp->config->environment; kv; kv = kv->next) { + for (kv = wp->config->env; kv; kv = kv->next) { if (*kv->value == '$') { char *value = getenv(kv->value + 1); diff --git a/sapi/fpm/fpm/fpm_php.c b/sapi/fpm/fpm/fpm_php.c index 5243716b65..a9288ae140 100644 --- a/sapi/fpm/fpm/fpm_php.c +++ b/sapi/fpm/fpm/fpm_php.c @@ -134,7 +134,7 @@ static int fpm_php_apply_defines(struct fpm_worker_pool_s *wp) /* {{{ */ static int fpm_php_set_allowed_clients(struct fpm_worker_pool_s *wp) /* {{{ */ { if (wp->listen_address_domain == FPM_AF_INET) { - fcgi_set_allowed_clients(wp->config->allowed_clients); + fcgi_set_allowed_clients(wp->config->listen_allowed_clients); } return 0; } @@ -145,7 +145,7 @@ static int fpm_php_set_fcgi_mgmt_vars(struct fpm_worker_pool_s *wp) /* {{{ */ char max_workers[10 + 1]; /* 4294967295 */ int len; - len = sprintf(max_workers, "%u", (unsigned int) wp->config->pm->max_children); + len = sprintf(max_workers, "%u", (unsigned int) wp->config->pm_max_children); fcgi_set_mgmt_var("FCGI_MAX_CONNS", sizeof("FCGI_MAX_CONNS")-1, max_workers, len); fcgi_set_mgmt_var("FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, max_workers, len); diff --git a/sapi/fpm/fpm/fpm_process_ctl.c b/sapi/fpm/fpm/fpm_process_ctl.c index d63fb4a5cd..b24f950f57 100644 --- a/sapi/fpm/fpm/fpm_process_ctl.c +++ b/sapi/fpm/fpm/fpm_process_ctl.c @@ -352,21 +352,21 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now, struct fpm_status_update_activity(wp->shm_status, idle, active, idle + active, 0); /* the rest is only used by PM_STYLE_DYNAMIC */ - if (wp->config->pm->style != PM_STYLE_DYNAMIC) continue; + if (wp->config->pm != PM_STYLE_DYNAMIC) continue; zlog(ZLOG_STUFF, ZLOG_DEBUG, "[pool %s] currently %d active children, %d spare children, %d running children. Spawning rate %d", wp->config->name, active, idle, wp->running_children, wp->idle_spawn_rate); - if (idle > wp->config->pm->dynamic.max_spare_servers && last_idle_child) { + if (idle > wp->config->pm_max_spare_servers && last_idle_child) { last_idle_child->idle_kill = 1; fpm_pctl_kill(last_idle_child->pid, FPM_PCTL_TERM); wp->idle_spawn_rate = 1; continue; } - if (idle < wp->config->pm->dynamic.min_spare_servers) { - if (wp->running_children >= wp->config->pm->max_children) { + if (idle < wp->config->pm_min_spare_servers) { + if (wp->running_children >= wp->config->pm_max_children) { if (!wp->warn_max_children) { - zlog(ZLOG_STUFF, ZLOG_WARNING, "[pool %s] server reached max_children setting (%d), consider raising it", wp->config->name, wp->config->pm->max_children); + zlog(ZLOG_STUFF, ZLOG_WARNING, "[pool %s] server reached max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children); wp->warn_max_children = 1; } wp->idle_spawn_rate = 1; @@ -378,13 +378,13 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now, struct } /* compute the number of idle process to spawn */ - i = MIN(wp->idle_spawn_rate, wp->config->pm->dynamic.min_spare_servers - idle); + i = MIN(wp->idle_spawn_rate, wp->config->pm_min_spare_servers - idle); /* get sure it won't exceed max_children */ - i = MIN(i, wp->config->pm->max_children - wp->running_children); + i = MIN(i, wp->config->pm_max_children - wp->running_children); if (i <= 0) { if (!wp->warn_max_children) { - zlog(ZLOG_STUFF, ZLOG_WARNING, "[pool %s] server reached max_children setting (%d), consider raising it", wp->config->name, wp->config->pm->max_children); + zlog(ZLOG_STUFF, ZLOG_WARNING, "[pool %s] server reached max_children setting (%d), consider raising it", wp->config->name, wp->config->pm_max_children); wp->warn_max_children = 1; } wp->idle_spawn_rate = 1; diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c index 57b0656a25..21baf053c5 100644 --- a/sapi/fpm/fpm/fpm_sockets.c +++ b/sapi/fpm/fpm/fpm_sockets.c @@ -164,16 +164,10 @@ static int fpm_sockets_hash_op(int sock, struct sockaddr *sa, char *key, int typ static int fpm_sockets_new_listening_socket(struct fpm_worker_pool_s *wp, struct sockaddr *sa, int socklen) /* {{{ */ { - int backlog = -1; int flags = 1; int sock; mode_t saved_umask; - /* we have custom backlog value */ - if (wp->config->listen_options) { - backlog = wp->config->listen_options->backlog; - } - sock = socket(sa->sa_family, SOCK_STREAM, 0); if (0 > sock) { @@ -205,7 +199,7 @@ static int fpm_sockets_new_listening_socket(struct fpm_worker_pool_s *wp, struct } umask(saved_umask); - if (0 > listen(sock, backlog)) { + if (0 > listen(sock, wp->config->listen_backlog)) { zlog(ZLOG_STUFF, ZLOG_SYSERROR, "listen() for address '%s' failed", wp->config->listen_address); return -1; } @@ -333,23 +327,21 @@ int fpm_sockets_init_main() /* {{{ */ /* create all required sockets */ for (wp = fpm_worker_all_pools; wp; wp = wp->next) { - if (!wp->is_template) { - switch (wp->listen_address_domain) { - case FPM_AF_INET : - wp->listening_socket = fpm_socket_af_inet_listening_socket(wp); - break; - - case FPM_AF_UNIX : - if (0 > fpm_unix_resolve_socket_premissions(wp)) { - return -1; - } - wp->listening_socket = fpm_socket_af_unix_listening_socket(wp); - break; - } + switch (wp->listen_address_domain) { + case FPM_AF_INET : + wp->listening_socket = fpm_socket_af_inet_listening_socket(wp); + break; - if (wp->listening_socket == -1) { - return -1; - } + case FPM_AF_UNIX : + if (0 > fpm_unix_resolve_socket_premissions(wp)) { + return -1; + } + wp->listening_socket = fpm_socket_af_unix_listening_socket(wp); + break; + } + + if (wp->listening_socket == -1) { + return -1; } } diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c index c9eadc820b..5b28062196 100644 --- a/sapi/fpm/fpm/fpm_status.c +++ b/sapi/fpm/fpm/fpm_status.c @@ -23,8 +23,8 @@ int fpm_status_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ zlog(ZLOG_STUFF, ZLOG_ERROR, "unable to init fpm_status because conf structure is NULL"); return -1; } - if (wp->config->pm->status || wp->config->pm->ping) { - if (wp->config->pm->status) { + if (wp->config->pm_status_path || wp->config->ping_path) { + if (wp->config->pm_status_path) { if (!wp->shm_status) { zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] unable to init fpm_status because the dedicated SHM has not been set", wp->config->name); return -1; @@ -32,16 +32,16 @@ int fpm_status_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ fpm_status_shm = wp->shm_status; } fpm_status_pool = strdup(wp->config->name); - if (wp->config->pm->status) { - fpm_status_uri = strdup(wp->config->pm->status); + if (wp->config->pm_status_path) { + fpm_status_uri = strdup(wp->config->pm_status_path); } - if (wp->config->pm->ping) { - if (!wp->config->pm->pong) { - zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] ping is set (%s) but pong is not set.", wp->config->name, wp->config->pm->ping); + if (wp->config->ping_path) { + if (!wp->config->ping_response) { + zlog(ZLOG_STUFF, ZLOG_ERROR, "[pool %s] ping is set (%s) but pong is not set.", wp->config->name, wp->config->ping_path); return -1; } - fpm_status_ping = strdup(wp->config->pm->ping); - fpm_status_pong = strdup(wp->config->pm->pong); + fpm_status_ping = strdup(wp->config->ping_path); + fpm_status_pong = strdup(wp->config->ping_response); } } return 0; diff --git a/sapi/fpm/fpm/fpm_unix.c b/sapi/fpm/fpm/fpm_unix.c index ba693b6421..0cec761167 100644 --- a/sapi/fpm/fpm/fpm_unix.c +++ b/sapi/fpm/fpm/fpm_unix.c @@ -29,23 +29,23 @@ size_t fpm_pagesize; int fpm_unix_resolve_socket_premissions(struct fpm_worker_pool_s *wp) /* {{{ */ { - struct fpm_listen_options_s *lo = wp->config->listen_options; + struct fpm_worker_pool_config_s *c = wp->config; /* uninitialized */ wp->socket_uid = -1; wp->socket_gid = -1; wp->socket_mode = 0666; - if (!lo) { + if (!c) { return 0; } - if (lo->owner && *lo->owner) { + if (c->listen_owner && *c->listen_owner) { struct passwd *pwd; - pwd = getpwnam(lo->owner); + pwd = getpwnam(c->listen_owner); if (!pwd) { - zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, lo->owner); + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, c->listen_owner); return -1; } @@ -53,19 +53,19 @@ int fpm_unix_resolve_socket_premissions(struct fpm_worker_pool_s *wp) /* {{{ */ wp->socket_gid = pwd->pw_gid; } - if (lo->group && *lo->group) { + if (c->listen_group && *c->listen_group) { struct group *grp; - grp = getgrnam(lo->group); + grp = getgrnam(c->listen_group); if (!grp) { - zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, lo->group); + zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, c->listen_group); return -1; } wp->socket_gid = grp->gr_gid; } - if (lo->mode && *lo->mode) { - wp->socket_mode = strtoul(lo->mode, 0, 8); + if (c->listen_mode && *c->listen_mode) { + wp->socket_mode = strtoul(c->listen_mode, 0, 8); } return 0; } @@ -152,6 +152,7 @@ int fpm_unix_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ getrlimit(RLIMIT_NOFILE, &r); r.rlim_cur = (rlim_t) wp->config->rlimit_files; +// r.rlim_max = (rlim_t) wp->config->rlimit_files; if (0 > setrlimit(RLIMIT_NOFILE, &r)) { zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] setrlimit(RLIMIT_NOFILE) failed", wp->config->name); } diff --git a/sapi/fpm/fpm/fpm_worker_pool.c b/sapi/fpm/fpm/fpm_worker_pool.c index 860f4d425c..53e3368fa7 100644 --- a/sapi/fpm/fpm/fpm_worker_pool.c +++ b/sapi/fpm/fpm/fpm_worker_pool.c @@ -51,9 +51,6 @@ struct fpm_worker_pool_s *fpm_worker_pool_alloc() /* {{{ */ } memset(ret, 0, sizeof(struct fpm_worker_pool_s)); - if (!fpm_worker_all_pools) { - fpm_worker_all_pools = ret; - } fpm_array_init(&ret->slots_used, sizeof(struct fpm_shm_slot_ptr_s), 50); fpm_array_init(&ret->slots_free, sizeof(struct fpm_shm_slot_ptr_s), 50); diff --git a/sapi/fpm/fpm/fpm_worker_pool.h b/sapi/fpm/fpm/fpm_worker_pool.h index afdf5ae12a..63aff9a55a 100644 --- a/sapi/fpm/fpm/fpm_worker_pool.h +++ b/sapi/fpm/fpm/fpm_worker_pool.h @@ -26,7 +26,6 @@ struct fpm_worker_pool_s { enum fpm_address_domain listen_address_domain; int listening_socket; int set_uid, set_gid; /* config uid and gid */ - unsigned is_template:1; /* just config template, no processes will be created */ int socket_uid, socket_gid, socket_mode; struct fpm_shm_s *shm_list; diff --git a/sapi/fpm/fpm/xml_config.c b/sapi/fpm/fpm/xml_config.c deleted file mode 100644 index 9990de6961..0000000000 --- a/sapi/fpm/fpm/xml_config.c +++ /dev/null @@ -1,275 +0,0 @@ - - /* $Id: xml_config.c,v 1.9 2008/08/26 15:09:15 anight Exp $ */ - /* (c) 2004-2007 Andrei Nigmatulin */ - -#include "fpm_config.h" - -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#endif -#include <string.h> -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> - -#include <libxml/parser.h> -#include <libxml/tree.h> - -#include "xml_config.h" - -static struct xml_conf_section **xml_conf_sections = 0; -static int xml_conf_sections_allocated = 0; -static int xml_conf_sections_used = 0; - -char *xml_conf_set_slot_boolean(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ -{ - char *value = vv; - long value_y = !strcasecmp(value, "yes") || !strcmp(value, "1") || !strcasecmp(value, "on") || !strcasecmp(value, "true"); - long value_n = !strcasecmp(value, "no") || !strcmp(value, "0") || !strcasecmp(value, "off") || !strcasecmp(value, "false"); - - if (!value_y && !value_n) { - return "xml_conf_set_slot(): invalid boolean value"; - } - -#ifdef XML_CONF_DEBUG - fprintf(stderr, "setting boolean '%s' => %s\n", name, value_y ? "TRUE" : "FALSE"); -#endif - - * (int *) ((char *) *conf + offset) = value_y ? 1 : 0; - return NULL; -} -/* }}} */ - -char *xml_conf_set_slot_string(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ -{ - char *value = vv; - char *v = strdup(value); - - if (!v) { - return "xml_conf_set_slot_string(): strdup() failed"; - } - -#ifdef XML_CONF_DEBUG - fprintf(stderr, "setting string '%s' => '%s'\n", name, v); -#endif - - * (char **) ((char *) *conf + offset) = v; - return NULL; -} -/* }}} */ - -char *xml_conf_set_slot_integer(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ -{ - char *value = vv; - int v = atoi(value); - - * (int *) ((char *) *conf + offset) = v; - -#ifdef XML_CONF_DEBUG - fprintf(stderr, "setting integer '%s' => %d\n", name, v); -#endif - return NULL; -} -/* }}} */ - -char *xml_conf_set_slot_time(void **conf, char *name, void *vv, intptr_t offset) /* {{{ */ -{ - char *value = vv; - int len = strlen(value); - char suffix; - int seconds; - - if (!len) { - return "xml_conf_set_slot_timeval(): invalid timeval value"; - } - - suffix = value[len-1]; - value[len-1] = '\0'; - switch (suffix) { - case 's' : - seconds = atoi(value); - break; - case 'm' : - seconds = 60 * atoi(value); - break; - case 'h' : - seconds = 60 * 60 * atoi(value); - break; - case 'd' : - seconds = 24 * 60 * 60 * atoi(value); - break; - default : - return "xml_conf_set_slot_timeval(): unknown suffix used in timeval value"; - } - - * (int *) ((char *) *conf + offset) = seconds; - -#ifdef XML_CONF_DEBUG - fprintf(stderr, "setting time '%s' => %d:%02d:%02d:%02d\n", name, expand_dhms(seconds)); -#endif - return NULL; -} -/* }}} */ - -char *xml_conf_parse_section(void **conf, struct xml_conf_section *section, void *xml_node) /* {{{ */ -{ - xmlNode *element = xml_node; - char *ret = 0; - -#ifdef XML_CONF_DEBUG - fprintf(stderr, "processing a section %s\n", section->path); -#endif - - for ( ; element; element = element->next) { - if (element->type == XML_ELEMENT_NODE && !strcmp((const char *) element->name, "value") && element->children) { - xmlChar *name = xmlGetProp(element, (unsigned char *) "name"); - - if (name) { - int i; - -#ifdef XML_CONF_DEBUG - fprintf(stderr, "found a value: %s\n", name); -#endif - for (i = 0; section->parsers[i].parser; i++) { - if (!section->parsers[i].name || !strcmp(section->parsers[i].name, (char *) name)) { - break; - } - } - - if (section->parsers[i].parser) { - if (section->parsers[i].type == XML_CONF_SCALAR) { - if (element->children->type == XML_TEXT_NODE) { - ret = section->parsers[i].parser(conf, (char *) name, element->children->content, section->parsers[i].offset); - } else { - ret = "XML_TEXT_NODE is expected, something different is given"; - } - } else { - ret = section->parsers[i].parser(conf, (char *) name, element->children, section->parsers[i].offset); - } - - xmlFree(name); - if (ret) { - return ret; - } else { - continue; - } - } - - fprintf(stderr, "Warning, unknown setting '%s' in section '%s'\n", (char *) name, section->path); - xmlFree(name); - } - } - } - return NULL; -} -/* }}} */ - -static char *xml_conf_parse_file(xmlNode *element) /* {{{ */ -{ - char *ret = 0; - - for ( ; element; element = element->next) { - - if (element->parent && element->type == XML_ELEMENT_NODE && !strcmp((const char *) element->name, "section")) { - xmlChar *name = xmlGetProp(element, (unsigned char *) "name"); - - if (name) { - char *parent_name = (char *) xmlGetNodePath(element->parent); - char *full_name; - int i; - struct xml_conf_section *section = NULL; - -#ifdef XML_CONF_DEBUG - fprintf(stderr, "got a section: %s/%s\n", parent_name, name); -#endif - full_name = alloca(strlen(parent_name) + strlen((char *) name) + 1 + 1); - sprintf(full_name, "%s/%s", parent_name, (char *) name); - xmlFree(parent_name); - xmlFree(name); - - for (i = 0; i < xml_conf_sections_used; i++) { - if (!strcmp(xml_conf_sections[i]->path, full_name)) { - section = xml_conf_sections[i]; - } - } - - if (section) { /* found a registered section */ - void *conf = section->conf(); - ret = xml_conf_parse_section(&conf, section, element->children); - if (ret) break; - } - } - } - - if (element->children) { - ret = xml_conf_parse_file(element->children); - if (ret) break; - } - } - return ret; -} -/* }}} */ - -char *xml_conf_load_file(char *file) /* {{{ */ -{ - char *ret = 0; - xmlDoc *doc; - - LIBXML_TEST_VERSION - - doc = xmlParseFile(file); - if (doc) { - ret = xml_conf_parse_file(doc->children); - xmlFreeDoc(doc); - } else { - ret = "failed to parse conf file"; - } - xmlCleanupParser(); - return ret; -} -/* }}} */ - -int xml_conf_init() /* {{{ */ -{ - return 0; -} -/* }}} */ - -void xml_conf_clean() /* {{{ */ -{ - if (xml_conf_sections) { - free(xml_conf_sections); - } -} -/* }}} */ - -int xml_conf_section_register(struct xml_conf_section *section) /* {{{ */ -{ - if (xml_conf_sections_allocated == xml_conf_sections_used) { - int new_size = xml_conf_sections_used + 10; - void *new_ptr = realloc(xml_conf_sections, sizeof(struct xml_conf_section *) * new_size); - - if (new_ptr) { - xml_conf_sections = new_ptr; - xml_conf_sections_allocated = new_size; - } else { - fprintf(stderr, "xml_conf_section_register(): out of memory\n"); - return -1; - } - } - xml_conf_sections[xml_conf_sections_used++] = section; - return 0; -} -/* }}} */ - -int xml_conf_sections_register(struct xml_conf_section *sections[]) /* {{{ */ -{ - for ( ; sections && *sections; sections++) { - if (0 > xml_conf_section_register(*sections)) { - return -1; - } - } - return 0; -} -/* }}} */ - diff --git a/sapi/fpm/fpm/xml_config.h b/sapi/fpm/fpm/xml_config.h deleted file mode 100644 index 1534fbde9d..0000000000 --- a/sapi/fpm/fpm/xml_config.h +++ /dev/null @@ -1,47 +0,0 @@ - - /* $Id: xml_config.h,v 1.3 2008/09/18 23:02:58 anight Exp $ */ - /* (c) 2004-2007 Andrei Nigmatulin */ - -#ifndef XML_CONFIG_H -#define XML_CONFIG_H 1 - -#if HAVE_INTTYPES_H -# include <inttypes.h> -#else -# include <stdint.h> -#endif - -struct xml_value_parser; - -struct xml_value_parser { - int type; - char *name; - char *(*parser)(void **, char *, void *, intptr_t offset); - intptr_t offset; -}; - -struct xml_conf_section { - void *(*conf)(); - char *path; - struct xml_value_parser *parsers; -}; - -char *xml_conf_set_slot_boolean(void **conf, char *name, void *value, intptr_t offset); -char *xml_conf_set_slot_string(void **conf, char *name, void *value, intptr_t offset); -char *xml_conf_set_slot_integer(void **conf, char *name, void *value, intptr_t offset); -char *xml_conf_set_slot_time(void **conf, char *name, void *value, intptr_t offset); - -int xml_conf_init(); -void xml_conf_clean(); -char *xml_conf_load_file(char *file); -char *xml_conf_parse_section(void **conf, struct xml_conf_section *section, void *ve); -int xml_conf_section_register(struct xml_conf_section *section); -int xml_conf_sections_register(struct xml_conf_section *sections[]); - -#define expand_hms(value) (value) / 3600, ((value) % 3600) / 60, (value) % 60 - -#define expand_dhms(value) (value) / 86400, ((value) % 86400) / 3600, ((value) % 3600) / 60, (value) % 60 - -enum { XML_CONF_SCALAR = 1, XML_CONF_SUBSECTION = 2 }; - -#endif diff --git a/sapi/fpm/php-fpm.conf.in b/sapi/fpm/php-fpm.conf.in index ca9032754a..4d5d874752 100644 --- a/sapi/fpm/php-fpm.conf.in +++ b/sapi/fpm/php-fpm.conf.in @@ -1,216 +1,283 @@ -<?xml version="1.0" ?> -<configuration> - - All relative paths in this config are relative to php's install prefix - - <section name="global_options"> - - Pid file - <value name="pid_file">@EXPANDED_LOCALSTATEDIR@/run/php-fpm.pid</value> - - Error log file - <value name="error_log">@EXPANDED_LOCALSTATEDIR@/log/php-fpm.log</value> - - Log level - <value name="log_level">notice</value> - - When this amount of php processes exited with SIGSEGV or SIGBUS ... - <value name="emergency_restart_threshold">10</value> - - ... in a less than this interval of time, a graceful restart will be initiated. - Useful to work around accidental curruptions in accelerator's shared memory. - <value name="emergency_restart_interval">1m</value> - - Time limit on waiting child's reaction on signals from master - <value name="process_control_timeout">5s</value> - - Set to 'no' to debug fpm - <value name="daemonize">yes</value> - - </section> - - <workers> - - <section name="pool"> - - Name of pool. Used in logs and stats. - <value name="name">default</value> - - Address to accept fastcgi requests on. - Valid syntax is 'ip.ad.re.ss:port' or just 'port' or '/path/to/unix/socket' - <value name="listen_address">127.0.0.1:9000</value> - - <value name="listen_options"> - - Set listen(2) backlog - <value name="backlog">-1</value> - - Set permissions for unix socket, if one used. - In Linux read/write permissions must be set in order to allow connections from web server. - Many BSD-derrived systems allow connections regardless of permissions. - <value name="owner">@php_fpm_user@</value> - <value name="group">@php_fpm_group@</value> - <value name="mode">0666</value> - </value> - - Additional php.ini defines, specific to this pool of workers. - These settings overwrite the values previously defined in the php.ini. - Like apache, you can use php_value, php_flag, php_admin_value or php_admin_flag. - Defining 'extension' will search for the corresponding shared extension in extension_dir. - Defining 'disable_functions' or 'disable_classes' won't overwrite previously defined - php.ini value, but the new value will be append. - <value name="php_value"> - <!-- <value name="error_log">/var/log/php-error.log</value> --> - </value> - <value name="php_flag"> - <!-- <value name="log_errors">true</value> --> - </value> - <value name="php_admin_value"> - <!-- <value name="sendmail_path">/usr/sbin/sendmail -t -i</value> --> - </value> - <value name="php_admin_flag"> - <!-- <value name="display_errors">0</value> --> - </value> - - Unix user of processes - <value name="user">@php_fpm_user@</value> - - Unix group of processes - <value name="group">@php_fpm_group@</value> - - Process manager settings - <value name="pm"> - - Sets style of controling worker process count. - Valid values are 'static' and 'dynamic' - <value name="style">static</value> - - Sets the limit on the number of simultaneous requests that will be served. - Equivalent to Apache MaxClients directive. - Equivalent to PHP_FCGI_CHILDREN environment in original php.fcgi - Used with any pm_style. - <value name="max_children">50</value> - - Sets the status URI to call to obtain php-fpm status page. - If not set, no URI will be recognized as a status page. - By default, it returns text/plain looking like: - accepted conn: 12073 - pool: default - process manager: static - idle processes: 35 - active processes: 65 - total processes: 100 - "accepted conn" : the number of request accepted by the pool - "pool" : the name of the pool - "process manager": static or dynamic - "idle processes": the number of idle processes - "active processes": the number of active processes - "total processes": idle + active - The last three number are uptaded every second. - The "accepted conn" is updated in real time - *** Output *** - By default it returns text/plain - But passing as a query string html or json, it will returns - the corresponding output syntax: - http://www.foo.bar/status - http://www.foo.bar/status?json - http://www.foo.bar/status?html - *** WARNING *** - It has to start with a /. It could be named has you want. - It's maybe not a good idea to use .php extension to be certain - not to conflict with a real PHP file - <value name="status">/status</value> - - Set the ping URI to call the monitoring page of php-fpm - If not set, no URI will be recognized as a ping page. - This could be used to test from outside that php-fpm - is alive and responding: - - have a graph of php-fpm availability (rrd or such) - - remove a server from a pool if it's not responding (load balancing systems) - - trigger alerts for the operating team (24/7) - *** WARNING *** - It has to start with a /. It could be named has you want. - It's maybe not a good idea to use .php extension to be certain - not to conflict with a real PHP file - <value name="ping">/ping</value> - Set the response to custom the response of a ping request - If 'pong' is not set, the default is "pong". - The response is text/plain with a 200 response code - <value name="pong">pong</value> - - Settings group for 'dynamic' pm style - <value name="dynamic"> - - Sets the number of server processes created on startup. - Used only when 'dynamic' pm_style is selected - <value name="start_servers">20</value> - - Sets the desired minimum number of idle server processes. - Used only when 'dynamic' pm_style is selected - <value name="min_spare_servers">5</value> - - Sets the desired maximum number of idle server processes. - Used only when 'dynamic' pm_style is selected - <value name="max_spare_servers">35</value> - - </value> - - </value> - - The timeout (in seconds) for serving a single request after which the worker process will be terminated - Should be used when 'max_execution_time' ini option does not stop script execution for some reason - '0s' means 'off' - <value name="request_terminate_timeout">0s</value> - - The timeout (in seconds) for serving of single request after which a php backtrace will be dumped to slow.log file - '0s' means 'off' - <value name="request_slowlog_timeout">0s</value> - - The log file for slow requests - <value name="slowlog">@EXPANDED_LOCALSTATEDIR@/log/php-fpm.log.slow</value> - - Set open file desc rlimit - <value name="rlimit_files">1024</value> - - Set max core size rlimit - <value name="rlimit_core">0</value> - - Chroot to this directory at the start, absolute path - <value name="chroot"></value> - - Chdir to this directory at the start, absolute path - <value name="chdir"></value> - - Redirect workers' stdout and stderr into main error log. - If not set, they will be redirected to /dev/null, according to FastCGI specs - <value name="catch_workers_output">yes</value> - - How much requests each process should execute before respawn. - Useful to work around memory leaks in 3rd party libraries. - For endless request processing please specify 0 - Equivalent to PHP_FCGI_MAX_REQUESTS - <value name="max_requests">500</value> - - Comma separated list of ipv4 addresses of FastCGI clients that allowed to connect. - Equivalent to FCGI_WEB_SERVER_ADDRS environment in original php.fcgi (5.2.2+) - Makes sense only with AF_INET listening socket. - <value name="allowed_clients">127.0.0.1</value> - - Pass environment variables like LD_LIBRARY_PATH - All $VARIABLEs are taken from current environment - <value name="environment"> - <value name="HOSTNAME">$HOSTNAME</value> - <value name="PATH">/usr/local/bin:/usr/bin:/bin</value> - <value name="TMP">/tmp</value> - <value name="TMPDIR">/tmp</value> - <value name="TEMP">/tmp</value> - <value name="OSTYPE">$OSTYPE</value> - <value name="MACHTYPE">$MACHTYPE</value> - <value name="MALLOC_CHECK_">2</value> - </value> - - </section> - - </workers> - -</configuration> +; +; All relative paths in this config are relative to php's install prefix +; +; +; Include one or more files. +; If glob(3) exists, it's used to include a bunch of files from a glob(3) pattern +; This directive can be used everywhere in the file. +; +;include=@EXPANDED_SYSCONFDIR@/fpm.d/*.conf +; +; + +[global] +; Pid file +; default: none +; +;pid = @EXPANDED_LOCALSTATEDIR@/run/php-fpm.pid + +; Error log file +; default: @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log +; +;error_log = @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log + +; Log level +; alert, error, warning, notice, debug +; default: notice +; +;log_level = notice + +; When this amount of php processes exited with SIGSEGV or SIGBUS ... +; 0 means 'Off' +; default: 0 +; +;emergency_restart_threshold = 0 + +; ... in a less than this interval of time, a graceful restart will be initiated. +; Useful to work around accidental curruptions in accelerator's shared memory. +; available units are s(econd), m(inute), h(hour), or d(day) +; default : 0s +; +;emergency_restart_interval = 0s + +; Time limit on waiting child's reaction on signals from master +; available units are s(econd), m(inute), h(hour), or d(day) +; default : 0s +; +;process_control_timeout = 0s + +; send fpm to backgound (default) +; set to 'no' to keep FPM in foreground for debugging +; default : yes +; +;daemonize = yes + +; Start a new pool named 'www' +; The name is used in logs and stats +; There is no limitation of the number of pool FPM can handle. Your system will tell you anyway :) +[www] + +; Address to accept fastcgi requests on. +; Valid syntaxes are: +; - 'ip.ad.re.ss:port' to listen on a TCP scoket to the specific address on the specific port +; - 'port' to listen on a TCP socket to all addreses on the specific port +; - '/path/to/unix/socket' to listen on a unix socket +; it's mandatory +; +listen = 127.0.0.1:9000 + +; Set listen(2) backlog +; -1 means unlimited +; default : -1 +; +;listen.backlog = -1 + +; Set permissions for unix socket, if one used. +; In Linux read/write permissions must be set in order to allow connections from web server. +; Many BSD-derrived systems allow connections regardless of permissions. +; default: user and group are set as the running user. Mode is set to 0666 +; +;listen.owner = @php_fpm_user@ +;listen.group = @php_fpm_group@ +;listen.mode = 0666 + +; Unix user/group of processes +; The user is mandatory. If the group is not set, the default user's group +; will be used +user = @php_fpm_user@ +group = @php_fpm_group@ + +; Choose the process manager which control how processes are managed +; Two choices: +; - static : a fixed number (pm.max_children) of child processes +; - dynamic : The number of child processes are set up dynamically depending on the following directives +; - pm.max_children : the maximum number of children that can be alive at the same time +; - pm.start_servers : the number of children created on startup +; - pm.min_spare_servers : the minimum number of children in 'idle' state (waiting to precess). +; If the number of 'idle' processes is less than this number, +; some children will be created. +; - pm.max_spare_servers : the maximum number of children in 'idle' state (waiting to precess). +; If the number of 'idle' processes is greater than this number, +; some children will be killed; +; It's mandatory +pm = dynamic + +; Sets the limit on the number of simultaneous requests (children processes will be forked) that will be served. +; Equivalent to Apache MaxClients directive (with mpm_prefork). +; Equivalent to PHP_FCGI_CHILDREN environment in original php.fcgi +; Used with any pm.style. +; It's mandatory +; +pm.max_children = 50 + +; Sets the number of server processes created on startup. +; Used only with 'dynamic' pm.style +; default : min_spare + (max_spare - min_spare) / 2 +; +;pm.start_servers = 20 + +; Sets the desired minimum number of idle server processes. +; Used only with 'dynamic' pm.style +; It's mandatory when pm is set to dynamic +; +;pm.min_spare_servers = 5 + +; Sets the desired maximum number of idle server processes. +; Used only with 'dynamic' pm.style +; It's mandatory when pm is set to dynamic +; +;pm.max_spare_servers = 35 + +; How much requests each process should execute before respawn. +; Useful to work around memory leaks in 3rd party libraries. +; For endless request processing please specify 0 +; Equivalent to PHP_FCGI_MAX_REQUESTS +; default : 0 +; +;max_requests = 500 + +; Sets the status URI to call to obtain php-fpm status page. +; If not set, no URI will be recognized as a status page. +; By default, it returns text/plain looking like: +; accepted conn: 12073 +; pool: default +; process manager: static +; idle processes: 35 +; active processes: 65 +; total processes: 100 +; "accepted conn" : the number of request accepted by the pool +; "pool" : the name of the pool +; "process manager": static or dynamic +; "idle processes": the number of idle processes +; "active processes": the number of active processes +; "total processes": idle + active +; The last three number are uptaded every second. +; The "accepted conn" is updated in real time +; *** Output *** +; By default it returns text/plain +; But passing as a query string html or json, it will returns +; the corresponding output syntax: +; http://www.foo.bar/status +; http://www.foo.bar/status?json +; http://www.foo.bar/status?html +; *** WARNING *** +; It has to start with a /. It could be named has you want. +; It's maybe not a good idea to use .php extension to be certain +; not to conflict with a real PHP file +; +; default: not set +; +;pm.status_path = /status + +; Set the ping URI to call the monitoring page of php-fpm +; If not set, no URI will be recognized as a ping page. +; This could be used to test from outside that php-fpm +; is alive and responding: +; - have a graph of php-fpm availability (rrd or such) +; - remove a server from a pool if it's not responding (load balancing systems) +; - trigger alerts for the operating team (24/7) +; *** WARNING *** +; It has to start with a /. It could be named has you want. +; It's maybe not a good idea to use .php extension to be certain +; not to conflict with a real PHP file +; +; default: not set +; +;ping.path = /ping + +; Set the response to custom the response of a ping request +; If 'pong' is not set, the default is "pong". +; The response is text/plain with a 200 response code +; +; default: pong +; +;pong.response = pong + +; The timeout (in seconds) for serving a single request after which the worker process will be terminated +; Should be used when 'max_execution_time' ini option does not stop script execution for some reason +; '0' means 'off' +; available units are s(econd), m(inute), h(hour), or d(day) +; default: 0 +; +;request_terminate_timeout = 0s + +; The timeout (in seconds) for serving of single request after which a php backtrace will be dumped to slow.log file +; '0s' means 'off' +; available units are s(econd), m(inute), h(hour), or d(day) +; +;request_slowlog_timeout = 0s + +; The log file for slow requests +; default: @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log.slow +; +;slowlog = @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log.slow + +; Set open file desc rlimit +; default: system defined value +; +;rlimit_files = 1024 + +; Set max core size rlimit +; It could be +; - unlimited +; - an integer greater or equal to 0 +; default: system defined value +; +;rlimit_core = 0 + +; Chroot to this directory at the start, absolute path +; *** WARNING *** +; chrooting is a great security features and should be used whenever it's possible. +; However, all php path will be related to the chroot (error_log, sessions.save_path, ...) +; When not set, chroot is not used +; default: not set +; +;chroot = + +; Chdir to this directory at the start, absolute path +; default: current directory or / when chroot +; +;chdir = /var/www + +; Redirect workers' stdout and stderr into main error log. +; If not set, they will be redirected to /dev/null, according to FastCGI specs +; default: no +; +;catch_workers_output = yes + +; List of ipv4 addresses of FastCGI clients that allowed to connect. +; Equivalent to FCGI_WEB_SERVER_ADDRS environment in original php.fcgi (5.2.2+) +; Makes sense only with a tcp listening socket. +; Each addresses must be separated by a comma +; default: any +; +;listen.allowed_client = 127.0.0.1 + +; Pass environment variables like LD_LIBRARY_PATH +; All $VARIABLEs are taken from current environment +; default: clean env +; +;env[HOSTNAME] = $HOSTNAME +;env[PATH] = /usr/local/bin:/usr/bin:/bin +;env[TMP] = /tmp +;env[TMPDIR] = /tmp +;env[TEMP] = /tmp + +; Additional php.ini defines, specific to this pool of workers. +; These settings overwrite the values previously defined in the php.ini. +; The directives are the same as the php sapi: +; - php_value/php_flag: you can set classic ini defines which can be overwriten from PHP call 'ini_set'. +; - php_admin_value/php_admin_flag: those directives won't be overwriten by PHP call 'ini_set' +; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no +; +; Defining 'extension' will load the corresponding shared extension from extension_dir. +; Defining 'disable_functions' or 'disable_classes' won't overwrite previously defined +; php.ini value, but the new value will be append. +; +; default: nothing is defined but the ones in php.ini and at startup with the -d arguement +; +;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -fpool1@my.domain.com +;php_flag[display_errors] = off +;php_admin_value[error_log] = /var/log/fpm-php.www.log +;php_admin_value[log_errors] = on +;php_admin_value[memory_limit] = 32M |