Exemple #1
0
int fpm_unix_init_main() /* {{{ */
{
	struct fpm_worker_pool_s *wp;

	fpm_pagesize = getpagesize();
	if (fpm_global_config.daemonize) {
		switch (fork()) {
			case -1 :
				zlog(ZLOG_STUFF, ZLOG_SYSERROR, "daemonized fork() failed");
				return -1;
			case 0 :
				break;
			default :
				fpm_cleanups_run(FPM_CLEANUP_PARENT_EXIT);
				exit(0);
		}
	}

	setsid();
	if (0 > fpm_clock_init()) {
		return -1;
	}

	fpm_globals.parent_pid = getpid();
	for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
		if (0 > fpm_unix_conf_wp(wp)) {
			return -1;
		}
	}

	fpm_stdio_init_final();
	return 0;
}
Exemple #2
0
int fpm_unix_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
{
	int is_root = !geteuid();
	int made_chroot = 0;

	if (wp->config->rlimit_files) {
		struct rlimit r;

		r.rlim_max = r.rlim_cur = (rlim_t) wp->config->rlimit_files;

		if (0 > setrlimit(RLIMIT_NOFILE, &r)) {
			zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] setrlimit(RLIMIT_NOFILE, %d) failed (%d)", wp->config->name, wp->config->rlimit_files, errno);
		}
	}

	if (wp->config->rlimit_core) {
		struct rlimit r;

		r.rlim_max = r.rlim_cur = wp->config->rlimit_core == -1 ? (rlim_t) RLIM_INFINITY : (rlim_t) wp->config->rlimit_core;

		if (0 > setrlimit(RLIMIT_CORE, &r)) {
			zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] setrlimit(RLIMIT_CORE, %d) failed (%d)", wp->config->name, wp->config->rlimit_core, errno);
		}
	}

	if (is_root && wp->config->chroot && *wp->config->chroot) {
		if (0 > chroot(wp->config->chroot)) {
			zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] chroot(%s) failed",  wp->config->name, wp->config->chroot);
			return -1;
		}
		made_chroot = 1;
	}

	if (wp->config->chdir && *wp->config->chdir) {
		if (0 > chdir(wp->config->chdir)) {
			zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] chdir(%s) failed", wp->config->name, wp->config->chdir);
			return -1;
		}
	} else if (made_chroot) {
		chdir("/");
	}

	if (is_root) {
		if (wp->set_gid) {
			if (0 > setgid(wp->set_gid)) {
				zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] setgid(%d) failed", wp->config->name, wp->set_gid);
				return -1;
			}
		}
		if (wp->set_uid) {
			if (0 > initgroups(wp->config->user, wp->set_gid)) {
				zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] initgroups(%s, %d) failed", wp->config->name, wp->config->user, wp->set_gid);
				return -1;
			}
			if (0 > setuid(wp->set_uid)) {
				zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] setuid(%d) failed", wp->config->name, wp->set_uid);
				return -1;
			}
		}
	}

#ifdef HAVE_PRCTL
	if (0 > prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)) {
		zlog(ZLOG_STUFF, ZLOG_SYSERROR, "[pool %s] prctl(PR_SET_DUMPABLE) failed", wp->config->name);
	}
#endif

	if (0 > fpm_clock_init()) {
		return -1;
	}
	return 0;
}
Exemple #3
0
int fpm_unix_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
{
    int is_root = !geteuid();
    int made_chroot = 0;

    if (wp->config->rlimit_files) {
        struct rlimit r;

        r.rlim_max = r.rlim_cur = (rlim_t) wp->config->rlimit_files;

        if (0 > setrlimit(RLIMIT_NOFILE, &r)) {
            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);
        }
    }

    if (wp->config->rlimit_core) {
        struct rlimit r;

        r.rlim_max = r.rlim_cur = wp->config->rlimit_core == -1 ? (rlim_t) RLIM_INFINITY : (rlim_t) wp->config->rlimit_core;

        if (0 > setrlimit(RLIMIT_CORE, &r)) {
            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);
        }
    }

    if (is_root && wp->config->chroot && *wp->config->chroot) {
        if (0 > chroot(wp->config->chroot)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to chroot(%s)",  wp->config->name, wp->config->chroot);
            return -1;
        }
        made_chroot = 1;
    }

    if (wp->config->chdir && *wp->config->chdir) {
        if (0 > chdir(wp->config->chdir)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to chdir(%s)", wp->config->name, wp->config->chdir);
            return -1;
        }
    } else if (made_chroot) {
        if (0 > chdir("/")) {
            zlog(ZLOG_WARNING, "[pool %s] failed to chdir(/)", wp->config->name);
        }
    }

    if (is_root) {

        if (wp->config->process_priority != 64) {
            if (setpriority(PRIO_PROCESS, 0, wp->config->process_priority) < 0) {
                zlog(ZLOG_SYSERROR, "[pool %s] Unable to set priority for this new process", wp->config->name);
                return -1;
            }
        }

        if (wp->set_gid) {
            if (0 > setgid(wp->set_gid)) {
                zlog(ZLOG_SYSERROR, "[pool %s] failed to setgid(%d)", wp->config->name, wp->set_gid);
                return -1;
            }
        }
        if (wp->set_uid) {
            if (0 > initgroups(wp->config->user, wp->set_gid)) {
                zlog(ZLOG_SYSERROR, "[pool %s] failed to initgroups(%s, %d)", wp->config->name, wp->config->user, wp->set_gid);
                return -1;
            }
            if (0 > setuid(wp->set_uid)) {
                zlog(ZLOG_SYSERROR, "[pool %s] failed to setuid(%d)", wp->config->name, wp->set_uid);
                return -1;
            }
        }
    }

