Browse Source

added gracefull shutdown and max-connections

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-merge-1.4.x@653 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.3
Jan Kneschke 17 years ago
parent
commit
5c20c426b7
  1. 3
      src/base.h
  2. 3
      src/configfile.c
  3. 4
      src/fdevent_select.c
  4. 2
      src/network.c
  5. 87
      src/server.c

3
src/base.h

@ -441,6 +441,7 @@ typedef struct {
unsigned short max_worker;
unsigned short max_fds;
unsigned short max_conns;
unsigned short log_request_header_on_error;
unsigned short log_state_handling;
@ -503,6 +504,8 @@ typedef struct {
int want_fds; /* waiting fds */
int sockets_disabled;
int max_conns;
/* buffers */
buffer *parse_full_path;
buffer *response_header;

3
src/configfile.c

@ -76,6 +76,7 @@ static int config_insert(server *srv) {
{ "server.errorlog-use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 39 */
{ "server.range-requests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 40 */
{ "server.stat-cache-engine", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 41 */
{ "server.max-connections", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER }, /* 42 */
{ "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
{ "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET },
@ -112,6 +113,7 @@ static int config_insert(server *srv) {
stat_cache_string = buffer_init();
cv[41].destination = stat_cache_string;
cv[42].destination = &(srv->srvconf.max_conns);
srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
assert(srv->config_storage);
@ -1018,6 +1020,7 @@ int config_set_defaults(server *srv) {
#endif
#ifdef USE_FREEBSD_KQUEUE
{ FDEVENT_HANDLER_FREEBSD_KQUEUE, "freebsd-kqueue" },
{ FDEVENT_HANDLER_FREEBSD_KQUEUE, "kqueue" },
#endif
{ FDEVENT_HANDLER_UNSET, NULL }
};

4
src/fdevent_select.c

@ -7,6 +7,7 @@
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <assert.h>
#include "fdevent.h"
#include "settings.h"
@ -36,6 +37,9 @@ static int fdevent_select_event_del(fdevents *ev, int fde_ndx, int fd) {
static int fdevent_select_event_add(fdevents *ev, int fde_ndx, int fd, int events) {
UNUSED(fde_ndx);
/* we should be protected by max-fds, but you never know */
assert(fd < FD_SETSIZE);
if (events & FDEVENT_IN) {
FD_SET(fd, &(ev->select_set_read));
FD_CLR(fd, &(ev->select_set_write));

2
src/network.c

@ -345,7 +345,7 @@ int network_close(server *srv) {
for (i = 0; i < srv->srv_sockets.used; i++) {
server_socket *srv_socket = srv->srv_sockets.ptr[i];
if (srv_socket->fd) {
if (srv_socket->fd != -1) {
/* check if server fd are already registered */
if (srv_socket->fde_ndx != -1) {
fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);

87
src/server.c

@ -56,6 +56,7 @@
#endif
static volatile sig_atomic_t srv_shutdown = 0;
static volatile sig_atomic_t gracefull_shutdown = 0;
static volatile sig_atomic_t handle_sig_alarm = 1;
static volatile sig_atomic_t handle_sig_hup = 0;
@ -65,8 +66,8 @@ static void sigaction_handler(int sig, siginfo_t *si, void *context) {
UNUSED(context);
switch (sig) {
case SIGINT: srv_shutdown = 1; break;
case SIGTERM: srv_shutdown = 1; break;
case SIGINT: gracefull_shutdown = 1; break;
case SIGALRM: handle_sig_alarm = 1; break;
case SIGHUP: handle_sig_hup = 1; break;
case SIGCHLD: break;
@ -75,8 +76,8 @@ static void sigaction_handler(int sig, siginfo_t *si, void *context) {
#elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
static void signal_handler(int sig) {
switch (sig) {
case SIGINT: srv_shutdown = 1; break;
case SIGTERM: srv_shutdown = 1; break;
case SIGINT: gracefull_shutdown = 1; break;
case SIGALRM: handle_sig_alarm = 1; break;
case SIGHUP: handle_sig_hup = 1; break;
case SIGCHLD: break;
@ -631,6 +632,18 @@ int main (int argc, char **argv) {
return -1;
}
}
/* set max-conns */
if (srv->srvconf.max_conns > srv->max_fds) {
/* we can't have more connections than max-fds */
srv->max_conns = srv->max_fds;
} else if (srv->srvconf.max_conns) {
/* otherwise respect thw wishes of the user */
srv->max_conns = srv->srvconf.max_conns;
} else {
/* or use the default */
srv->max_conns = srv->max_fds;
}
if (HANDLER_GO_ON != plugins_call_init(srv)) {
log_error_write(srv, __FILE__, __LINE__, "s", "Initialization of plugins failed. Going down.");
@ -960,31 +973,63 @@ int main (int argc, char **argv) {
}
}
/* handle out of fd condition */
if (!srv->sockets_disabled &&
srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) {
if (srv->sockets_disabled) {
/* our server sockets are disabled, why ? */
if ((srv->cur_fds + srv->want_fds < srv->max_fds * 0.8) && /* we have enough unused fds */
(srv->conns->used < srv->max_conns * 0.9) &&
(0 == gracefull_shutdown)) {
for (i = 0; i < srv->srv_sockets.used; i++) {
server_socket *srv_socket = srv->srv_sockets.ptr[i];
fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
}
/* disable server-fds */
log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
for (i = 0; i < srv->srv_sockets.used; i++) {
server_socket *srv_socket = srv->srv_sockets.ptr[i];
fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
srv->sockets_disabled = 0;
}
} else {
if ((srv->cur_fds + srv->want_fds > srv->max_fds * 0.9) || /* out of fds */
(srv->conns->used > srv->max_conns) || /* out of connections */
(gracefull_shutdown)) { /* gracefull_shutdown */
/* disable server-fds */
log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
srv->sockets_disabled = 1;
} else if (srv->sockets_disabled &&
srv->cur_fds + srv->want_fds < srv->max_fds * 0.8) {
for (i = 0; i < srv->srv_sockets.used; i++) {
server_socket *srv_socket = srv->srv_sockets.ptr[i];
fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
if (gracefull_shutdown) {
/* we don't want this socket anymore,
*
* closing it right away will make it possible for
* the next lighttpd to take over (gracefull restart)
* */
fdevent_unregister(srv->ev, srv_socket->fd);
close(srv_socket->fd);
srv_socket->fd = -1;
/* network_close() will cleanup after us */
}
}
if (gracefull_shutdown) {
log_error_write(srv, __FILE__, __LINE__, "s", "[note] gracefull shutdown started");
} else if (srv->conns->used > srv->max_conns) {
log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
} else {
log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
}
for (i = 0; i < srv->srv_sockets.used; i++) {
server_socket *srv_socket = srv->srv_sockets.ptr[i];
fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
srv->sockets_disabled = 1;
}
log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled, out-of-fds");
srv->sockets_disabled = 0;
}
if (gracefull_shutdown && srv->conns->used == 0) {
/* we are in gracefull shutdown phase and all connections are closed
* we are ready to terminate without harming anyone */
srv_shutdown = 1;
}
/* we still have some fds to share */

Loading…
Cancel
Save