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:
parent
df814223ff
commit
223e971c7e
|
@ -165,6 +165,7 @@ OPTIONS = [
|
||||||
"single-thread",
|
"single-thread",
|
||||||
"add-x-forwarded-proto",
|
"add-x-forwarded-proto",
|
||||||
"strip-incoming-x-forwarded-proto",
|
"strip-incoming-x-forwarded-proto",
|
||||||
|
"single-process",
|
||||||
]
|
]
|
||||||
|
|
||||||
LOGVARS = [
|
LOGVARS = [
|
||||||
|
|
43
src/shrpx.cc
43
src/shrpx.cc
|
@ -1205,13 +1205,17 @@ pid_t fork_worker_process(int &main_ipc_fd,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pid = fork();
|
auto config = get_config();
|
||||||
|
|
||||||
|
pid_t pid = 0;
|
||||||
|
|
||||||
|
if (!config->single_process) {
|
||||||
|
pid = fork();
|
||||||
|
}
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
ev_loop_fork(EV_DEFAULT);
|
ev_loop_fork(EV_DEFAULT);
|
||||||
|
|
||||||
auto config = get_config();
|
|
||||||
|
|
||||||
for (auto &addr : config->conn.listener.addrs) {
|
for (auto &addr : config->conn.listener.addrs) {
|
||||||
util::make_socket_closeonexec(addr.fd);
|
util::make_socket_closeonexec(addr.fd);
|
||||||
}
|
}
|
||||||
|
@ -1230,23 +1234,38 @@ pid_t fork_worker_process(int &main_ipc_fd,
|
||||||
LOG(FATAL) << "Unblocking all signals failed: "
|
LOG(FATAL) << "Unblocking all signals failed: "
|
||||||
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
<< xsi_strerror(error, errbuf.data(), errbuf.size());
|
||||||
|
|
||||||
|
if (config->single_process) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
nghttp2_Exit(EXIT_FAILURE);
|
nghttp2_Exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config->single_process) {
|
||||||
close(ipc_fd[1]);
|
close(ipc_fd[1]);
|
||||||
|
}
|
||||||
|
|
||||||
WorkerProcessConfig wpconf{ipc_fd[0]};
|
WorkerProcessConfig wpconf{ipc_fd[0]};
|
||||||
rv = worker_process_event_loop(&wpconf);
|
rv = worker_process_event_loop(&wpconf);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
LOG(FATAL) << "Worker process returned error";
|
LOG(FATAL) << "Worker process returned error";
|
||||||
|
|
||||||
|
if (config->single_process) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
} else {
|
||||||
nghttp2_Exit(EXIT_FAILURE);
|
nghttp2_Exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG(NOTICE) << "Worker process shutting down momentarily";
|
LOG(NOTICE) << "Worker process shutting down momentarily";
|
||||||
|
|
||||||
// call exit(...) instead of nghttp2_Exit to get leak sanitizer report
|
// call exit(...) instead of nghttp2_Exit to get leak sanitizer report
|
||||||
|
if (config->single_process) {
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
} else {
|
||||||
nghttp2_Exit(EXIT_SUCCESS);
|
nghttp2_Exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// parent process
|
// parent process
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
|
@ -1322,7 +1341,7 @@ int event_loop() {
|
||||||
|
|
||||||
auto loop = ev_default_loop(config->ev_loop_flags);
|
auto loop = ev_default_loop(config->ev_loop_flags);
|
||||||
|
|
||||||
int ipc_fd;
|
int ipc_fd = 0;
|
||||||
|
|
||||||
auto pid = fork_worker_process(ipc_fd, {});
|
auto pid = fork_worker_process(ipc_fd, {});
|
||||||
|
|
||||||
|
@ -2641,6 +2660,14 @@ Process:
|
||||||
--user=<USER>
|
--user=<USER>
|
||||||
Run this program as <USER>. This option is intended to
|
Run this program as <USER>. This option is intended to
|
||||||
be used to drop root privileges.
|
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:
|
Scripting:
|
||||||
--mruby-file=<PATH>
|
--mruby-file=<PATH>
|
||||||
|
@ -3000,7 +3027,7 @@ void reload_config(WorkerProcess *wp) {
|
||||||
// already created first default loop.
|
// already created first default loop.
|
||||||
auto loop = ev_default_loop(new_config->ev_loop_flags);
|
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
|
// fork_worker_process and forked child process assumes new
|
||||||
// configuration can be obtained from get_config().
|
// 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_ADD_X_FORWARDED_PROTO.c_str(), no_argument, &flag, 157},
|
||||||
{SHRPX_OPT_STRIP_INCOMING_X_FORWARDED_PROTO.c_str(), no_argument, &flag,
|
{SHRPX_OPT_STRIP_INCOMING_X_FORWARDED_PROTO.c_str(), no_argument, &flag,
|
||||||
158},
|
158},
|
||||||
|
{SHRPX_OPT_SINGLE_PROCESS.c_str(), no_argument, &flag, 159},
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
|
|
||||||
int option_index = 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,
|
cmdcfgs.emplace_back(SHRPX_OPT_STRIP_INCOMING_X_FORWARDED_PROTO,
|
||||||
StringRef::from_lit("yes"));
|
StringRef::from_lit("yes"));
|
||||||
break;
|
break;
|
||||||
|
case 159:
|
||||||
|
// --single-process
|
||||||
|
cmdcfgs.emplace_back(SHRPX_OPT_SINGLE_PROCESS,
|
||||||
|
StringRef::from_lit("yes"));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1620,6 +1620,9 @@ int option_lookup_token(const char *name, size_t namelen) {
|
||||||
if (util::strieq_l("client-cipher", name, 13)) {
|
if (util::strieq_l("client-cipher", name, 13)) {
|
||||||
return SHRPX_OPTID_CLIENT_CIPHERS;
|
return SHRPX_OPTID_CLIENT_CIPHERS;
|
||||||
}
|
}
|
||||||
|
if (util::strieq_l("single-proces", name, 13)) {
|
||||||
|
return SHRPX_OPTID_SINGLE_PROCESS;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (util::strieq_l("tls-proto-lis", name, 13)) {
|
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:
|
case SHRPX_OPTID_STRIP_INCOMING_X_FORWARDED_PROTO:
|
||||||
config->http.xfp.strip_incoming = util::strieq_l("yes", optarg);
|
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;
|
return 0;
|
||||||
case SHRPX_OPTID_CONF:
|
case SHRPX_OPTID_CONF:
|
||||||
LOG(WARN) << "conf: ignored";
|
LOG(WARN) << "conf: ignored";
|
||||||
|
|
|
@ -340,6 +340,7 @@ constexpr auto SHRPX_OPT_ADD_X_FORWARDED_PROTO =
|
||||||
StringRef::from_lit("add-x-forwarded-proto");
|
StringRef::from_lit("add-x-forwarded-proto");
|
||||||
constexpr auto SHRPX_OPT_STRIP_INCOMING_X_FORWARDED_PROTO =
|
constexpr auto SHRPX_OPT_STRIP_INCOMING_X_FORWARDED_PROTO =
|
||||||
StringRef::from_lit("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;
|
constexpr size_t SHRPX_OBFUSCATED_NODE_LENGTH = 8;
|
||||||
|
|
||||||
|
@ -872,6 +873,7 @@ struct Config {
|
||||||
verbose{false},
|
verbose{false},
|
||||||
daemon{false},
|
daemon{false},
|
||||||
http2_proxy{false},
|
http2_proxy{false},
|
||||||
|
single_process{false},
|
||||||
single_thread{false},
|
single_thread{false},
|
||||||
ev_loop_flags{0} {}
|
ev_loop_flags{0} {}
|
||||||
~Config();
|
~Config();
|
||||||
|
@ -913,6 +915,9 @@ struct Config {
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool daemon;
|
bool daemon;
|
||||||
bool http2_proxy;
|
bool http2_proxy;
|
||||||
|
// Run nghttpx in single process mode. With this mode, signal
|
||||||
|
// handling is omitted.
|
||||||
|
bool single_process;
|
||||||
bool single_thread;
|
bool single_thread;
|
||||||
// flags passed to ev_default_loop() and ev_loop_new()
|
// flags passed to ev_default_loop() and ev_loop_new()
|
||||||
int ev_loop_flags;
|
int ev_loop_flags;
|
||||||
|
@ -1049,6 +1054,7 @@ enum {
|
||||||
SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER,
|
SHRPX_OPTID_RESPONSE_HEADER_FIELD_BUFFER,
|
||||||
SHRPX_OPTID_RLIMIT_NOFILE,
|
SHRPX_OPTID_RLIMIT_NOFILE,
|
||||||
SHRPX_OPTID_SERVER_NAME,
|
SHRPX_OPTID_SERVER_NAME,
|
||||||
|
SHRPX_OPTID_SINGLE_PROCESS,
|
||||||
SHRPX_OPTID_SINGLE_THREAD,
|
SHRPX_OPTID_SINGLE_THREAD,
|
||||||
SHRPX_OPTID_STREAM_READ_TIMEOUT,
|
SHRPX_OPTID_STREAM_READ_TIMEOUT,
|
||||||
SHRPX_OPTID_STREAM_WRITE_TIMEOUT,
|
SHRPX_OPTID_STREAM_WRITE_TIMEOUT,
|
||||||
|
|
Loading…
Reference in New Issue