nghttpx: Add --single-process option

With --single-process option, nghttpx will run in a single process
mode where master and worker are unified into one process.  nghttpx
still spawns additional process for neverbleed.  In the single process
mode, signal handling is disabled.
This commit is contained in:
Tatsuhiro Tsujikawa 2017-04-06 19:53:39 +09:00
parent df814223ff
commit 223e971c7e
4 changed files with 56 additions and 9 deletions

View File

@ -165,6 +165,7 @@ OPTIONS = [
"single-thread",
"add-x-forwarded-proto",
"strip-incoming-x-forwarded-proto",
"single-process",
]
LOGVARS = [

View File

@ -1205,13 +1205,17 @@ pid_t fork_worker_process(int &main_ipc_fd,
return -1;
}
auto pid = fork();
auto config = get_config();
pid_t pid = 0;
if (!config->single_process) {
pid = fork();
}
if (pid == 0) {
ev_loop_fork(EV_DEFAULT);
auto config = get_config();
for (auto &addr : config->conn.listener.addrs) {
util::make_socket_closeonexec(addr.fd);
}
@ -1230,22 +1234,37 @@ pid_t fork_worker_process(int &main_ipc_fd,
LOG(FATAL) << "Unblocking all signals failed: "
<< xsi_strerror(error, errbuf.data(), errbuf.size());
nghttp2_Exit(EXIT_FAILURE);
if (config->single_process) {
exit(EXIT_FAILURE);
} else {
nghttp2_Exit(EXIT_FAILURE);
}
}
if (!config->single_process) {
close(ipc_fd[1]);
}
close(ipc_fd[1]);
WorkerProcessConfig wpconf{ipc_fd[0]};
rv = worker_process_event_loop(&wpconf);
if (rv != 0) {
LOG(FATAL) << "Worker process returned error";
nghttp2_Exit(EXIT_FAILURE);
if (config->single_process) {
exit(EXIT_FAILURE);
} else {
nghttp2_Exit(EXIT_FAILURE);
}
}
LOG(NOTICE) << "Worker process shutting down momentarily";
// call exit(...) instead of nghttp2_Exit to get leak sanitizer report
nghttp2_Exit(EXIT_SUCCESS);
if (config->single_process) {
exit(EXIT_SUCCESS);
} else {
nghttp2_Exit(EXIT_SUCCESS);
}
}
// parent process
@ -1322,7 +1341,7 @@ int event_loop() {
auto loop = ev_default_loop(config->ev_loop_flags);
int ipc_fd;
int ipc_fd = 0;
auto pid = fork_worker_process(ipc_fd, {});
@ -2641,6 +2660,14 @@ Process:
--user=<USER>
Run this program as <USER>. This option is intended to
be used to drop root privileges.
--single-process
Run this program in a single process mode for debugging
purpose. Without this option, nghttpx creates at least
2 processes: master and worker processes. If this
option is used, master and worker are unified into a
single process. nghttpx still spawns additional process
if neverbleed is used. In the single process mode, the
signal handling feature is disabled.
Scripting:
--mruby-file=<PATH>
@ -3000,7 +3027,7 @@ void reload_config(WorkerProcess *wp) {
// already created first default loop.
auto loop = ev_default_loop(new_config->ev_loop_flags);
int ipc_fd;
int ipc_fd = 0;
// fork_worker_process and forked child process assumes new
// configuration can be obtained from get_config().
@ -3309,6 +3336,7 @@ int main(int argc, char **argv) {
{SHRPX_OPT_ADD_X_FORWARDED_PROTO.c_str(), no_argument, &flag, 157},
{SHRPX_OPT_STRIP_INCOMING_X_FORWARDED_PROTO.c_str(), no_argument, &flag,
158},
{SHRPX_OPT_SINGLE_PROCESS.c_str(), no_argument, &flag, 159},
{nullptr, 0, nullptr, 0}};
int option_index = 0;
@ -4055,6 +4083,11 @@ int main(int argc, char **argv) {
cmdcfgs.emplace_back(SHRPX_OPT_STRIP_INCOMING_X_FORWARDED_PROTO,
StringRef::from_lit("yes"));
break;
case 159:
// --single-process
cmdcfgs.emplace_back(SHRPX_OPT_SINGLE_PROCESS,
StringRef::from_lit("yes"));
break;
default:
break;
}

View File

@ -1620,6 +1620,9 @@ int option_lookup_token(const char *name, size_t namelen) {
if (util::strieq_l("client-cipher", name, 13)) {
return SHRPX_OPTID_CLIENT_CIPHERS;
}
if (util::strieq_l("single-proces", name, 13)) {
return SHRPX_OPTID_SINGLE_PROCESS;
}
break;
case 't':
if (util::strieq_l("tls-proto-lis", name, 13)) {
@ -3374,6 +3377,10 @@ int parse_config(Config *config, int optid, const StringRef &opt,
case SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_PROTO:
config->http.xfp.strip_incoming = util::strieq_l("yes", optarg);
return 0;
case SHRPX_OPTID_SINGLE_PROCESS:
config->single_process = util::strieq_l("yes", optarg);
return 0;
case SHRPX_OPTID_CONF:
LOG(WARN) << "conf: ignored";

View File

@ -340,6 +340,7 @@ constexpr auto SHRPX_OPT_ADD_X_FORWARDED_PROTO =
StringRef::from_lit("add-x-forwarded-proto");
constexpr auto SHRPX_OPT_STRIP_INCOMING_X_FORWARDED_PROTO =
StringRef::from_lit("strip-incoming-x-forwarded-proto");
constexpr auto SHRPX_OPT_SINGLE_PROCESS = StringRef::from_lit("single-process");
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
@ -872,6 +873,7 @@ struct Config {
verbose{false},
daemon{false},
http2_proxy{false},
single_process{false},
single_thread{false},
ev_loop_flags{0} {}
~Config();
@ -913,6 +915,9 @@ struct Config {
bool verbose;
bool daemon;
bool http2_proxy;
// Run nghttpx in single process mode. With this mode, signal
// handling is omitted.
bool single_process;
bool single_thread;
// flags passed to ev_default_loop() and ev_loop_new()
int ev_loop_flags;
@ -1049,6 +1054,7 @@ enum {
SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER,
SHRPX_OPTID_RLIMIT_NOFILE,
SHRPX_OPTID_SERVER_NAME,
SHRPX_OPTID_SINGLE_PROCESS,
SHRPX_OPTID_SINGLE_THREAD,
SHRPX_OPTID_STREAM_READ_TIMEOUT,
SHRPX_OPTID_STREAM_WRITE_TIMEOUT,