php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
fpm_unix.c
Go to the documentation of this file.
1 /* (c) 2007,2008 Andrei Nigmatulin */
2
3#include "fpm_config.h"
4
5#include <string.h>
6#include <sys/time.h>
7#include <sys/resource.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <sys/types.h>
11#include <sys/un.h>
12#include <pwd.h>
13#include <grp.h>
14
15#ifdef HAVE_PRCTL
16#include <sys/prctl.h>
17#endif
18
19#ifdef HAVE_PROCCTL
20#include <sys/procctl.h>
21#endif
22
23#ifdef HAVE_SETPFLAGS
24#include <priv.h>
25#endif
26
27#ifdef HAVE_APPARMOR
28#include <sys/apparmor.h>
29#endif
30
31#ifdef HAVE_SYS_ACL_H
32#include <sys/acl.h>
33#endif
34
35#ifdef HAVE_SELINUX
36#include <selinux/selinux.h>
37#endif
38
39#include "fpm.h"
40#include "fpm_conf.h"
41#include "fpm_cleanup.h"
42#include "fpm_clock.h"
43#include "fpm_stdio.h"
44#include "fpm_unix.h"
45#include "fpm_signals.h"
46#include "zlog.h"
47
49
50
51static inline bool fpm_unix_is_id(const char* name)
52{
53 return strlen(name) == strspn(name, "0123456789");
54}
55
56static struct passwd *fpm_unix_get_passwd(struct fpm_worker_pool_s *wp, const char *name, int flags)
57{
58 struct passwd *pwd = getpwnam(name);
59 if (!pwd) {
60 zlog(flags, "[pool %s] cannot get uid for user '%s'", wp->config->name, name);
61 return NULL;
62 }
63
64 return pwd;
65}
66
67static inline bool fpm_unix_check_listen_address(struct fpm_worker_pool_s *wp, const char *address, int flags)
68{
70 return true;
71 }
72
73 struct sockaddr_un test_socket;
74 size_t address_length = strlen(address);
75 size_t socket_length = sizeof(test_socket.sun_path);
76
77 if (address_length < socket_length) {
78 return true;
79 }
80
81 zlog(
82 flags,
83 "[pool %s] cannot bind to UNIX socket '%s' as path is too long (found length: %zu, "
84 "maximal length: %zu)",
85 wp->config->name,
86 address,
87 address_length,
88 socket_length
89 );
90
91 return false;
92}
93
94static inline bool fpm_unix_check_passwd(struct fpm_worker_pool_s *wp, const char *name, int flags)
95{
96 return !name || fpm_unix_is_id(name) || fpm_unix_get_passwd(wp, name, flags);
97}
98
99static struct group *fpm_unix_get_group(struct fpm_worker_pool_s *wp, const char *name, int flags)
100{
101 struct group *group = getgrnam(name);
102 if (!group) {
103 zlog(flags, "[pool %s] cannot get gid for group '%s'", wp->config->name, name);
104 return NULL;
105 }
106
107 return group;
108}
109
110static inline bool fpm_unix_check_group(struct fpm_worker_pool_s *wp, const char *name, int flags)
111{
112 return !name || fpm_unix_is_id(name) || fpm_unix_get_group(wp, name, flags);
113}
114
116{
117 struct fpm_worker_pool_config_s *config = wp->config;
118 return (
119 fpm_unix_check_passwd(wp, config->user, ZLOG_ERROR) &&
120 fpm_unix_check_group(wp, config->group, ZLOG_ERROR) &&
121 fpm_unix_check_listen_address(wp, config->listen_address, ZLOG_SYSERROR) &&
122 fpm_unix_check_passwd(wp, config->listen_owner, ZLOG_SYSERROR) &&
123 fpm_unix_check_group(wp, config->listen_group, ZLOG_SYSERROR)
124 );
125}
126
128{
129 struct fpm_worker_pool_config_s *c = wp->config;
130#ifdef HAVE_FPM_ACL
131 int n;
132
133 /* uninitialized */
134 wp->socket_acl = NULL;
135#endif
136 wp->socket_uid = -1;
137 wp->socket_gid = -1;
138 wp->socket_mode = 0660;
139
140 if (!c) {
141 return 0;
142 }
143
144 if (c->listen_mode && *c->listen_mode) {
145 wp->socket_mode = strtoul(c->listen_mode, 0, 8);
146 }
147
148#ifdef HAVE_FPM_ACL
149 /* count the users and groups configured */
150 n = 0;
151 if (c->listen_acl_users && *c->listen_acl_users) {
152 char *p;
153 n++;
154 for (p=strchr(c->listen_acl_users, ',') ; p ; p=strchr(p+1, ',')) {
155 n++;
156 }
157 }
158 if (c->listen_acl_groups && *c->listen_acl_groups) {
159 char *p;
160 n++;
161 for (p=strchr(c->listen_acl_groups, ',') ; p ; p=strchr(p+1, ',')) {
162 n++;
163 }
164 }
165 /* if ACL configured */
166 if (n) {
167 acl_t acl;
168 acl_entry_t entry;
169 acl_permset_t perm;
170 char *tmp, *p, *end;
171
172 acl = acl_init(n);
173 if (!acl) {
174 zlog(ZLOG_SYSERROR, "[pool %s] cannot allocate ACL", wp->config->name);
175 return -1;
176 }
177 /* Create USER ACL */
178 if (c->listen_acl_users && *c->listen_acl_users) {
179 struct passwd *pwd;
180
181 tmp = estrdup(c->listen_acl_users);
182 for (p=tmp ; p ; p=end) {
183 if ((end = strchr(p, ','))) {
184 *end++ = 0;
185 }
186 pwd = fpm_unix_get_passwd(wp, p, ZLOG_SYSERROR);
187 if (pwd) {
188 zlog(ZLOG_DEBUG, "[pool %s] user '%s' have uid=%d", wp->config->name, p, pwd->pw_uid);
189 } else {
190 acl_free(acl);
191 efree(tmp);
192 return -1;
193 }
194 if (0 > acl_create_entry(&acl, &entry) ||
195 0 > acl_set_tag_type(entry, ACL_USER) ||
196 0 > acl_set_qualifier(entry, &pwd->pw_uid) ||
197 0 > acl_get_permset(entry, &perm) ||
198 0 > acl_clear_perms (perm) ||
199 0 > acl_add_perm (perm, ACL_READ) ||
200 0 > acl_add_perm (perm, ACL_WRITE)) {
201 zlog(ZLOG_SYSERROR, "[pool %s] cannot create ACL for user '%s'", wp->config->name, p);
202 acl_free(acl);
203 efree(tmp);
204 return -1;
205 }
206 }
207 efree(tmp);
208 }
209 /* Create GROUP ACL */
210 if (c->listen_acl_groups && *c->listen_acl_groups) {
211 struct group *grp;
212
213 tmp = estrdup(c->listen_acl_groups);
214 for (p=tmp ; p ; p=end) {
215 if ((end = strchr(p, ','))) {
216 *end++ = 0;
217 }
218 grp = fpm_unix_get_group(wp, p, ZLOG_SYSERROR);
219 if (grp) {
220 zlog(ZLOG_DEBUG, "[pool %s] group '%s' have gid=%d", wp->config->name, p, grp->gr_gid);
221 } else {
222 acl_free(acl);
223 efree(tmp);
224 return -1;
225 }
226 if (0 > acl_create_entry(&acl, &entry) ||
227 0 > acl_set_tag_type(entry, ACL_GROUP) ||
228 0 > acl_set_qualifier(entry, &grp->gr_gid) ||
229 0 > acl_get_permset(entry, &perm) ||
230 0 > acl_clear_perms (perm) ||
231 0 > acl_add_perm (perm, ACL_READ) ||
232 0 > acl_add_perm (perm, ACL_WRITE)) {
233 zlog(ZLOG_SYSERROR, "[pool %s] cannot create ACL for group '%s'", wp->config->name, p);
234 acl_free(acl);
235 efree(tmp);
236 return -1;
237 }
238 }
239 efree(tmp);
240 }
241 if (c->listen_owner && *c->listen_owner) {
242 zlog(ZLOG_WARNING, "[pool %s] ACL set, listen.owner = '%s' is ignored", wp->config->name, c->listen_owner);
243 }
244 if (c->listen_group && *c->listen_group) {
245 zlog(ZLOG_WARNING, "[pool %s] ACL set, listen.group = '%s' is ignored", wp->config->name, c->listen_group);
246 }
247 wp->socket_acl = acl;
248 return 0;
249 }
250 /* When listen.users and listen.groups not configured, continue with standard right */
251#endif
252
253 if (c->listen_owner && *c->listen_owner) {
254 if (fpm_unix_is_id(c->listen_owner)) {
255 wp->socket_uid = strtoul(c->listen_owner, 0, 10);
256 } else {
257 struct passwd *pwd;
258
259 pwd = fpm_unix_get_passwd(wp, c->listen_owner, ZLOG_SYSERROR);
260 if (!pwd) {
261 return -1;
262 }
263
264 wp->socket_uid = pwd->pw_uid;
265 wp->socket_gid = pwd->pw_gid;
266 }
267 }
268
269 if (c->listen_group && *c->listen_group) {
270 if (fpm_unix_is_id(c->listen_group)) {
271 wp->socket_gid = strtoul(c->listen_group, 0, 10);
272 } else {
273 struct group *grp;
274
275 grp = fpm_unix_get_group(wp, c->listen_group, ZLOG_SYSERROR);
276 if (!grp) {
277 return -1;
278 }
279 wp->socket_gid = grp->gr_gid;
280 }
281 }
282
283 return 0;
284}
285/* }}} */
286
287int fpm_unix_set_socket_permissions(struct fpm_worker_pool_s *wp, const char *path) /* {{{ */
288{
289#ifdef HAVE_FPM_ACL
290 if (wp->socket_acl) {
291 acl_t aclfile, aclconf;
292 acl_entry_t entryfile, entryconf;
293 int i;
294
295 /* Read the socket ACL */
296 aclconf = wp->socket_acl;
297 aclfile = acl_get_file (path, ACL_TYPE_ACCESS);
298 if (!aclfile) {
299 zlog(ZLOG_SYSERROR, "[pool %s] failed to read the ACL of the socket '%s'", wp->config->name, path);
300 return -1;
301 }
302 /* Copy the new ACL entry from config */
303 for (i=ACL_FIRST_ENTRY ; acl_get_entry(aclconf, i, &entryconf) ; i=ACL_NEXT_ENTRY) {
304 if (0 > acl_create_entry (&aclfile, &entryfile) ||
305 0 > acl_copy_entry(entryfile, entryconf)) {
306 zlog(ZLOG_SYSERROR, "[pool %s] failed to add entry to the ACL of the socket '%s'", wp->config->name, path);
307 acl_free(aclfile);
308 return -1;
309 }
310 }
311 /* Write the socket ACL */
312 if (0 > acl_calc_mask (&aclfile) ||
313 0 > acl_valid (aclfile) ||
314 0 > acl_set_file (path, ACL_TYPE_ACCESS, aclfile)) {
315 zlog(ZLOG_SYSERROR, "[pool %s] failed to write the ACL of the socket '%s'", wp->config->name, path);
316 acl_free(aclfile);
317 return -1;
318 } else {
319 zlog(ZLOG_DEBUG, "[pool %s] ACL of the socket '%s' is set", wp->config->name, path);
320 }
321
322 acl_free(aclfile);
323 return 0;
324 }
325 /* When listen.users and listen.groups not configured, continue with standard right */
326#endif
327
328 if (wp->socket_uid != -1 || wp->socket_gid != -1) {
329 if (0 > chown(path, wp->socket_uid, wp->socket_gid)) {
330 zlog(ZLOG_SYSERROR, "[pool %s] failed to chown() the socket '%s'", wp->config->name, wp->config->listen_address);
331 return -1;
332 }
333 }
334 return 0;
335}
336/* }}} */
337
339{
340#ifdef HAVE_FPM_ACL
341 if (wp->socket_acl) {
342 return acl_free(wp->socket_acl);
343 }
344#endif
345 return 0;
346}
347/* }}} */
348
349static int fpm_unix_conf_wp(struct fpm_worker_pool_s *wp) /* {{{ */
350{
351 struct passwd *pwd;
352 int is_root = !geteuid();
353
354 if (is_root) {
355 if (wp->config->user && *wp->config->user) {
356 if (fpm_unix_is_id(wp->config->user)) {
357 wp->set_uid = strtoul(wp->config->user, 0, 10);
358 pwd = getpwuid(wp->set_uid);
359 if (pwd) {
360 wp->set_gid = pwd->pw_gid;
361 wp->set_user = strdup(pwd->pw_name);
362 }
363 } else {
364 struct passwd *pwd;
365
366 pwd = fpm_unix_get_passwd(wp, wp->config->user, ZLOG_ERROR);
367 if (!pwd) {
368 return -1;
369 }
370
371 wp->set_uid = pwd->pw_uid;
372 wp->set_gid = pwd->pw_gid;
373
374 wp->user = strdup(pwd->pw_name);
375 wp->home = strdup(pwd->pw_dir);
376 }
377 }
378
379 if (wp->config->group && *wp->config->group) {
380 if (fpm_unix_is_id(wp->config->group)) {
381 wp->set_gid = strtoul(wp->config->group, 0, 10);
382 } else {
383 struct group *grp;
384
385 grp = fpm_unix_get_group(wp, wp->config->group, ZLOG_ERROR);
386 if (!grp) {
387 return -1;
388 }
389 wp->set_gid = grp->gr_gid;
390 }
391 }
392
393 if (!fpm_globals.run_as_root) {
394 if (wp->set_uid == 0 || wp->set_gid == 0) {
395 zlog(ZLOG_ERROR, "[pool %s] please specify user and group other than root", wp->config->name);
396 return -1;
397 }
398 }
399 } else { /* not root */
400 if (wp->config->user && *wp->config->user) {
401 zlog(ZLOG_NOTICE, "[pool %s] 'user' directive is ignored when FPM is not running as root", wp->config->name);
402 }
403 if (wp->config->group && *wp->config->group) {
404 zlog(ZLOG_NOTICE, "[pool %s] 'group' directive is ignored when FPM is not running as root", wp->config->name);
405 }
406 if (wp->config->chroot && *wp->config->chroot) {
407 zlog(ZLOG_NOTICE, "[pool %s] 'chroot' directive is ignored when FPM is not running as root", wp->config->name);
408 }
409 if (wp->config->process_priority != 64) {
410 zlog(ZLOG_NOTICE, "[pool %s] 'process.priority' directive is ignored when FPM is not running as root", wp->config->name);
411 }
412
413 /* set up HOME and USER anyway */
414 pwd = getpwuid(getuid());
415 if (pwd) {
416 wp->user = strdup(pwd->pw_name);
417 wp->home = strdup(pwd->pw_dir);
418 }
419 }
420 return 0;
421}
422/* }}} */
423
424int fpm_unix_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
425{
426 int is_root = !geteuid();
427 int made_chroot = 0;
428
429 if (wp->config->rlimit_files) {
430 struct rlimit r;
431
432 r.rlim_max = r.rlim_cur = (rlim_t) wp->config->rlimit_files;
433
434 if (0 > setrlimit(RLIMIT_NOFILE, &r)) {
435 zlog(ZLOG_SYSERROR, "[pool %s] failed to set rlimit_files for this pool. Please check your system limits or decrease rlimit_files. setrlimit(RLIMIT_NOFILE, %d)", wp->config->name, wp->config->rlimit_files);
436 }
437 }
438
439 if (wp->config->rlimit_core) {
440 struct rlimit r;
441
442 r.rlim_max = r.rlim_cur = wp->config->rlimit_core == -1 ? (rlim_t) RLIM_INFINITY : (rlim_t) wp->config->rlimit_core;
443
444 if (0 > setrlimit(RLIMIT_CORE, &r)) {
445 zlog(ZLOG_SYSERROR, "[pool %s] failed to set rlimit_core for this pool. Please check your system limits or decrease rlimit_core. setrlimit(RLIMIT_CORE, %d)", wp->config->name, wp->config->rlimit_core);
446 }
447 }
448
449 if (is_root && wp->config->chroot && *wp->config->chroot) {
450 if (0 > chroot(wp->config->chroot)) {
451 zlog(ZLOG_SYSERROR, "[pool %s] failed to chroot(%s)", wp->config->name, wp->config->chroot);
452 return -1;
453 }
454 made_chroot = 1;
455 }
456
457 if (wp->config->chdir && *wp->config->chdir) {
458 if (0 > chdir(wp->config->chdir)) {
459 zlog(ZLOG_SYSERROR, "[pool %s] failed to chdir(%s)", wp->config->name, wp->config->chdir);
460 return -1;
461 }
462 } else if (made_chroot) {
463 if (0 > chdir("/")) {
464 zlog(ZLOG_WARNING, "[pool %s] failed to chdir(/)", wp->config->name);
465 }
466 }
467
468 if (is_root) {
469
470 if (wp->config->process_priority != 64) {
471 if (setpriority(PRIO_PROCESS, 0, wp->config->process_priority) < 0) {
472 zlog(ZLOG_SYSERROR, "[pool %s] Unable to set priority for this new process", wp->config->name);
473 return -1;
474 }
475 }
476
477 if (wp->set_gid) {
478 if (0 > setgid(wp->set_gid)) {
479 zlog(ZLOG_SYSERROR, "[pool %s] failed to setgid(%d)", wp->config->name, wp->set_gid);
480 return -1;
481 }
482 }
483 if (wp->set_uid) {
484 if (0 > initgroups(wp->set_user ? wp->set_user : wp->config->user, wp->set_gid)) {
485 zlog(ZLOG_SYSERROR, "[pool %s] failed to initgroups(%s, %d)", wp->config->name, wp->config->user, wp->set_gid);
486 return -1;
487 }
488 if (0 > setuid(wp->set_uid)) {
489 zlog(ZLOG_SYSERROR, "[pool %s] failed to setuid(%d)", wp->config->name, wp->set_uid);
490 return -1;
491 }
492 }
493 }
494
495#ifdef HAVE_PRCTL
496 if (wp->config->process_dumpable) {
497 int dumpable = 1;
498#ifdef HAVE_SELINUX
499 if (security_get_boolean_active("deny_ptrace") == 1) {
500 zlog(ZLOG_SYSERROR, "[pool %s] ptrace is denied", wp->config->name);
501 dumpable = 0;
502 }
503#endif
504 if (dumpable && 0 > prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)) {
505 zlog(ZLOG_SYSERROR, "[pool %s] failed to prctl(PR_SET_DUMPABLE)", wp->config->name);
506 }
507 }
508#endif
509
510#ifdef HAVE_PROCCTL
511 int dumpable = PROC_TRACE_CTL_ENABLE;
512 if (wp->config->process_dumpable && -1 == procctl(P_PID, getpid(), PROC_TRACE_CTL, &dumpable)) {
513 zlog(ZLOG_SYSERROR, "[pool %s] failed to procctl(PROC_TRACE_CTL)", wp->config->name);
514 }
515#endif
516
517#ifdef HAVE_SETPFLAGS
518 if (wp->config->process_dumpable && 0 > setpflags(__PROC_PROTECT, 0)) {
519 zlog(ZLOG_SYSERROR, "[pool %s] failed to setpflags(__PROC_PROTECT)", wp->config->name);
520 }
521#endif
522
523 if (0 > fpm_clock_init()) {
524 return -1;
525 }
526
527#ifdef HAVE_APPARMOR
528 if (wp->config->apparmor_hat) {
529 char *con, *new_con;
530
531 if (aa_getcon(&con, NULL) == -1) {
532 zlog(ZLOG_SYSERROR, "[pool %s] failed to query apparmor confinement. Please check if \"/proc/*/attr/current\" is read and writeable.", wp->config->name);
533 return -1;
534 }
535
536 size_t new_con_length = strlen(con) + strlen(wp->config->apparmor_hat) + 3; // // + 0 Byte
537 new_con = malloc(new_con_length);
538 if (!new_con) {
539 zlog(ZLOG_SYSERROR, "[pool %s] failed to allocate memory for apparmor hat change.", wp->config->name);
540 free(con);
541 return -1;
542 }
543
544 if (0 > snprintf(new_con, new_con_length, "%s//%s", con, wp->config->apparmor_hat)) {
545 zlog(ZLOG_SYSERROR, "[pool %s] failed to construct apparmor confinement.", wp->config->name);
546 free(con);
547 free(new_con);
548 return -1;
549 }
550
551 if (0 > aa_change_profile(new_con)) {
552 zlog(ZLOG_SYSERROR, "[pool %s] failed to change to new confinement (%s). Please check if \"/proc/*/attr/current\" is read and writeable and \"change_profile -> %s//*\" is allowed.", wp->config->name, new_con, con);
553 free(con);
554 free(new_con);
555 return -1;
556 }
557
558 free(con);
559 free(new_con);
560 }
561#endif
562
563 return 0;
564}
565/* }}} */
566
568{
569 struct fpm_worker_pool_s *wp;
570 int is_root = !geteuid();
571
572 if (fpm_global_config.rlimit_files) {
573 struct rlimit r;
574
575 r.rlim_max = r.rlim_cur = (rlim_t) fpm_global_config.rlimit_files;
576
577 if (0 > setrlimit(RLIMIT_NOFILE, &r)) {
578 zlog(ZLOG_SYSERROR, "failed to set rlimit_files for this pool. Please check your system limits or decrease rlimit_files. setrlimit(RLIMIT_NOFILE, %d)", fpm_global_config.rlimit_files);
579 return -1;
580 }
581 }
582
583 if (fpm_global_config.rlimit_core) {
584 struct rlimit r;
585
586 r.rlim_max = r.rlim_cur = fpm_global_config.rlimit_core == -1 ? (rlim_t) RLIM_INFINITY : (rlim_t) fpm_global_config.rlimit_core;
587
588 if (0 > setrlimit(RLIMIT_CORE, &r)) {
589 zlog(ZLOG_SYSERROR, "failed to set rlimit_core for this pool. Please check your system limits or decrease rlimit_core. setrlimit(RLIMIT_CORE, %d)", fpm_global_config.rlimit_core);
590 return -1;
591 }
592 }
593
594 fpm_pagesize = getpagesize();
595 if (fpm_global_config.daemonize) {
596 /*
597 * If daemonize, the calling process will die soon
598 * and the master process continues to initialize itself.
599 *
600 * The parent process has then to wait for the master
601 * process to initialize to return a consistent exit
602 * value. For this purpose, the master process will
603 * send \"1\" into the pipe if everything went well
604 * and \"0\" otherwise.
605 */
606
607
608 struct timeval tv;
609 fd_set rfds;
610 int ret;
611
612 if (pipe(fpm_globals.send_config_pipe) == -1) {
613 zlog(ZLOG_SYSERROR, "failed to create pipe");
614 return -1;
615 }
616
617 /* then fork */
618 pid_t pid = fork();
619 switch (pid) {
620
621 case -1 : /* error */
622 zlog(ZLOG_SYSERROR, "failed to daemonize");
623 return -1;
624
625 case 0 : /* children */
626 close(fpm_globals.send_config_pipe[0]); /* close the read side of the pipe */
627 break;
628
629 default : /* parent */
630 close(fpm_globals.send_config_pipe[1]); /* close the write side of the pipe */
631
632 /*
633 * wait for 10s before exiting with error
634 * the child is supposed to send 1 or 0 into the pipe to tell the parent
635 * how it goes for it
636 */
637 FD_ZERO(&rfds);
638 FD_SET(fpm_globals.send_config_pipe[0], &rfds);
639
640 tv.tv_sec = 10;
641 tv.tv_usec = 0;
642
643 zlog(ZLOG_DEBUG, "The calling process is waiting for the master process to ping via fd=%d", fpm_globals.send_config_pipe[0]);
644 ret = select(fpm_globals.send_config_pipe[0] + 1, &rfds, NULL, NULL, &tv);
645 if (ret == -1) {
646 zlog(ZLOG_SYSERROR, "failed to select");
648 }
649 if (ret) { /* data available */
650 int readval;
651 ret = read(fpm_globals.send_config_pipe[0], &readval, sizeof(readval));
652 if (ret == -1) {
653 zlog(ZLOG_SYSERROR, "failed to read from pipe");
655 }
656
657 if (ret == 0) {
658 zlog(ZLOG_ERROR, "no data have been read from pipe");
660 } else {
661 if (readval == 1) {
662 zlog(ZLOG_DEBUG, "I received a valid acknowledge from the master process, I can exit without error");
665 } else {
666 zlog(ZLOG_DEBUG, "The master process returned an error !");
668 }
669 }
670 } else { /* no date sent ! */
671 zlog(ZLOG_ERROR, "the master process didn't send back its status (via the pipe to the calling process)");
673 }
675 }
676 }
677
678 /* continue as a child */
679 setsid();
680 if (0 > fpm_clock_init()) {
681 return -1;
682 }
683
684 if (fpm_global_config.process_priority != 64) {
685 if (is_root) {
686 if (setpriority(PRIO_PROCESS, 0, fpm_global_config.process_priority) < 0) {
687 zlog(ZLOG_SYSERROR, "Unable to set priority for the master process");
688 return -1;
689 }
690 } else {
691 zlog(ZLOG_NOTICE, "'process.priority' directive is ignored when FPM is not running as root");
692 }
693 }
694
695 fpm_globals.parent_pid = getpid();
696 for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
697 if (0 > fpm_unix_conf_wp(wp)) {
698 return -1;
699 }
700 }
701
702 return 0;
703}
chroot(string $directory)
chdir(string $directory)
chown(string $filename, string|int $user)
strspn(string $string, string $characters, int $offset=0, ?int $length=null)
strchr(string $haystack, string $needle, bool $before_needle=false)
zend_long n
Definition ffi.c:4979
struct fpm_globals_s fpm_globals
Definition fpm.c:24
#define FPM_EXIT_SOFTWARE
Definition fpm.h:27
#define FPM_EXIT_OK
Definition fpm.h:15
void fpm_cleanups_run(int type)
Definition fpm_cleanup.c:36
@ FPM_CLEANUP_PARENT_EXIT
Definition fpm_cleanup.h:11
int fpm_clock_init(void)
Definition fpm_clock.c:105
struct fpm_global_config_s fpm_global_config
Definition fpm_conf.c:64
int fpm_unix_set_socket_permissions(struct fpm_worker_pool_s *wp, const char *path)
Definition fpm_unix.c:287
int fpm_unix_free_socket_permissions(struct fpm_worker_pool_s *wp)
Definition fpm_unix.c:338
int fpm_unix_resolve_socket_permissions(struct fpm_worker_pool_s *wp)
Definition fpm_unix.c:127
int fpm_unix_init_main(void)
Definition fpm_unix.c:567
int fpm_unix_init_child(struct fpm_worker_pool_s *wp)
Definition fpm_unix.c:424
bool fpm_unix_test_config(struct fpm_worker_pool_s *wp)
Definition fpm_unix.c:115
size_t fpm_pagesize
Definition fpm_unix.c:48
struct fpm_worker_pool_s * fpm_worker_all_pools
@ FPM_AF_UNIX
#define NULL
Definition gdcache.h:45
const P_PID
const PRIO_PROCESS
unsigned const char * end
Definition php_ffi.h:51
struct timeval tv
Definition session.c:1280
p
Definition session.c:1105
struct fpm_worker_pool_config_s * config
enum fpm_address_domain listen_address_domain
struct fpm_worker_pool_s * next
#define close(a)
#define efree(ptr)
Definition zend_alloc.h:155
#define estrdup(s)
Definition zend_alloc.h:164
strlen(string $string)
exit(string|int $status=0)
#define snprintf
zend_string * name
zval * ret
#define ZLOG_SYSERROR
Definition zlog.h:53
@ ZLOG_DEBUG
Definition zlog.h:42
@ ZLOG_ERROR
Definition zlog.h:45
@ ZLOG_NOTICE
Definition zlog.h:43
@ ZLOG_WARNING
Definition zlog.h:44
#define zlog(flags,...)
Definition zlog.h:9