[MEDIUM] session: make session_shutdown() an independant function

We already had the ability to kill a connection, but it was only
for the checks. Now we can do this for any session, and for this we
add a specific flag "K" to the logs.
This commit is contained in:
Willy Tarreau 2011-09-07 23:01:56 +02:00
parent 532a450ebc
commit a2a64e9689
6 changed files with 23 additions and 14 deletions

View File

@ -8872,6 +8872,8 @@ each of which has a special meaning :
D : the session was killed by haproxy because the server was detected D : the session was killed by haproxy because the server was detected
as down and was configured to kill all connections when going down. as down and was configured to kill all connections when going down.
K : the session was actively killed by an admin operating on haproxy.
c : the client-side timeout expired while waiting for the client to c : the client-side timeout expired while waiting for the client to
send or receive data. send or receive data.

View File

@ -36,6 +36,8 @@ int session_accept(struct listener *l, int cfd, struct sockaddr_storage *addr);
/* perform minimal intializations, report 0 in case of error, 1 if OK. */ /* perform minimal intializations, report 0 in case of error, 1 if OK. */
int init_session(); int init_session();
/* kill a session and set the termination flags to <why> (one of SN_ERR_*) */
void session_shutdown(struct session *session, int why);
void session_process_counters(struct session *s); void session_process_counters(struct session *s);
void sess_change_server(struct session *sess, struct server *newsrv); void sess_change_server(struct session *sess, struct server *newsrv);

View File

@ -56,7 +56,7 @@
#define SN_REDIRECTABLE 0x00000400 /* set if this session is redirectable (GET or HEAD) */ #define SN_REDIRECTABLE 0x00000400 /* set if this session is redirectable (GET or HEAD) */
#define SN_TUNNEL 0x00000800 /* tunnel-mode session, nothing to catch after data */ #define SN_TUNNEL 0x00000800 /* tunnel-mode session, nothing to catch after data */
/* session termination conditions, bits values 0x1000 to 0x7000 (0-7 shift 12) */ /* session termination conditions, bits values 0x1000 to 0x7000 (0-9 shift 12) */
#define SN_ERR_NONE 0x00000000 #define SN_ERR_NONE 0x00000000
#define SN_ERR_CLITO 0x00001000 /* client time-out */ #define SN_ERR_CLITO 0x00001000 /* client time-out */
#define SN_ERR_CLICL 0x00002000 /* client closed (read/write error) */ #define SN_ERR_CLICL 0x00002000 /* client closed (read/write error) */
@ -66,6 +66,7 @@
#define SN_ERR_RESOURCE 0x00006000 /* the proxy encountered a lack of a local resources (fd, mem, ...) */ #define SN_ERR_RESOURCE 0x00006000 /* the proxy encountered a lack of a local resources (fd, mem, ...) */
#define SN_ERR_INTERNAL 0x00007000 /* the proxy encountered an internal error */ #define SN_ERR_INTERNAL 0x00007000 /* the proxy encountered an internal error */
#define SN_ERR_DOWN 0x00008000 /* the proxy killed a session because the backend became unavailable */ #define SN_ERR_DOWN 0x00008000 /* the proxy killed a session because the backend became unavailable */
#define SN_ERR_KILLED 0x00009000 /* the proxy killed a session because it was asked to do so */
#define SN_ERR_MASK 0x0000f000 /* mask to get only session error flags */ #define SN_ERR_MASK 0x0000f000 /* mask to get only session error flags */
#define SN_ERR_SHIFT 12 /* bit shift */ #define SN_ERR_SHIFT 12 /* bit shift */

View File

@ -364,18 +364,9 @@ static void shutdown_sessions(struct server *srv)
{ {
struct session *session, *session_bck; struct session *session, *session_bck;
list_for_each_entry_safe(session, session_bck, list_for_each_entry_safe(session, session_bck, &srv->actconns, by_srv)
&srv->actconns, by_srv) { if (session->srv_conn == srv)
if (session->srv_conn == srv && session_shutdown(session, SN_ERR_DOWN);
!(session->req->flags & (BF_SHUTW|BF_SHUTW_NOW))) {
buffer_shutw_now(session->req);
buffer_shutr_now(session->rep);
session->task->nice = 1024;
if (!(session->flags & SN_ERR_MASK))
session->flags |= SN_ERR_DOWN;
task_wakeup(session->task, TASK_WOKEN_OTHER);
}
}
} }
/* Sets server <s> down, notifies by all available means, recounts the /* Sets server <s> down, notifies by all available means, recounts the

View File

@ -52,7 +52,7 @@ const char *monthname[12] = {
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
}; };
const char sess_term_cond[9] = "-cCsSPRID"; /* normal, CliTo, CliErr, SrvTo, SrvErr, PxErr, Resource, Internal, Down */ const char sess_term_cond[10] = "-cCsSPRIDK"; /* normal, CliTo, CliErr, SrvTo, SrvErr, PxErr, Resource, Internal, Down, Killed */
const char sess_fin_state[8] = "-RCHDLQT"; /* cliRequest, srvConnect, srvHeader, Data, Last, Queue, Tarpit */ const char sess_fin_state[8] = "-RCHDLQT"; /* cliRequest, srvConnect, srvHeader, Data, Last, Queue, Tarpit */
/* /*

View File

@ -2214,6 +2214,19 @@ void default_srv_error(struct session *s, struct stream_interface *si)
s->flags |= fin; s->flags |= fin;
} }
/* kill a session and set the termination flags to <why> (one of SN_ERR_*) */
void session_shutdown(struct session *session, int why)
{
if (session->req->flags & (BF_SHUTW|BF_SHUTW_NOW))
return;
buffer_shutw_now(session->req);
buffer_shutr_now(session->rep);
session->task->nice = 1024;
if (!(session->flags & SN_ERR_MASK))
session->flags |= why;
task_wakeup(session->task, TASK_WOKEN_OTHER);
}
/************************************************************************/ /************************************************************************/
/* All supported ACL keywords must be declared here. */ /* All supported ACL keywords must be declared here. */