Shutdown listen socket during segfault

During a segfault, we continue to accept incoming connections. This is
bad as the web server is unlikely to do a good job of serving these well.
Here we close the listen socket as soon as we discover the server is crashing.

A more robust way to do this might have been to have an array of FDs that
are listening for incoming connections. We could have then closed those
from the signal handling thread. This would complete the operation more
quickly and also handle a case where the libevent thread wasn't running.
However, this version was quicker to write.

I didn't understand why some signals didn't trigger the Segfaulting variable.
Does anybody have insight into that?
Esse commit está contido em:
Ben Maurer
2013-07-25 15:47:58 -07:00
commit de Sara Golemon
commit a9e05eabf4
3 arquivos alterados com 24 adições e 2 exclusões
+2 -2
Ver Arquivo
@@ -28,16 +28,16 @@ namespace HPHP {
//////////////////////////////////////////////////////////////////////
bool SegFaulting = false;
bool IsCrashing = false;
static void bt_handler(int sig) {
// In case we crash again in the signal hander or something
signal(sig, SIG_DFL);
IsCrashing = true;
// Generating a stack dumps significant time, try to stop threads
// from flushing bad data or generating more faults meanwhile
if (sig==SIGQUIT || sig==SIGILL || sig==SIGSEGV || sig==SIGBUS) {
SegFaulting = true;
LightProcess::Close();
// leave running for SIGTERM SIGFPE SIGABRT
}
+2
Ver Arquivo
@@ -21,6 +21,8 @@ namespace HPHP {
//////////////////////////////////////////////////////////////////////
extern bool IsCrashing;
extern bool SegFaulting;
void install_crash_reporter();
//////////////////////////////////////////////////////////////////////
+20
Ver Arquivo
@@ -18,6 +18,7 @@
#include "hphp/runtime/base/runtime_option.h"
#include "hphp/runtime/base/memory_manager.h"
#include "hphp/runtime/base/crash_reporter.h"
#include "hphp/runtime/server/server_stats.h"
#include "hphp/runtime/server/http_protocol.h"
#include "hphp/runtime/debugger/debugger.h"
@@ -377,6 +378,25 @@ int LibEventServer::getAcceptSocketSSL() {
// request/response handling
void LibEventServer::onRequest(struct evhttp_request *request) {
// If we are in the process of crashing, we want to reject incoming work.
// This will prompt the load balancers to choose another server. Using
// shutdown rather than close has the advantage that it makes fewer changes
// to the process (eg, it doesn't close the FD so if the FD number were
// corrupted it would be mostly harmless).
//
// Setting accept sock to -1 will leak FDs. But we're crashing anyways.
if (IsCrashing) {
if (m_accept_sock != -1) {
shutdown(m_accept_sock, SHUT_FBLISTEN);
m_accept_sock = -1;
}
if (m_accept_sock_ssl != -1) {
shutdown(m_accept_sock_ssl, SHUT_FBLISTEN);
m_accept_sock_ssl = -1;
}
return;
}
if (RuntimeOption::EnableKeepAlive &&
RuntimeOption::ConnectionTimeoutSeconds > 0) {
// before processing request, set the connection timeout