From: Willy Tarreau Date: Tue, 1 Jun 2010 07:51:00 +0000 (+0200) Subject: [MEDIUM] session: move the conn_retries attribute to the stream interface X-Git-Tag: v1.5-dev8~583 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ee28de0a1236be4b5460cd29bbdf3f94aca5e395;p=thirdparty%2Fhaproxy.git [MEDIUM] session: move the conn_retries attribute to the stream interface The conn_retries still lies in the session and its initialization depends on the backend when it may not yet be known. Let's first move it to the stream interface. --- diff --git a/include/types/session.h b/include/types/session.h index daf2619261..fd86f09d4a 100644 --- a/include/types/session.h +++ b/include/types/session.h @@ -163,7 +163,6 @@ struct session { struct listener *listener; /* the listener by which the request arrived */ struct proxy *fe; /* the proxy this session depends on for the client side */ struct proxy *be; /* the proxy this session depends on for the server side */ - int conn_retries; /* number of connect retries left */ int flags; /* some flags describing the session */ unsigned term_trace; /* term trace: 4*8 bits indicating which part of the code closed */ struct buffer *req; /* request buffer */ diff --git a/include/types/stream_interface.h b/include/types/stream_interface.h index 6ad6684e9e..db166c9b24 100644 --- a/include/types/stream_interface.h +++ b/include/types/stream_interface.h @@ -2,7 +2,7 @@ * include/types/stream_interface.h * This file describes the stream_interface struct and associated constants. * - * Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu + * Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -82,6 +82,9 @@ struct proxy; /* Note that if an iohandler is set, the update function will not be called by * the session handler, so it may be used to resync flags at the end of the I/O * handler. See stream_int_update_embedded() for reference. + * This struct could be optimized, because : + * - connect(), fd, conn_retries are only used in stream_sock mode + * - iohandler(), private, st0, st1 are only used in iohandler mode */ struct stream_interface { unsigned int state; /* SI_ST* */ @@ -99,6 +102,7 @@ struct stream_interface { struct sockaddr *, struct sockaddr *); /* connect function if any */ void (*iohandler)(struct stream_interface *); /* internal I/O handler when embedded */ struct buffer *ib, *ob; /* input and output buffers */ + int conn_retries; /* number of connect retries left */ unsigned int err_type; /* first error detected, one of SI_ET_* */ void *err_loc; /* commonly the server, NULL when SI_ET_NONE */ void *private; /* may be used by any function above */ diff --git a/src/dumpstats.c b/src/dumpstats.c index bbda255f19..dee7aa4a0e 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -2540,7 +2540,7 @@ int stats_dump_full_sess_to_buffer(struct session *s, struct buffer *rep) chunk_printf(&msg, " flags=0x%x, conn_retries=%d, srv_conn=%p, pend_pos=%p\n", - sess->flags, sess->conn_retries, sess->srv_conn, sess->pend_pos); + sess->flags, sess->si[1].conn_retries, sess->srv_conn, sess->pend_pos); chunk_printf(&msg, " frontend=%s (id=%u mode=%s), listener=%s (id=%u)\n", diff --git a/src/frontend.c b/src/frontend.c index 9bd793f754..d51f2fdead 100644 --- a/src/frontend.c +++ b/src/frontend.c @@ -157,7 +157,7 @@ int frontend_accept(struct listener *l, int cfd, struct sockaddr_storage *addr) s->srv = s->prev_srv = s->srv_conn = NULL; s->pend_pos = NULL; - s->conn_retries = s->be->conn_retries; + s->si[1].conn_retries = s->be->conn_retries; /* init store persistence */ s->store_count = 0; diff --git a/src/log.c b/src/log.c index b323d7e89a..25e5f0377b 100644 --- a/src/log.c +++ b/src/log.c @@ -327,7 +327,7 @@ void tcp_sess_log(struct session *s) struct tm tm; /* if we don't want to log normal traffic, return now */ - err = (s->flags & (SN_ERR_MASK | SN_REDISP)) || (s->conn_retries != be->conn_retries); + err = (s->flags & (SN_ERR_MASK | SN_REDISP)) || (s->req->cons->conn_retries != be->conn_retries); if (!err && (fe->options2 & PR_O2_NOLOGNORM)) return; @@ -371,7 +371,7 @@ void tcp_sess_log(struct session *s) sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT], actconn, fe->feconn, be->beconn, s->srv ? s->srv->cur_sess : 0, (s->flags & SN_REDISP)?"+":"", - (s->conn_retries>0)?(be->conn_retries - s->conn_retries):be->conn_retries, + (s->req->cons->conn_retries>0)?(be->conn_retries - s->req->cons->conn_retries):be->conn_retries, s->logs.srv_queue_size, s->logs.prx_queue_size); s->logs.logwait = 0; diff --git a/src/proto_http.c b/src/proto_http.c index a1ff02c84a..280abf725c 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -860,7 +860,7 @@ void http_sess_clflog(struct session *s) prx_log = fe; err = (s->flags & (SN_ERR_MASK | SN_REDISP)) || - (s->conn_retries != be->conn_retries) || + (s->req->cons->conn_retries != be->conn_retries) || txn->status >= 500; if (s->cli_addr.ss_family == AF_INET) @@ -976,7 +976,7 @@ void http_sess_clflog(struct session *s) w = snprintf(h, sizeof(tmpline) - (h - tmpline), " %d %d %d %d %d %ld %ld", actconn, fe->feconn, be->beconn, s->srv ? s->srv->cur_sess : 0, - (s->conn_retries > 0) ? (be->conn_retries - s->conn_retries) : be->conn_retries, + (s->req->cons->conn_retries > 0) ? (be->conn_retries - s->req->cons->conn_retries) : be->conn_retries, s->logs.srv_queue_size, s->logs.prx_queue_size); if (w < 0 || w >= sizeof(tmpline) - (h - tmpline)) @@ -1082,7 +1082,7 @@ void http_sess_log(struct session *s) /* if we don't want to log normal traffic, return now */ err = (s->flags & (SN_ERR_MASK | SN_REDISP)) || - (s->conn_retries != be->conn_retries) || + (s->req->cons->conn_retries != be->conn_retries) || txn->status >= 500; if (!err && (fe->options2 & PR_O2_NOLOGNORM)) return; @@ -1187,7 +1187,7 @@ void http_sess_log(struct session *s) (be->options & PR_O_COOK_ANY) ? sess_set_cookie[(txn->flags & TX_SCK_MASK) >> TX_SCK_SHIFT] : '-', actconn, fe->feconn, be->beconn, s->srv ? s->srv->cur_sess : 0, (s->flags & SN_REDISP)?"+":"", - (s->conn_retries>0)?(be->conn_retries - s->conn_retries):be->conn_retries, + (s->req->cons->conn_retries>0)?(be->conn_retries - s->req->cons->conn_retries):be->conn_retries, s->logs.srv_queue_size, s->logs.prx_queue_size, tmpline); s->logs.logwait = 0; @@ -6726,7 +6726,7 @@ void http_reset_txn(struct session *s) s->store_count = 0; s->pend_pos = NULL; - s->conn_retries = s->be->conn_retries; + s->req->cons->conn_retries = s->be->conn_retries; s->req->flags |= BF_READ_DONTWAIT; /* one read is usually enough */ diff --git a/src/proxy.c b/src/proxy.c index 98ff94db36..cd7f68289b 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -719,7 +719,7 @@ int session_set_backend(struct session *s, struct proxy *be) proxy_inc_be_ctr(be); /* assign new parameters to the session from the new backend */ - s->conn_retries = be->conn_retries; + s->si[1].conn_retries = be->conn_retries; s->si[1].flags &= ~SI_FL_INDEP_STR; if (be->options2 & PR_O2_INDEPSTR) s->si[1].flags |= SI_FL_INDEP_STR; diff --git a/src/session.c b/src/session.c index 08bb4c315e..79432cf1d1 100644 --- a/src/session.c +++ b/src/session.c @@ -254,8 +254,8 @@ int sess_update_st_cer(struct session *s, struct stream_interface *si) } /* ensure that we have enough retries left */ - s->conn_retries--; - if (s->conn_retries < 0) { + si->conn_retries--; + if (si->conn_retries < 0) { if (!si->err_type) { si->err_type = SI_ET_CONN_ERR; si->err_loc = s->srv; @@ -284,7 +284,7 @@ int sess_update_st_cer(struct session *s, struct stream_interface *si) * bit to ignore any persistence cookie. We won't count a retry nor a * redispatch yet, because this will depend on what server is selected. */ - if (s->srv && s->conn_retries == 0 && + if (s->srv && si->conn_retries == 0 && s->be->options & PR_O_REDISP && !(s->flags & SN_FORCE_PRST)) { if (may_dequeue_tasks(s->srv, s->be)) process_srv_queue(s->srv); @@ -970,7 +970,7 @@ resync_stream_interface: s->req->flags, s->rep->flags, s->req->l, s->rep->l, s->rep->cons->state, s->req->cons->state, s->rep->cons->err_type, s->req->cons->err_type, - s->conn_retries); + s->req->cons->conn_retries); /* nothing special to be done on client side */ if (unlikely(s->req->prod->state == SI_ST_DIS))