fat Sun, 14 Nov 2010 22:01:34 +0000
Revision: http://svn.php.net/viewvc?view=revision&revision=305341
Log:
- Fixed #52691 (allow multiple instance of FPM using a custom prefix)
Bug: http://bugs.php.net/52691 (Analyzed) allow multiple instance of FPM using
a custom prefix
Changed paths:
U php/php-src/branches/PHP_5_3/NEWS
U php/php-src/branches/PHP_5_3/sapi/fpm/config.m4
U php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm.c
U php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm.h
U php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_conf.c
U php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_conf.h
U php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_main.c
U php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_php.h
U php/php-src/branches/PHP_5_3/sapi/fpm/php-fpm.8.in
U php/php-src/branches/PHP_5_3/sapi/fpm/php-fpm.conf.in
U php/php-src/trunk/sapi/fpm/config.m4
U php/php-src/trunk/sapi/fpm/fpm/fpm.c
U php/php-src/trunk/sapi/fpm/fpm/fpm.h
U php/php-src/trunk/sapi/fpm/fpm/fpm_conf.c
U php/php-src/trunk/sapi/fpm/fpm/fpm_conf.h
U php/php-src/trunk/sapi/fpm/fpm/fpm_main.c
U php/php-src/trunk/sapi/fpm/fpm/fpm_php.h
U php/php-src/trunk/sapi/fpm/php-fpm.8.in
U php/php-src/trunk/sapi/fpm/php-fpm.conf.in
Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/NEWS 2010-11-14 22:01:34 UTC (rev 305341)
@@ -14,6 +14,8 @@
(Andrey)
- Improved support for is_link and related functions on Windows. (Pierre)
+- Added '-p/--prefix' to php-fpm to use a custom prefix and run multiple
+ instances. (fat)
- Added support for the ( and ) delimiters/separators to
DateTime::createFromFormat(). (Derick)
- Added custom process title for FPM. (fat)
Modified: php/php-src/branches/PHP_5_3/sapi/fpm/config.m4
===================================================================
--- php/php-src/branches/PHP_5_3/sapi/fpm/config.m4 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/sapi/fpm/config.m4 2010-11-14 22:01:34 UTC (rev 305341)
@@ -603,6 +603,8 @@
PHP_SUBST_OLD(php_fpm_sysconfdir)
php_fpm_localstatedir=`eval echo $localstatedir`
PHP_SUBST_OLD(php_fpm_localstatedir)
+ php_fpm_prefix=`eval echo $prefix`
+ PHP_SUBST_OLD(php_fpm_prefix)
AC_DEFINE_UNQUOTED(PHP_FPM_USER, "$php_fpm_user", [fpm user name])
AC_DEFINE_UNQUOTED(PHP_FPM_GROUP, "$php_fpm_group", [fpm group name])
Modified: php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm.c
===================================================================
--- php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm.c 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm.c 2010-11-14 22:01:34 UTC (rev 305341)
@@ -23,11 +23,12 @@
struct fpm_globals_s fpm_globals;
-int fpm_init(int argc, char **argv, char *config, struct event_base **base) /* {{{ */
+int fpm_init(int argc, char **argv, char *config, char *prefix, struct event_base **base) /* {{{ */
{
fpm_globals.argc = argc;
fpm_globals.argv = argv;
fpm_globals.config = config;
+ fpm_globals.prefix = prefix;
if (0 > fpm_php_init_main() ||
0 > fpm_stdio_init_main() ||
Modified: php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm.h
===================================================================
--- php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm.h 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm.h 2010-11-14 22:01:34 UTC (rev 305341)
@@ -10,13 +10,14 @@
#include <event.h>
int fpm_run(int *max_requests, struct event_base *base);
-int fpm_init(int argc, char **argv, char *config, struct event_base **base);
+int fpm_init(int argc, char **argv, char *config, char *prefix, struct event_base **base);
struct fpm_globals_s {
pid_t parent_pid;
int argc;
char **argv;
char *config;
+ char *prefix;
int running_children;
int error_log_fd;
int log_level;
Modified: php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_conf.c
===================================================================
--- php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_conf.c 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_conf.c 2010-11-14 22:01:34 UTC (rev 305341)
@@ -74,6 +74,7 @@
};
static struct ini_value_parser_s ini_fpm_pool_options[] = {
+ { "prefix", &fpm_conf_set_string, WPO(prefix) },
{ "user", &fpm_conf_set_string, WPO(user) },
{ "group", &fpm_conf_set_string, WPO(group) },
{ "chroot", &fpm_conf_set_string, WPO(chroot) },
@@ -114,6 +115,29 @@
}
/* }}} */
+static int fpm_conf_expand_pool_name(char **value) {
+ char *token;
+
+ if (!value || !*value) {
+ return 0;
+ }
+
+ while ((token = strstr(*value, "$pool"))) {
+ char *buf;
+ char *p1 = *value;
+ char *p2 = token + strlen("$pool");
+ if (!current_wp || !current_wp->config || !current_wp->config->name) {
+ return -1;
+ }
+ token[0] = '\0';
+ spprintf(&buf, 0, "%s%s%s", p1, current_wp->config->name, p2);
+ *value = strdup(buf);
+ efree(buf);
+ }
+
+ return 0;
+}
+
static char *fpm_conf_set_boolean(zval *value, void **config, intptr_t offset) /* {{{ */
{
char *val = Z_STRVAL_P(value);
@@ -141,6 +165,9 @@
if (!new) {
return "fpm_conf_set_string(): strdup() failed";
}
+ if (fpm_conf_expand_pool_name(&new) == -1) {
+ return "Can't use '$pool' when the pool is not defined";
+ }
*old = new;
return NULL;
@@ -295,6 +322,9 @@
kv->value = strdup(b ? "On" : "Off");
} else {
kv->value = strdup(Z_STRVAL_P(value));
+ if (fpm_conf_expand_pool_name(&kv->value) == -1) {
+ return "Can't use '$pool' when the pool is not defined";
+ }
}
if (!kv->value) {
@@ -381,27 +411,68 @@
free(wpc->chroot);
free(wpc->chdir);
free(wpc->slowlog);
+ free(wpc->prefix);
return 0;
}
/* }}} */
-static int fpm_evaluate_full_path(char **path) /* {{{ */
+static int fpm_evaluate_full_path(char **path, struct fpm_worker_pool_s *wp, char *default_prefix, int expand) /* {{{ */
{
- if (**path != '/') {
- char *full_path;
+ char *prefix = NULL;
+ char *full_path;
- full_path = malloc(sizeof(PHP_PREFIX) + strlen(*path) + 1);
+ if (!path || !*path || **path == '/') {
+ return 0;
+ }
- if (!full_path) {
- return -1;
+ if (wp && wp->config) {
+ prefix = wp->config->prefix;
+ }
+
+ /* if the wp prefix is not set */
+ if (prefix == NULL) {
+ prefix = fpm_globals.prefix;
+ }
+
+ /* if the global prefix is not set */
+ if (prefix == NULL) {
+ prefix = default_prefix ? default_prefix : PHP_PREFIX;
+ }
+
+ if (expand) {
+ char *tmp;
+ tmp = strstr(*path, "$prefix");
+ if (tmp != NULL) {
+
+ if (tmp != *path) {
+ zlog(ZLOG_ERROR, "'$prefix' must be use at the begining of the value");
+ return -1;
+ }
+
+ if (strlen(*path) > strlen("$prefix")) {
+ free(*path);
+ tmp = strdup((*path) + strlen("$prefix"));
+ *path = tmp;
+ } else {
+ free(*path);
+ *path = NULL;
+ }
}
+ }
- sprintf(full_path, "%s/%s", PHP_PREFIX, *path);
+ if (*path) {
+ spprintf(&full_path, 0, "%s/%s", prefix, *path);
free(*path);
- *path = full_path;
+ *path = strdup(full_path);
+ efree(full_path);
+ } else {
+ *path = strdup(prefix);
}
+ if (**path != '/' && wp != NULL && wp->config) {
+ return fpm_evaluate_full_path(path, NULL, default_prefix, expand);
+ }
return 0;
}
/* }}} */
@@ -417,11 +488,20 @@
for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
+ if (wp->config->prefix && *wp->config->prefix) {
+ fpm_evaluate_full_path(&wp->config->prefix, NULL, NULL, 0);
+
+ if (!fpm_conf_is_dir(wp->config->prefix)) {
+ zlog(ZLOG_ERROR, "[pool %s] the prefix '%s' does not exist or is not a directory", wp->config->name, wp->config->prefix);
+ return -1;
+ }
+ }
+
if (wp->config->listen_address && *wp->config->listen_address) {
wp->listen_address_domain = fpm_sockets_domain_from_address(wp->config->listen_address);
if (wp->listen_address_domain == FPM_AF_UNIX && *wp->config->listen_address != '/') {
- fpm_evaluate_full_path(&wp->config->listen_address);
+ fpm_evaluate_full_path(&wp->config->listen_address, wp, NULL, 0);
}
} else {
zlog(ZLOG_ALERT, "[pool %s] no listen address have been defined!", wp->config->name);
@@ -478,6 +558,9 @@
}
+ if (wp->config->slowlog && *wp->config->slowlog) {
+ fpm_evaluate_full_path(&wp->config->slowlog, wp, NULL, 0);
+ }
if (wp->config->request_slowlog_timeout) {
#if HAVE_FPM_TRACE
@@ -495,14 +578,10 @@
wp->config->request_slowlog_timeout = 0;
#endif
- }
- if (wp->config->request_slowlog_timeout && wp->config->slowlog && *wp->config->slowlog) {
- int fd;
+ if (wp->config->slowlog && *wp->config->slowlog) {
+ int fd;
- fpm_evaluate_full_path(&wp->config->slowlog);
-
- if (wp->config->request_slowlog_timeout) {
fd = open(wp->config->slowlog, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
if (0 > fd) {
@@ -583,6 +662,9 @@
}
if (wp->config->chroot && *wp->config->chroot) {
+
+ fpm_evaluate_full_path(&wp->config->chroot, wp, NULL, 1);
+
if (*wp->config->chroot != '/') {
zlog(ZLOG_ERROR, "[pool %s] the chroot path '%s' must start with a '/'", wp->config->name, wp->config->chroot);
return -1;
@@ -594,6 +676,9 @@
}
if (wp->config->chdir && *wp->config->chdir) {
+
+ fpm_evaluate_full_path(&wp->config->chdir, wp, NULL, 0);
+
if (*wp->config->chdir != '/') {
zlog(ZLOG_ERROR, "[pool %s] the chdir path '%s' must start with a '/'", wp->config->name, wp->config->chdir);
return -1;
@@ -601,21 +686,16 @@
if (wp->config->chroot) {
char *buf;
- size_t len;
- len = strlen(wp->config->chroot) + strlen(wp->config->chdir) + 1;
- buf = malloc(sizeof(char) * len);
- if (!buf) {
- zlog(ZLOG_SYSERROR, "[pool %s] malloc() failed", wp->config->name);
- return -1;
- }
- snprintf(buf, len, "%s%s", wp->config->chroot, wp->config->chdir);
+ spprintf(&buf, 0, "%s/%s", wp->config->chroot, wp->config->chdir);
+
if (!fpm_conf_is_dir(buf)) {
zlog(ZLOG_ERROR, "[pool %s] the chdir path '%s' within the chroot path '%s' ('%s') does not exist or is not a directory", wp->config->name, wp->config->chdir, wp->config->chroot, buf);
- free(buf);
+ efree(buf);
return -1;
}
- free(buf);
+
+ efree(buf);
} else {
if (!fpm_conf_is_dir(wp->config->chdir)) {
zlog(ZLOG_ERROR, "[pool %s] the chdir path '%s' does not exist or is not a directory", wp->config->name, wp->config->chdir);
@@ -623,6 +703,26 @@
}
}
}
+ if (!wp->config->chroot) {
+ struct key_value_s *kv;
+ char *options[] = FPM_PHP_INI_TO_EXPAND;
+ char **p;
+
+ for (kv = wp->config->php_values; kv; kv = kv->next) {
+ for (p=options; *p; p++) {
+ if (!strcasecmp(kv->key, *p)) {
+ fpm_evaluate_full_path(&kv->value, wp, NULL, 0);
+ }
+ }
+ }
+ for (kv = wp->config->php_admin_values; kv; kv = kv->next) {
+ for (p=options; *p; p++) {
+ if (!strcasecmp(kv->key, *p)) {
+ fpm_evaluate_full_path(&kv->value, wp, NULL, 0);
+ }
+ }
+ }
+ }
}
return 0;
}
@@ -671,18 +771,14 @@
static int fpm_conf_post_process() /* {{{ */
{
if (fpm_global_config.pid_file) {
- fpm_evaluate_full_path(&fpm_global_config.pid_file);
+ fpm_evaluate_full_path(&fpm_global_config.pid_file, NULL, PHP_LOCALSTATEDIR, 0);
}
if (!fpm_global_config.error_log) {
- char *tmp_log_path;
-
- spprintf(&tmp_log_path, 0, "%s/log/php-fpm.log", PHP_LOCALSTATEDIR);
- fpm_global_config.error_log = strdup(tmp_log_path);
- efree(tmp_log_path);
+ fpm_global_config.error_log = strdup("log/php-fpm.log");
}
- fpm_evaluate_full_path(&fpm_global_config.error_log);
+ fpm_evaluate_full_path(&fpm_global_config.error_log, NULL, PHP_LOCALSTATEDIR, 0);
if (0 > fpm_stdio_open_error_log(0)) {
return -1;
@@ -990,7 +1086,7 @@
if (ini_include) {
char *tmp = ini_include;
ini_include = NULL;
- fpm_evaluate_full_path(&tmp);
+ fpm_evaluate_full_path(&tmp, NULL, NULL, 0);
fpm_conf_ini_parser_include(tmp, &error TSRMLS_CC);
if (error) {
free(tmp);
@@ -1014,10 +1110,23 @@
int ret;
TSRMLS_FETCH();
+ if (fpm_globals.prefix && *fpm_globals.prefix) {
+ if (!fpm_conf_is_dir(fpm_globals.prefix)) {
+ zlog(ZLOG_ERROR, "the global prefix '%s' does not exist or is not a directory", fpm_globals.prefix);
+ return -1;
+ }
+ }
+
if (fpm_globals.config == NULL) {
- spprintf(&fpm_globals.config, 0, "%s/php-fpm.conf", PHP_SYSCONFDIR);
+
+ if (fpm_globals.prefix == NULL) {
+ spprintf(&fpm_globals.config, 0, "%s/php-fpm.conf", PHP_SYSCONFDIR);
+ } else {
+ spprintf(&fpm_globals.config, 0, "%s/etc/php-fpm.conf", fpm_globals.prefix);
+ }
+
if (!fpm_globals.config) {
- zlog(ZLOG_SYSERROR, "spprintf() failed (\"%s/php-fpm.conf\")", PHP_SYSCONFDIR);
+ zlog(ZLOG_SYSERROR, "spprintf() failed (fpm_globals.config)");
return -1;
}
}
Modified: php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_conf.h
===================================================================
--- php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_conf.h 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_conf.h 2010-11-14 22:01:34 UTC (rev 305341)
@@ -31,6 +31,7 @@
struct fpm_worker_pool_config_s {
char *name;
+ char *prefix;
char *user;
char *group;
char *chroot;
Modified: php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_main.c
===================================================================
--- php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_main.c 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_main.c 2010-11-14 22:01:34 UTC (rev 305341)
@@ -153,6 +153,7 @@
{'v', 0, "version"},
{'y', 1, "fpm-config"},
{'t', 0, "test"},
+ {'p', 1, "prefix"},
{'-', 0, NULL} /* end of args */
};
@@ -960,7 +961,7 @@
prog = "php";
}
- php_printf( "Usage: %s [-n] [-e] [-h] [-i] [-m] [-v] [-t] [-c <file>] [-d foo[=bar]] [-y <file>]\n"
+ php_printf( "Usage: %s [-n] [-e] [-h] [-i] [-m] [-v] [-t] [-p <prefix> ] [-c <file>] [-d foo[=bar]] [-y <file>]\n"
" -c <path>|<file> Look for php.ini file in this directory\n"
" -n No php.ini file will be used\n"
" -d foo[=bar] Define INI entry foo with value 'bar'\n"
@@ -969,10 +970,12 @@
" -i PHP information\n"
" -m Show compiled in modules\n"
" -v Version number\n"
+ " -p, --prefix <dir>\n"
+ " Specify alternative prefix path to FastCGI process manager (default: %s).\n"
" -y, --fpm-config <file>\n"
" Specify alternative path to FastCGI process manager config file.\n"
" -t, --test Test FPM configuration and exit\n",
- prog);
+ prog, PHP_PREFIX);
}
/* }}} */
@@ -1549,6 +1552,7 @@
int fcgi_fd = 0;
fcgi_request request;
char *fpm_config = NULL;
+ char *fpm_prefix = NULL;
fcgi_init();
@@ -1586,9 +1590,11 @@
}
cgi_sapi_module.php_ini_path_override = strdup(php_optarg);
break;
+
case 'n':
cgi_sapi_module.php_ini_ignore = 1;
break;
+
case 'd': {
/* define ini entries on command line */
int len = strlen(php_optarg);
@@ -1620,10 +1626,15 @@
}
break;
}
+
case 'y':
fpm_config = php_optarg;
break;
+ case 'p':
+ fpm_prefix = php_optarg;
+ break;
+
case 'e': /* enable extended info output */
CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
break;
@@ -1768,7 +1779,7 @@
}
}
- if (0 > fpm_init(argc, argv, fpm_config ? fpm_config : CGIG(fpm_config), &CGIG(event_base))) {
+ if (0 > fpm_init(argc, argv, fpm_config ? fpm_config : CGIG(fpm_config), fpm_prefix, &CGIG(event_base))) {
return FAILURE;
}
Modified: php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_php.h
===================================================================
--- php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_php.h 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/sapi/fpm/fpm/fpm_php.h 2010-11-14 22:01:34 UTC (rev 305341)
@@ -11,6 +11,26 @@
#include "build-defs.h" /* for PHP_ defines */
#include "fpm/fpm_conf.h"
+#define FPM_PHP_INI_TO_EXPAND \
+ { \
+ "error_log", \
+ "extension_dir", \
+ "mime_magic.magicfile", \
+ "sendmail_path", \
+ "session.cookie_path", \
+ "session_pgsql.sem_file_name", \
+ "soap.wsdl_cache_dir", \
+ "uploadprogress.file.filename_template", \
+ "xdebug.output_dir", \
+ "xdebug.profiler_output_dir", \
+ "xdebug.trace_output_dir", \
+ "xmms.path", \
+ "axis2.client_home", \
+ "blenc.key_file", \
+ "coin_acceptor.device", \
+ NULL \
+ }
+
struct fpm_worker_pool_s;
int fpm_php_init_child(struct fpm_worker_pool_s *wp);
Modified: php/php-src/branches/PHP_5_3/sapi/fpm/php-fpm.8.in
===================================================================
--- php/php-src/branches/PHP_5_3/sapi/fpm/php-fpm.8.in 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/sapi/fpm/php-fpm.8.in 2010-11-14 22:01:34 UTC (rev 305341)
@@ -77,7 +77,12 @@
.PD 1
.B \-v
Version number
+.B \-\-prefix \fIpath\fP
.TP
+.PD 1
+.B \-p
+Specify alternative prefix path (the default is @php_fpm_prefix@)
+.TP
.PD 0
.B \-\-fpm\-config \fIfile\fP
.TP
Modified: php/php-src/branches/PHP_5_3/sapi/fpm/php-fpm.conf.in
===================================================================
--- php/php-src/branches/PHP_5_3/sapi/fpm/php-fpm.conf.in 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/branches/PHP_5_3/sapi/fpm/php-fpm.conf.in 2010-11-14 22:01:34 UTC (rev 305341)
@@ -3,12 +3,16 @@
;;;;;;;;;;;;;;;;;;;;;
; All relative paths in this configuration file are relative to PHP's install
-; prefix.
+; prefix (@prefix@). This prefix can be dynamicaly changed by using the
+; '-p' argument from the command line.
; Include one or more files. If glob(3) exists, it is used to include a bunch of
; files from a glob(3) pattern. This directive can be used everywhere in the
; file.
-;inclu...@expanded_sysconfdir@/fpm.d/*.conf
+; Relative path can also be used. They will be prefixed by:
+; - the global prefix if it's been set (-p arguement)
+; - @prefix@ otherwise
+;include=etc/fpm.d/*.conf
;;;;;;;;;;;;;;;;;;
; Global Options ;
@@ -16,12 +20,14 @@
[global]
; Pid file
+; Note: the default prefix is @EXPANDED_LOCALSTATEDIR@
; Default Value: none
-;pid = @EXPANDED_LOCALSTATEDIR@/run/php-fpm.pid
+;pid = run/php-fpm.pid
; Error log file
-; Default Value: @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log
-;error_log = @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log
+; Note: the default prefix is @EXPANDED_LOCALSTATEDIR@
+; Default Value: log/php-fpm.log
+;error_log = log/php-fpm.log
; Log level
; Possible Values: alert, error, warning, notice, debug
@@ -62,8 +68,23 @@
; FPM can handle. Your system will tell you anyway :)
; Start a new pool named 'www'.
+; the variable $pool can we used in any directive and will be replaced by the
+; pool name ('www' here)
[www]
+; Per pool prefix
+; It only applies on the following directives:
+; - 'slowlog'
+; - 'listen' (unixsocket)
+; - 'chroot'
+; - 'chdir'
+; - 'php_values'
+; - 'php_admin_values'
+; When not set, the global prefix (or @php_fpm_prefix@) applies instead.
+; Note: This directive can also be relative to the global prefix.
+; Default Value: none
+;prefix = /path/to/pools/$pool
+
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
@@ -218,7 +239,7 @@
; The log file for slow requests
; Default Value: not set
; Note: slowlog is mandatory if request_slowlog_timeout is set
-;slowlog = @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log.slow
+;slowlog = log/$pool.log.slow
; Set open file descriptor rlimit.
; Default Value: system defined value
@@ -231,13 +252,17 @@
; Chroot to this directory at the start. This value must be defined as an
; absolute path. When this value is not set, chroot is not used.
+; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
+; of its subdirectories. If the pool prefix is not set, the global prefix
+; will be used instead.
; Note: chrooting is a great security feature and should be used whenever
; possible. However, all PHP paths will be relative to the chroot
; (error_log, sessions.save_path, ...).
; Default Value: not set
;chroot =
-; Chdir to this directory at the start. This value must be an absolute path.
+; Chdir to this directory at the start.
+; Note: relative path can be used.
; Default Value: current directory or / when chroot
;chdir = /var/www
@@ -269,6 +294,9 @@
; overwrite previously defined php.ini values, but will append the new value
; instead.
+; Note: path INI options can be relative and will be expanded with the prefix
+; (pool, global or @prefix@)
+
; Default Value: nothing is defined by default except the values in php.ini and
; specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f [email protected]
Modified: php/php-src/trunk/sapi/fpm/config.m4
===================================================================
--- php/php-src/trunk/sapi/fpm/config.m4 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/trunk/sapi/fpm/config.m4 2010-11-14 22:01:34 UTC (rev 305341)
@@ -603,6 +603,8 @@
PHP_SUBST_OLD(php_fpm_sysconfdir)
php_fpm_localstatedir=`eval echo $localstatedir`
PHP_SUBST_OLD(php_fpm_localstatedir)
+ php_fpm_prefix=`eval echo $prefix`
+ PHP_SUBST_OLD(php_fpm_prefix)
AC_DEFINE_UNQUOTED(PHP_FPM_USER, "$php_fpm_user", [fpm user name])
AC_DEFINE_UNQUOTED(PHP_FPM_GROUP, "$php_fpm_group", [fpm group name])
Modified: php/php-src/trunk/sapi/fpm/fpm/fpm.c
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/fpm.c 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/trunk/sapi/fpm/fpm/fpm.c 2010-11-14 22:01:34 UTC (rev 305341)
@@ -23,11 +23,12 @@
struct fpm_globals_s fpm_globals;
-int fpm_init(int argc, char **argv, char *config, struct event_base **base) /* {{{ */
+int fpm_init(int argc, char **argv, char *config, char *prefix, struct event_base **base) /* {{{ */
{
fpm_globals.argc = argc;
fpm_globals.argv = argv;
fpm_globals.config = config;
+ fpm_globals.prefix = prefix;
if (0 > fpm_php_init_main() ||
0 > fpm_stdio_init_main() ||
Modified: php/php-src/trunk/sapi/fpm/fpm/fpm.h
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/fpm.h 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/trunk/sapi/fpm/fpm/fpm.h 2010-11-14 22:01:34 UTC (rev 305341)
@@ -10,13 +10,14 @@
#include <event.h>
int fpm_run(int *max_requests, struct event_base *base);
-int fpm_init(int argc, char **argv, char *config, struct event_base **base);
+int fpm_init(int argc, char **argv, char *config, char *prefix, struct event_base **base);
struct fpm_globals_s {
pid_t parent_pid;
int argc;
char **argv;
char *config;
+ char *prefix;
int running_children;
int error_log_fd;
int log_level;
Modified: php/php-src/trunk/sapi/fpm/fpm/fpm_conf.c
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/fpm_conf.c 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/trunk/sapi/fpm/fpm/fpm_conf.c 2010-11-14 22:01:34 UTC (rev 305341)
@@ -74,6 +74,7 @@
};
static struct ini_value_parser_s ini_fpm_pool_options[] = {
+ { "prefix", &fpm_conf_set_string, WPO(prefix) },
{ "user", &fpm_conf_set_string, WPO(user) },
{ "group", &fpm_conf_set_string, WPO(group) },
{ "chroot", &fpm_conf_set_string, WPO(chroot) },
@@ -114,6 +115,29 @@
}
/* }}} */
+static int fpm_conf_expand_pool_name(char **value) {
+ char *token;
+
+ if (!value || !*value) {
+ return 0;
+ }
+
+ while ((token = strstr(*value, "$pool"))) {
+ char *buf;
+ char *p1 = *value;
+ char *p2 = token + strlen("$pool");
+ if (!current_wp || !current_wp->config || !current_wp->config->name) {
+ return -1;
+ }
+ token[0] = '\0';
+ spprintf(&buf, 0, "%s%s%s", p1, current_wp->config->name, p2);
+ *value = strdup(buf);
+ efree(buf);
+ }
+
+ return 0;
+}
+
static char *fpm_conf_set_boolean(zval *value, void **config, intptr_t offset) /* {{{ */
{
char *val = Z_STRVAL_P(value);
@@ -141,6 +165,9 @@
if (!new) {
return "fpm_conf_set_string(): strdup() failed";
}
+ if (fpm_conf_expand_pool_name(&new) == -1) {
+ return "Can't use '$pool' when the pool is not defined";
+ }
*old = new;
return NULL;
@@ -295,6 +322,9 @@
kv->value = strdup(b ? "On" : "Off");
} else {
kv->value = strdup(Z_STRVAL_P(value));
+ if (fpm_conf_expand_pool_name(&kv->value) == -1) {
+ return "Can't use '$pool' when the pool is not defined";
+ }
}
if (!kv->value) {
@@ -381,27 +411,68 @@
free(wpc->chroot);
free(wpc->chdir);
free(wpc->slowlog);
+ free(wpc->prefix);
return 0;
}
/* }}} */
-static int fpm_evaluate_full_path(char **path) /* {{{ */
+static int fpm_evaluate_full_path(char **path, struct fpm_worker_pool_s *wp, char *default_prefix, int expand) /* {{{ */
{
- if (**path != '/') {
- char *full_path;
+ char *prefix = NULL;
+ char *full_path;
- full_path = malloc(sizeof(PHP_PREFIX) + strlen(*path) + 1);
+ if (!path || !*path || **path == '/') {
+ return 0;
+ }
- if (!full_path) {
- return -1;
+ if (wp && wp->config) {
+ prefix = wp->config->prefix;
+ }
+
+ /* if the wp prefix is not set */
+ if (prefix == NULL) {
+ prefix = fpm_globals.prefix;
+ }
+
+ /* if the global prefix is not set */
+ if (prefix == NULL) {
+ prefix = default_prefix ? default_prefix : PHP_PREFIX;
+ }
+
+ if (expand) {
+ char *tmp;
+ tmp = strstr(*path, "$prefix");
+ if (tmp != NULL) {
+
+ if (tmp != *path) {
+ zlog(ZLOG_ERROR, "'$prefix' must be use at the begining of the value");
+ return -1;
+ }
+
+ if (strlen(*path) > strlen("$prefix")) {
+ free(*path);
+ tmp = strdup((*path) + strlen("$prefix"));
+ *path = tmp;
+ } else {
+ free(*path);
+ *path = NULL;
+ }
}
+ }
- sprintf(full_path, "%s/%s", PHP_PREFIX, *path);
+ if (*path) {
+ spprintf(&full_path, 0, "%s/%s", prefix, *path);
free(*path);
- *path = full_path;
+ *path = strdup(full_path);
+ efree(full_path);
+ } else {
+ *path = strdup(prefix);
}
+ if (**path != '/' && wp != NULL && wp->config) {
+ return fpm_evaluate_full_path(path, NULL, default_prefix, expand);
+ }
return 0;
}
/* }}} */
@@ -417,11 +488,20 @@
for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
+ if (wp->config->prefix && *wp->config->prefix) {
+ fpm_evaluate_full_path(&wp->config->prefix, NULL, NULL, 0);
+
+ if (!fpm_conf_is_dir(wp->config->prefix)) {
+ zlog(ZLOG_ERROR, "[pool %s] the prefix '%s' does not exist or is not a directory", wp->config->name, wp->config->prefix);
+ return -1;
+ }
+ }
+
if (wp->config->listen_address && *wp->config->listen_address) {
wp->listen_address_domain = fpm_sockets_domain_from_address(wp->config->listen_address);
if (wp->listen_address_domain == FPM_AF_UNIX && *wp->config->listen_address != '/') {
- fpm_evaluate_full_path(&wp->config->listen_address);
+ fpm_evaluate_full_path(&wp->config->listen_address, wp, NULL, 0);
}
} else {
zlog(ZLOG_ALERT, "[pool %s] no listen address have been defined!", wp->config->name);
@@ -478,6 +558,9 @@
}
+ if (wp->config->slowlog && *wp->config->slowlog) {
+ fpm_evaluate_full_path(&wp->config->slowlog, wp, NULL, 0);
+ }
if (wp->config->request_slowlog_timeout) {
#if HAVE_FPM_TRACE
@@ -495,14 +578,10 @@
wp->config->request_slowlog_timeout = 0;
#endif
- }
- if (wp->config->request_slowlog_timeout && wp->config->slowlog && *wp->config->slowlog) {
- int fd;
+ if (wp->config->slowlog && *wp->config->slowlog) {
+ int fd;
- fpm_evaluate_full_path(&wp->config->slowlog);
-
- if (wp->config->request_slowlog_timeout) {
fd = open(wp->config->slowlog, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR);
if (0 > fd) {
@@ -583,6 +662,9 @@
}
if (wp->config->chroot && *wp->config->chroot) {
+
+ fpm_evaluate_full_path(&wp->config->chroot, wp, NULL, 1);
+
if (*wp->config->chroot != '/') {
zlog(ZLOG_ERROR, "[pool %s] the chroot path '%s' must start with a '/'", wp->config->name, wp->config->chroot);
return -1;
@@ -594,6 +676,9 @@
}
if (wp->config->chdir && *wp->config->chdir) {
+
+ fpm_evaluate_full_path(&wp->config->chdir, wp, NULL, 0);
+
if (*wp->config->chdir != '/') {
zlog(ZLOG_ERROR, "[pool %s] the chdir path '%s' must start with a '/'", wp->config->name, wp->config->chdir);
return -1;
@@ -601,21 +686,16 @@
if (wp->config->chroot) {
char *buf;
- size_t len;
- len = strlen(wp->config->chroot) + strlen(wp->config->chdir) + 1;
- buf = malloc(sizeof(char) * len);
- if (!buf) {
- zlog(ZLOG_SYSERROR, "[pool %s] malloc() failed", wp->config->name);
- return -1;
- }
- snprintf(buf, len, "%s%s", wp->config->chroot, wp->config->chdir);
+ spprintf(&buf, 0, "%s/%s", wp->config->chroot, wp->config->chdir);
+
if (!fpm_conf_is_dir(buf)) {
zlog(ZLOG_ERROR, "[pool %s] the chdir path '%s' within the chroot path '%s' ('%s') does not exist or is not a directory", wp->config->name, wp->config->chdir, wp->config->chroot, buf);
- free(buf);
+ efree(buf);
return -1;
}
- free(buf);
+
+ efree(buf);
} else {
if (!fpm_conf_is_dir(wp->config->chdir)) {
zlog(ZLOG_ERROR, "[pool %s] the chdir path '%s' does not exist or is not a directory", wp->config->name, wp->config->chdir);
@@ -623,6 +703,26 @@
}
}
}
+ if (!wp->config->chroot) {
+ struct key_value_s *kv;
+ char *options[] = FPM_PHP_INI_TO_EXPAND;
+ char **p;
+
+ for (kv = wp->config->php_values; kv; kv = kv->next) {
+ for (p=options; *p; p++) {
+ if (!strcasecmp(kv->key, *p)) {
+ fpm_evaluate_full_path(&kv->value, wp, NULL, 0);
+ }
+ }
+ }
+ for (kv = wp->config->php_admin_values; kv; kv = kv->next) {
+ for (p=options; *p; p++) {
+ if (!strcasecmp(kv->key, *p)) {
+ fpm_evaluate_full_path(&kv->value, wp, NULL, 0);
+ }
+ }
+ }
+ }
}
return 0;
}
@@ -671,18 +771,14 @@
static int fpm_conf_post_process() /* {{{ */
{
if (fpm_global_config.pid_file) {
- fpm_evaluate_full_path(&fpm_global_config.pid_file);
+ fpm_evaluate_full_path(&fpm_global_config.pid_file, NULL, PHP_LOCALSTATEDIR, 0);
}
if (!fpm_global_config.error_log) {
- char *tmp_log_path;
-
- spprintf(&tmp_log_path, 0, "%s/log/php-fpm.log", PHP_LOCALSTATEDIR);
- fpm_global_config.error_log = strdup(tmp_log_path);
- efree(tmp_log_path);
+ fpm_global_config.error_log = strdup("log/php-fpm.log");
}
- fpm_evaluate_full_path(&fpm_global_config.error_log);
+ fpm_evaluate_full_path(&fpm_global_config.error_log, NULL, PHP_LOCALSTATEDIR, 0);
if (0 > fpm_stdio_open_error_log(0)) {
return -1;
@@ -990,7 +1086,7 @@
if (ini_include) {
char *tmp = ini_include;
ini_include = NULL;
- fpm_evaluate_full_path(&tmp);
+ fpm_evaluate_full_path(&tmp, NULL, NULL, 0);
fpm_conf_ini_parser_include(tmp, &error TSRMLS_CC);
if (error) {
free(tmp);
@@ -1014,10 +1110,23 @@
int ret;
TSRMLS_FETCH();
+ if (fpm_globals.prefix && *fpm_globals.prefix) {
+ if (!fpm_conf_is_dir(fpm_globals.prefix)) {
+ zlog(ZLOG_ERROR, "the global prefix '%s' does not exist or is not a directory", fpm_globals.prefix);
+ return -1;
+ }
+ }
+
if (fpm_globals.config == NULL) {
- spprintf(&fpm_globals.config, 0, "%s/php-fpm.conf", PHP_SYSCONFDIR);
+
+ if (fpm_globals.prefix == NULL) {
+ spprintf(&fpm_globals.config, 0, "%s/php-fpm.conf", PHP_SYSCONFDIR);
+ } else {
+ spprintf(&fpm_globals.config, 0, "%s/etc/php-fpm.conf", fpm_globals.prefix);
+ }
+
if (!fpm_globals.config) {
- zlog(ZLOG_SYSERROR, "spprintf() failed (\"%s/php-fpm.conf\")", PHP_SYSCONFDIR);
+ zlog(ZLOG_SYSERROR, "spprintf() failed (fpm_globals.config)");
return -1;
}
}
Modified: php/php-src/trunk/sapi/fpm/fpm/fpm_conf.h
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/fpm_conf.h 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/trunk/sapi/fpm/fpm/fpm_conf.h 2010-11-14 22:01:34 UTC (rev 305341)
@@ -31,6 +31,7 @@
struct fpm_worker_pool_config_s {
char *name;
+ char *prefix;
char *user;
char *group;
char *chroot;
Modified: php/php-src/trunk/sapi/fpm/fpm/fpm_main.c
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/fpm_main.c 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/trunk/sapi/fpm/fpm/fpm_main.c 2010-11-14 22:01:34 UTC (rev 305341)
@@ -153,6 +153,7 @@
{'v', 0, "version"},
{'y', 1, "fpm-config"},
{'t', 0, "test"},
+ {'p', 1, "prefix"},
{'-', 0, NULL} /* end of args */
};
@@ -958,7 +959,7 @@
prog = "php";
}
- php_printf( "Usage: %s [-n] [-e] [-h] [-i] [-m] [-v] [-t] [-c <file>] [-d foo[=bar]] [-y <file>]\n"
+ php_printf( "Usage: %s [-n] [-e] [-h] [-i] [-m] [-v] [-t] [-p <prefix> ] [-c <file>] [-d foo[=bar]] [-y <file>]\n"
" -c <path>|<file> Look for php.ini file in this directory\n"
" -n No php.ini file will be used\n"
" -d foo[=bar] Define INI entry foo with value 'bar'\n"
@@ -967,10 +968,12 @@
" -i PHP information\n"
" -m Show compiled in modules\n"
" -v Version number\n"
+ " -p, --prefix <dir>\n"
+ " Specify alternative prefix path to FastCGI process manager (default: %s).\n"
" -y, --fpm-config <file>\n"
" Specify alternative path to FastCGI process manager config file.\n"
" -t, --test Test FPM configuration and exit\n",
- prog);
+ prog, PHP_PREFIX);
}
/* }}} */
@@ -1547,6 +1550,7 @@
int fcgi_fd = 0;
fcgi_request request;
char *fpm_config = NULL;
+ char *fpm_prefix = NULL;
fcgi_init();
@@ -1585,9 +1589,11 @@
}
cgi_sapi_module.php_ini_path_override = strdup(php_optarg);
break;
+
case 'n':
cgi_sapi_module.php_ini_ignore = 1;
break;
+
case 'd': {
/* define ini entries on command line */
int len = strlen(php_optarg);
@@ -1619,10 +1625,15 @@
}
break;
}
+
case 'y':
fpm_config = php_optarg;
break;
+ case 'p':
+ fpm_prefix = php_optarg;
+ break;
+
case 'e': /* enable extended info output */
CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
break;
@@ -1767,7 +1778,7 @@
}
}
- if (0 > fpm_init(argc, argv, fpm_config ? fpm_config : CGIG(fpm_config), &CGIG(event_base))) {
+ if (0 > fpm_init(argc, argv, fpm_config ? fpm_config : CGIG(fpm_config), fpm_prefix, &CGIG(event_base))) {
return FAILURE;
}
Modified: php/php-src/trunk/sapi/fpm/fpm/fpm_php.h
===================================================================
--- php/php-src/trunk/sapi/fpm/fpm/fpm_php.h 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/trunk/sapi/fpm/fpm/fpm_php.h 2010-11-14 22:01:34 UTC (rev 305341)
@@ -11,6 +11,26 @@
#include "build-defs.h" /* for PHP_ defines */
#include "fpm/fpm_conf.h"
+#define FPM_PHP_INI_TO_EXPAND \
+ { \
+ "error_log", \
+ "extension_dir", \
+ "mime_magic.magicfile", \
+ "sendmail_path", \
+ "session.cookie_path", \
+ "session_pgsql.sem_file_name", \
+ "soap.wsdl_cache_dir", \
+ "uploadprogress.file.filename_template", \
+ "xdebug.output_dir", \
+ "xdebug.profiler_output_dir", \
+ "xdebug.trace_output_dir", \
+ "xmms.path", \
+ "axis2.client_home", \
+ "blenc.key_file", \
+ "coin_acceptor.device", \
+ NULL \
+ }
+
struct fpm_worker_pool_s;
int fpm_php_init_child(struct fpm_worker_pool_s *wp);
Modified: php/php-src/trunk/sapi/fpm/php-fpm.8.in
===================================================================
--- php/php-src/trunk/sapi/fpm/php-fpm.8.in 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/trunk/sapi/fpm/php-fpm.8.in 2010-11-14 22:01:34 UTC (rev 305341)
@@ -77,7 +77,12 @@
.PD 1
.B \-v
Version number
+.B \-\-prefix \fIpath\fP
.TP
+.PD 1
+.B \-p
+Specify alternative prefix path (the default is @php_fpm_prefix@)
+.TP
.PD 0
.B \-\-fpm\-config \fIfile\fP
.TP
Modified: php/php-src/trunk/sapi/fpm/php-fpm.conf.in
===================================================================
--- php/php-src/trunk/sapi/fpm/php-fpm.conf.in 2010-11-14 20:30:23 UTC (rev 305340)
+++ php/php-src/trunk/sapi/fpm/php-fpm.conf.in 2010-11-14 22:01:34 UTC (rev 305341)
@@ -3,12 +3,16 @@
;;;;;;;;;;;;;;;;;;;;;
; All relative paths in this configuration file are relative to PHP's install
-; prefix.
+; prefix (@prefix@). This prefix can be dynamicaly changed by using the
+; '-p' argument from the command line.
; Include one or more files. If glob(3) exists, it is used to include a bunch of
; files from a glob(3) pattern. This directive can be used everywhere in the
; file.
-;inclu...@expanded_sysconfdir@/fpm.d/*.conf
+; Relative path can also be used. They will be prefixed by:
+; - the global prefix if it's been set (-p arguement)
+; - @prefix@ otherwise
+;include=etc/fpm.d/*.conf
;;;;;;;;;;;;;;;;;;
; Global Options ;
@@ -16,12 +20,14 @@
[global]
; Pid file
+; Note: the default prefix is @EXPANDED_LOCALSTATEDIR@
; Default Value: none
-;pid = @EXPANDED_LOCALSTATEDIR@/run/php-fpm.pid
+;pid = run/php-fpm.pid
; Error log file
-; Default Value: @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log
-;error_log = @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log
+; Note: the default prefix is @EXPANDED_LOCALSTATEDIR@
+; Default Value: log/php-fpm.log
+;error_log = log/php-fpm.log
; Log level
; Possible Values: alert, error, warning, notice, debug
@@ -62,8 +68,23 @@
; FPM can handle. Your system will tell you anyway :)
; Start a new pool named 'www'.
+; the variable $pool can we used in any directive and will be replaced by the
+; pool name ('www' here)
[www]
+; Per pool prefix
+; It only applies on the following directives:
+; - 'slowlog'
+; - 'listen' (unixsocket)
+; - 'chroot'
+; - 'chdir'
+; - 'php_values'
+; - 'php_admin_values'
+; When not set, the global prefix (or @php_fpm_prefix@) applies instead.
+; Note: This directive can also be relative to the global prefix.
+; Default Value: none
+;prefix = /path/to/pools/$pool
+
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
@@ -218,7 +239,7 @@
; The log file for slow requests
; Default Value: not set
; Note: slowlog is mandatory if request_slowlog_timeout is set
-;slowlog = @EXPANDED_LOCALSTATEDIR@/log/php-fpm.log.slow
+;slowlog = log/$pool.log.slow
; Set open file descriptor rlimit.
; Default Value: system defined value
@@ -231,13 +252,17 @@
; Chroot to this directory at the start. This value must be defined as an
; absolute path. When this value is not set, chroot is not used.
+; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
+; of its subdirectories. If the pool prefix is not set, the global prefix
+; will be used instead.
; Note: chrooting is a great security feature and should be used whenever
; possible. However, all PHP paths will be relative to the chroot
; (error_log, sessions.save_path, ...).
; Default Value: not set
;chroot =
-; Chdir to this directory at the start. This value must be an absolute path.
+; Chdir to this directory at the start.
+; Note: relative path can be used.
; Default Value: current directory or / when chroot
;chdir = /var/www
@@ -269,6 +294,9 @@
; overwrite previously defined php.ini values, but will append the new value
; instead.
+; Note: path INI options can be relative and will be expanded with the prefix
+; (pool, global or @prefix@)
+
; Default Value: nothing is defined by default except the values in php.ini and
; specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f [email protected]
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php