#ifdef HAVE_PRCTL
    if (0 > prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)) {
        zlog(ZLOG_SYSERROR, "[pool %s] failed to prctl(PR_SET_DUMPABLE)", wp->config->name);
    }
#endif

    if (0 > fpm_clock_init()) {
        return -1;
    }

#ifdef HAVE_APPARMOR
    if (wp->config->apparmor_hat) {
        char *con, *new_con;

        if (aa_getcon(&con, NULL) == -1) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to query apparmor confinement. Please check if \"/proc/*/attr/current\" is read and writeable.", wp->config->name);
            return -1;
        }

        new_con = malloc(strlen(con) + strlen(wp->config->apparmor_hat) + 3); // // + 0 Byte
        if (!new_con) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to allocate memory for apparmor hat change.", wp->config->name);
            return -1;
        }

        if (0 > sprintf(new_con, "%s//%s", con, wp->config->apparmor_hat)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to construct apparmor confinement.", wp->config->name);
            return -1;
        }

        if (0 > aa_change_profile(new_con)) {
            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);
            return -1;
        }

        free(con);
        free(new_con);
    }
#endif

    return 0;
}
Exemple #4
0
// 初始化unix
int fpm_unix_init_main() /* {{{ */
{
    struct fpm_worker_pool_s *wp;
    int is_root = !geteuid();

    // 能够打开的最大的文件描述符数量
    if (fpm_global_config.rlimit_files) {
        struct rlimit r;

        r.rlim_max = r.rlim_cur = (rlim_t) fpm_global_config.rlimit_files;

        // setrlimit和getrlimit系统调用
        if (0 > setrlimit(RLIMIT_NOFILE, &r)) {
            zlog(ZLOG_SYSERROR, "failed to set rlimit_core for this pool. Please check your system limits or decrease rlimit_files. setrlimit(RLIMIT_NOFILE, %d)", fpm_global_config.rlimit_files);
            return -1;
        }
    }

    // coredump的最大值
    if (fpm_global_config.rlimit_core) {
        struct rlimit r;

        r.rlim_max = r.rlim_cur = fpm_global_config.rlimit_core == -1 ? (rlim_t) RLIM_INFINITY : (rlim_t) fpm_global_config.rlimit_core;

        if (0 > setrlimit(RLIMIT_CORE, &r)) {
            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);
            return -1;
        }
    }

    // linux页面大小
    fpm_pagesize = getpagesize();

    // 在守护进程模式下,会folk出子进程,而前台进程会当Init完毕后退出程
    if (fpm_global_config.daemonize) {
        /*
         * If daemonize, the calling process will die soon
         * and the master process continues to initialize itself.
         *
         * The parent process has then to wait for the master
         * process to initialize to return a consistent exit
         * value. For this pupose, the master process will
         * send \"1\" into the pipe if everything went well
         * and \"0\" otherwise.
         */

        struct timeval tv;
        fd_set rfds;
        int ret;

        // 创建管道,将send_config_pipe两个文件描述符连接起来
        if (pipe(fpm_globals.send_config_pipe) == -1) {
            zlog(ZLOG_SYSERROR, "failed to create pipe");
            return -1;
        }

        /* then fork */
        pid_t pid = fork();
        switch (pid) {

        case -1 : /* error */
            zlog(ZLOG_SYSERROR, "failed to daemonize");
            return -1;

        case 0 : /* children */
            close(fpm_globals.send_config_pipe[0]); /* close the read side of the pipe */
            break;

        default : /* parent */
            close(fpm_globals.send_config_pipe[1]); /* close the write side of the pipe */

            /*
             * wait for 10s before exiting with error
             * the child is supposed to send 1 or 0 into the pipe to tell the parent
             * how it goes for it
             */
            FD_ZERO(&rfds);
            FD_SET(fpm_globals.send_config_pipe[0], &rfds);

            tv.tv_sec = 10;
            tv.tv_usec = 0;

            zlog(ZLOG_DEBUG, "The calling process is waiting for the master process to ping via fd=%d", fpm_globals.send_config_pipe[0]);
            ret = select(fpm_globals.send_config_pipe[0] + 1, &rfds, NULL, NULL, &tv);
            if (ret == -1) {
                zlog(ZLOG_SYSERROR, "failed to select");
                exit(FPM_EXIT_SOFTWARE);
            }
            if (ret) { /* data available */
                int readval;
                ret = read(fpm_globals.send_config_pipe[0], &readval, sizeof(readval));
                if (ret == -1) {
                    zlog(ZLOG_SYSERROR, "failed to read from pipe");
                    exit(FPM_EXIT_SOFTWARE);
                }

                if (ret == 0) {
                    zlog(ZLOG_ERROR, "no data have been read from pipe");
                    exit(FPM_EXIT_SOFTWARE);
                } else {
                    // 收到了数据
                    // 1表示初始化成功
                    // 0表示失败
                    if (readval == 1) {
                        zlog(ZLOG_DEBUG, "I received a valid acknoledge from the master process, I can exit without error");
                        fpm_cleanups_run(FPM_CLEANUP_PARENT_EXIT);
                        exit(FPM_EXIT_OK);
                    } else {
                        zlog(ZLOG_DEBUG, "The master process returned an error !");
                        exit(FPM_EXIT_SOFTWARE);
                    }
                }
            } else { /* no date sent ! */
                zlog(ZLOG_ERROR, "the master process didn't send back its status (via the pipe to the calling process)");
                exit(FPM_EXIT_SOFTWARE);
            }
            exit(FPM_EXIT_SOFTWARE);
        }
    }

    /* continue as a child */
    setsid();
    if (0 > fpm_clock_init()) {
        return -1;
    }

    // 设置php-fpm进程的优先级
    if (fpm_global_config.process_priority != 64) {
        if (is_root) {
            if (setpriority(PRIO_PROCESS, 0, fpm_global_config.process_priority) < 0) {
                zlog(ZLOG_SYSERROR, "Unable to set priority for the master process");
                return -1;
            }
        } else {
            zlog(ZLOG_NOTICE, "'process.priority' directive is ignored when FPM is not running as root");
        }
    }

    // 设置master进程的pid
    fpm_globals.parent_pid = getpid();
    for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
        if (0 > fpm_unix_conf_wp(wp)) {
            return -1;
        }
    }

    return 0;
}
Exemple #5
0
int fpm_unix_init_child(struct fpm_worker_pool_s *wp) /* {{{ */
{
	int is_root = !geteuid();
	int made_chroot = 0;

	if (wp->config->rlimit_files) {
		struct rlimit r;

		r.rlim_max = r.rlim_cur = (rlim_t) wp->config->rlimit_files;

		if (0 > setrlimit(RLIMIT_NOFILE, &r)) {
			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);
		}
	}

	if (wp->config->rlimit_core) {
		struct rlimit r;

		r.rlim_max = r.rlim_cur = wp->config->rlimit_core == -1 ? (rlim_t) RLIM_INFINITY : (rlim_t) wp->config->rlimit_core;

		if (0 > setrlimit(RLIMIT_CORE, &r)) {
			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);
		}
	}

	if (is_root && wp->config->chroot && *wp->config->chroot) {
		if (0 > chroot(wp->config->chroot)) {
			zlog(ZLOG_SYSERROR, "[pool %s] failed to chroot(%s)",  wp->config->name, wp->config->chroot);
			return -1;
		}
		made_chroot = 1;
	}

	if (wp->config->chdir && *wp->config->chdir) {
		if (0 > chdir(wp->config->chdir)) {
			zlog(ZLOG_SYSERROR, "[pool %s] failed to chdir(%s)", wp->config->name, wp->config->chdir);
			return -1;
		}
	} else if (made_chroot) {
		chdir("/");
	}

	if (is_root) {

		if (wp->config->process_priority != 64) {
			if (setpriority(PRIO_PROCESS, 0, wp->config->process_priority) < 0) {
				zlog(ZLOG_SYSERROR, "[pool %s] Unable to set priority for this new process", wp->config->name);
				return -1;
			}
		}

		if (wp->set_gid) {
			if (0 > setgid(wp->set_gid)) {
				zlog(ZLOG_SYSERROR, "[pool %s] failed to setgid(%d)", wp->config->name, wp->set_gid);
				return -1;
			}
		}
		if (wp->set_uid) {
			if (0 > initgroups(wp->config->user, wp->set_gid)) {
				zlog(ZLOG_SYSERROR, "[pool %s] failed to initgroups(%s, %d)", wp->config->name, wp->config->user, wp->set_gid);
				return -1;
			}
			if (0 > setuid(wp->set_uid)) {
				zlog(ZLOG_SYSERROR, "[pool %s] failed to setuid(%d)", wp->config->name, wp->set_uid);
				return -1;
			}
		}
	}

#ifdef HAVE_PRCTL
	if (0 > prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)) {
		zlog(ZLOG_SYSERROR, "[pool %s] failed to prctl(PR_SET_DUMPABLE)", wp->config->name);
	}
#endif

	if (0 > fpm_clock_init()) {
		return -1;
	}
	return 0;
}