Merge branch 'nghttpx-reload'
This commit is contained in:
commit
fb3d6f68a8
|
@ -49,6 +49,9 @@ SIGQUIT
|
|||
accepting connection. After all connections are handled, nghttpx
|
||||
exits.
|
||||
|
||||
SIGHUP
|
||||
Reload configuration file given in :option:`--conf`.
|
||||
|
||||
SIGUSR1
|
||||
Reopen log files.
|
||||
|
||||
|
@ -56,7 +59,11 @@ SIGUSR2
|
|||
Fork and execute nghttpx. It will execute the binary in the same
|
||||
path with same command-line arguments and environment variables.
|
||||
After new process comes up, sending SIGQUIT to the original process
|
||||
to perform hot swapping.
|
||||
to perform hot swapping. The difference between SIGUSR2 + SIGQUIT
|
||||
and SIGHUP is that former is usually used to execute new binary, and
|
||||
the master process is newly spawned. On the other hand, the latter
|
||||
just reloads configuration file, and the same master process
|
||||
continues to exist.
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -236,6 +236,9 @@ all existing frontend connections are done, the current process will
|
|||
exit. At this point, only new nghttpx process exists and serves
|
||||
incoming requests.
|
||||
|
||||
If you want to just reload configuration file without executing new
|
||||
binary, send SIGHUP to nghttpx master process.
|
||||
|
||||
Re-opening log files
|
||||
--------------------
|
||||
|
||||
|
|
665
src/shrpx.cc
665
src/shrpx.cc
File diff suppressed because it is too large
Load Diff
|
@ -60,16 +60,44 @@
|
|||
namespace shrpx {
|
||||
|
||||
namespace {
|
||||
Config *config = nullptr;
|
||||
std::unique_ptr<Config> config;
|
||||
} // namespace
|
||||
|
||||
constexpr auto SHRPX_UNIX_PATH_PREFIX = StringRef::from_lit("unix:");
|
||||
|
||||
const Config *get_config() { return config; }
|
||||
const Config *get_config() { return config.get(); }
|
||||
|
||||
Config *mod_config() { return config; }
|
||||
Config *mod_config() { return config.get(); }
|
||||
|
||||
void create_config() { config = new Config(); }
|
||||
std::unique_ptr<Config> replace_config(std::unique_ptr<Config> another) {
|
||||
config.swap(another);
|
||||
return another;
|
||||
}
|
||||
|
||||
void create_config() { config = make_unique<Config>(); }
|
||||
|
||||
Config::~Config() {
|
||||
auto &upstreamconf = http2.upstream;
|
||||
|
||||
nghttp2_option_del(upstreamconf.option);
|
||||
nghttp2_option_del(upstreamconf.alt_mode_option);
|
||||
nghttp2_session_callbacks_del(upstreamconf.callbacks);
|
||||
|
||||
auto &downstreamconf = http2.downstream;
|
||||
|
||||
nghttp2_option_del(downstreamconf.option);
|
||||
nghttp2_session_callbacks_del(downstreamconf.callbacks);
|
||||
|
||||
auto &dumpconf = http2.upstream.debug.dump;
|
||||
|
||||
if (dumpconf.request_header) {
|
||||
fclose(dumpconf.request_header);
|
||||
}
|
||||
|
||||
if (dumpconf.response_header) {
|
||||
fclose(dumpconf.response_header);
|
||||
}
|
||||
}
|
||||
|
||||
TicketKeys::~TicketKeys() {
|
||||
/* Erase keys from memory */
|
||||
|
@ -2398,7 +2426,7 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
}
|
||||
|
||||
included_set.insert(optarg);
|
||||
auto rv = load_config(optarg.c_str(), included_set);
|
||||
auto rv = load_config(config, optarg.c_str(), included_set);
|
||||
included_set.erase(optarg);
|
||||
|
||||
if (rv != 0) {
|
||||
|
@ -2648,7 +2676,8 @@ int parse_config(Config *config, int optid, const StringRef &opt,
|
|||
return -1;
|
||||
}
|
||||
|
||||
int load_config(const char *filename, std::set<StringRef> &include_set) {
|
||||
int load_config(Config *config, const char *filename,
|
||||
std::set<StringRef> &include_set) {
|
||||
std::ifstream in(filename, std::ios::binary);
|
||||
if (!in) {
|
||||
LOG(ERROR) << "Could not open config file " << filename;
|
||||
|
@ -2669,7 +2698,7 @@ int load_config(const char *filename, std::set<StringRef> &include_set) {
|
|||
}
|
||||
*eq = '\0';
|
||||
|
||||
if (parse_config(mod_config(), StringRef{std::begin(line), eq},
|
||||
if (parse_config(config, StringRef{std::begin(line), eq},
|
||||
StringRef{eq + 1, std::end(line)}, include_set) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -706,6 +706,8 @@ struct APIConfig {
|
|||
};
|
||||
|
||||
struct Config {
|
||||
~Config();
|
||||
|
||||
HttpProxy downstream_http_proxy;
|
||||
HttpConfig http;
|
||||
Http2Config http2;
|
||||
|
@ -717,13 +719,9 @@ struct Config {
|
|||
ImmutableString conf_path;
|
||||
ImmutableString user;
|
||||
ImmutableString mruby_file;
|
||||
char **original_argv;
|
||||
char **argv;
|
||||
char *cwd;
|
||||
size_t num_worker;
|
||||
size_t padding;
|
||||
size_t rlimit_nofile;
|
||||
int argc;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
pid_t pid;
|
||||
|
@ -736,6 +734,9 @@ struct Config {
|
|||
|
||||
const Config *get_config();
|
||||
Config *mod_config();
|
||||
// Replaces the current config with given |new_config|. The old config is
|
||||
// returned.
|
||||
std::unique_ptr<Config> replace_config(std::unique_ptr<Config> new_config);
|
||||
void create_config();
|
||||
|
||||
// generated by gennghttpxfun.py
|
||||
|
@ -890,10 +891,11 @@ int parse_config(Config *config, const StringRef &opt, const StringRef &optarg,
|
|||
int parse_config(Config *config, int optid, const StringRef &opt,
|
||||
const StringRef &optarg, std::set<StringRef> &included_set);
|
||||
|
||||
// Loads configurations from |filename| and stores them in statically
|
||||
// allocated Config object. This function returns 0 if it succeeds, or
|
||||
// -1. See parse_config() for |include_set|.
|
||||
int load_config(const char *filename, std::set<StringRef> &include_set);
|
||||
// Loads configurations from |filename| and stores them in |config|.
|
||||
// This function returns 0 if it succeeds, or -1. See parse_config()
|
||||
// for |include_set|.
|
||||
int load_config(Config *config, const char *filename,
|
||||
std::set<StringRef> &include_set);
|
||||
|
||||
// Parses header field in |optarg|. We expect header field is formed
|
||||
// like "NAME: VALUE". We require that NAME is non empty string. ":"
|
||||
|
|
|
@ -114,8 +114,9 @@ constexpr auto master_proc_ign_signals = std::array<int, 1>{{SIGPIPE}};
|
|||
} // namespace
|
||||
|
||||
namespace {
|
||||
constexpr auto worker_proc_ign_signals = std::array<int, 4>{
|
||||
{REOPEN_LOG_SIGNAL, EXEC_BINARY_SIGNAL, GRACEFUL_SHUTDOWN_SIGNAL, SIGPIPE}};
|
||||
constexpr auto worker_proc_ign_signals =
|
||||
std::array<int, 5>{{REOPEN_LOG_SIGNAL, EXEC_BINARY_SIGNAL,
|
||||
GRACEFUL_SHUTDOWN_SIGNAL, RELOAD_SIGNAL, SIGPIPE}};
|
||||
} // namespace
|
||||
|
||||
void shrpx_signal_set_master_proc_ign_handler() {
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace shrpx {
|
|||
constexpr int REOPEN_LOG_SIGNAL = SIGUSR1;
|
||||
constexpr int EXEC_BINARY_SIGNAL = SIGUSR2;
|
||||
constexpr int GRACEFUL_SHUTDOWN_SIGNAL = SIGQUIT;
|
||||
constexpr int RELOAD_SIGNAL = SIGHUP;
|
||||
|
||||
// Blocks all signals. The previous signal mask is stored into
|
||||
// |oldset| if it is not nullptr. This function returns 0 if it
|
||||
|
|
|
@ -94,16 +94,14 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
|
|||
}
|
||||
} // namespace
|
||||
|
||||
// This function is meant be called from master process, hence the
|
||||
// call exit(3).
|
||||
std::vector<unsigned char>
|
||||
set_alpn_prefs(const std::vector<std::string> &protos) {
|
||||
int set_alpn_prefs(std::vector<unsigned char> &out,
|
||||
const std::vector<std::string> &protos) {
|
||||
size_t len = 0;
|
||||
|
||||
for (const auto &proto : protos) {
|
||||
if (proto.size() > 255) {
|
||||
LOG(FATAL) << "Too long ALPN identifier: " << proto.size();
|
||||
exit(EXIT_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len += 1 + proto.size();
|
||||
|
@ -111,10 +109,10 @@ set_alpn_prefs(const std::vector<std::string> &protos) {
|
|||
|
||||
if (len > (1 << 16) - 1) {
|
||||
LOG(FATAL) << "Too long ALPN identifier list: " << len;
|
||||
exit(EXIT_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto out = std::vector<unsigned char>(len);
|
||||
out.resize(len);
|
||||
auto ptr = out.data();
|
||||
|
||||
for (const auto &proto : protos) {
|
||||
|
@ -123,7 +121,7 @@ set_alpn_prefs(const std::vector<std::string> &protos) {
|
|||
ptr += proto.size();
|
||||
}
|
||||
|
||||
return out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -181,8 +181,8 @@ bool check_http2_requirement(SSL *ssl);
|
|||
// passed to SSL_CTX_set_options().
|
||||
long int create_tls_proto_mask(const std::vector<std::string> &tls_proto_list);
|
||||
|
||||
std::vector<unsigned char>
|
||||
set_alpn_prefs(const std::vector<std::string> &protos);
|
||||
int set_alpn_prefs(std::vector<unsigned char> &out,
|
||||
const std::vector<std::string> &protos);
|
||||
|
||||
// Setups server side SSL_CTX. This function inspects get_config()
|
||||
// and if upstream_no_tls is true, returns nullptr. Otherwise
|
||||
|
|
Loading…
Reference in New Issue