mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 22:01:31 +02:00
[MEDIUM] reintroduce BF_HIJACK with produce_content
The stats dump are back. Even very large config files with 5000 servers work fast and well. The SN_SELF_GEN flag has completely been removed.
This commit is contained in:
parent
36e6a41bc8
commit
72b179a53c
@ -108,6 +108,18 @@ static inline void buffer_abort(struct buffer *buf)
|
|||||||
buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
|
buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set the buffer to hijacking mode */
|
||||||
|
static inline void buffer_start_hijack(struct buffer *buf)
|
||||||
|
{
|
||||||
|
buf->flags |= BF_HIJACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* releases the buffer from hijacking mode */
|
||||||
|
static inline void buffer_stop_hijack(struct buffer *buf)
|
||||||
|
{
|
||||||
|
buf->flags &= ~BF_HIJACK;
|
||||||
|
}
|
||||||
|
|
||||||
/* returns the maximum number of bytes writable at once in this buffer */
|
/* returns the maximum number of bytes writable at once in this buffer */
|
||||||
static inline int buffer_max(const struct buffer *buf)
|
static inline int buffer_max(const struct buffer *buf)
|
||||||
{
|
{
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
#define BF_MASK_INTERFACE (BF_MASK_INTF_I | BF_MASK_INTF_O)
|
#define BF_MASK_INTERFACE (BF_MASK_INTF_I | BF_MASK_INTF_O)
|
||||||
|
|
||||||
#define BF_MASK_ANALYSER (BF_FULL|BF_READ_NULL|BF_READ_ERROR|BF_READ_TIMEOUT|BF_SHUTR|BF_WRITE_ERROR)
|
#define BF_MASK_ANALYSER (BF_FULL|BF_READ_NULL|BF_READ_ERROR|BF_READ_TIMEOUT|BF_SHUTR|BF_WRITE_ERROR)
|
||||||
|
#define BF_MASK_INJECTER (BF_FULL|BF_WRITE_STATUS|BF_WRITE_TIMEOUT|BF_SHUTW)
|
||||||
|
|
||||||
/* Analysers (buffer->analysers).
|
/* Analysers (buffer->analysers).
|
||||||
* Those bits indicate that there are some processing to do on the buffer
|
* Those bits indicate that there are some processing to do on the buffer
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
#define SN_BE_ASSIGNED 0x00000008 /* a backend was assigned. Conns are accounted. */
|
#define SN_BE_ASSIGNED 0x00000008 /* a backend was assigned. Conns are accounted. */
|
||||||
#define SN_CONN_CLOSED 0x00000010 /* "Connection: close" was present or added */
|
#define SN_CONN_CLOSED 0x00000010 /* "Connection: close" was present or added */
|
||||||
#define SN_MONITOR 0x00000020 /* this session comes from a monitoring system */
|
#define SN_MONITOR 0x00000020 /* this session comes from a monitoring system */
|
||||||
#define SN_SELF_GEN 0x00000040 /* the proxy generates data for the client (eg: stats) */
|
/* unused: 0x00000040 */
|
||||||
#define SN_FRT_ADDR_SET 0x00000080 /* set if the frontend address has been filled */
|
#define SN_FRT_ADDR_SET 0x00000080 /* set if the frontend address has been filled */
|
||||||
#define SN_REDISP 0x00000100 /* set if this session was redispatched from one server to another */
|
#define SN_REDISP 0x00000100 /* set if this session was redispatched from one server to another */
|
||||||
#define SN_CONN_TAR 0x00000200 /* set if this session is turning around before reconnecting */
|
#define SN_CONN_TAR 0x00000200 /* set if this session is turning around before reconnecting */
|
||||||
|
@ -290,7 +290,7 @@ int stats_dump_raw(struct session *s, struct uri_auth *uri)
|
|||||||
/*
|
/*
|
||||||
* Produces statistics data for the session <s>. Expects to be called with
|
* Produces statistics data for the session <s>. Expects to be called with
|
||||||
* client socket shut down on input. It stops by itself by unsetting the
|
* client socket shut down on input. It stops by itself by unsetting the
|
||||||
* SN_SELF_GEN flag from the session, which it uses to keep on being called
|
* BF_HIJACK flag from the buffer, which it uses to keep on being called
|
||||||
* when there is free space in the buffer, of simply by letting an empty buffer
|
* when there is free space in the buffer, of simply by letting an empty buffer
|
||||||
* upon return.s->data_ctx must have been zeroed before the first call, and the
|
* upon return.s->data_ctx must have been zeroed before the first call, and the
|
||||||
* flags set. It returns 0 if it had to stop writing data and an I/O is needed,
|
* flags set. It returns 0 if it had to stop writing data and an I/O is needed,
|
||||||
@ -310,7 +310,7 @@ int stats_dump_http(struct session *s, struct uri_auth *uri)
|
|||||||
switch (s->data_state) {
|
switch (s->data_state) {
|
||||||
case DATA_ST_INIT:
|
case DATA_ST_INIT:
|
||||||
/* the function had not been called yet */
|
/* the function had not been called yet */
|
||||||
s->flags |= SN_SELF_GEN; // more data will follow
|
buffer_start_hijack(rep);
|
||||||
|
|
||||||
chunk_printf(&msg, sizeof(trash),
|
chunk_printf(&msg, sizeof(trash),
|
||||||
"HTTP/1.0 200 OK\r\n"
|
"HTTP/1.0 200 OK\r\n"
|
||||||
@ -337,7 +337,7 @@ int stats_dump_http(struct session *s, struct uri_auth *uri)
|
|||||||
if (s->txn.meth == HTTP_METH_HEAD) {
|
if (s->txn.meth == HTTP_METH_HEAD) {
|
||||||
/* that's all we return in case of HEAD request */
|
/* that's all we return in case of HEAD request */
|
||||||
s->data_state = DATA_ST_FIN;
|
s->data_state = DATA_ST_FIN;
|
||||||
s->flags &= ~SN_SELF_GEN;
|
buffer_stop_hijack(rep);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -570,12 +570,12 @@ int stats_dump_http(struct session *s, struct uri_auth *uri)
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case DATA_ST_FIN:
|
case DATA_ST_FIN:
|
||||||
s->flags &= ~SN_SELF_GEN;
|
buffer_stop_hijack(rep);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* unknown state ! */
|
/* unknown state ! */
|
||||||
s->flags &= ~SN_SELF_GEN;
|
buffer_stop_hijack(rep);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -772,15 +772,25 @@ void process_session(struct task *t, int *next)
|
|||||||
rqf_req = s->req->flags;
|
rqf_req = s->req->flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rpf_rep ^ s->rep->flags) & BF_MASK_ANALYSER) {
|
if (unlikely(s->rep->flags & BF_HIJACK)) {
|
||||||
/* the analysers must block it themselves */
|
/* In inject mode, we wake up everytime something has
|
||||||
if (s->rep->prod->state >= SI_ST_EST) {
|
* happened on the write side of the buffer.
|
||||||
|
*/
|
||||||
|
if ((s->rep->flags & (BF_PARTIAL_WRITE|BF_WRITE_ERROR|BF_SHUTW)) &&
|
||||||
|
!(s->rep->flags & BF_FULL)) {
|
||||||
|
if (produce_content(s) != 0)
|
||||||
|
resync = 1; /* completed, better re-check flags */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (s->rep->prod->state >= SI_ST_EST) {
|
||||||
|
if ((rpf_rep ^ s->rep->flags) & BF_MASK_ANALYSER) {
|
||||||
|
/* the analysers must block it themselves */
|
||||||
resync = 1;
|
resync = 1;
|
||||||
s->rep->flags |= BF_MAY_FORWARD;
|
s->rep->flags |= BF_MAY_FORWARD;
|
||||||
if (s->rep->analysers)
|
if (s->rep->analysers)
|
||||||
process_response(s);
|
process_response(s);
|
||||||
|
rpf_rep = s->rep->flags;
|
||||||
}
|
}
|
||||||
rpf_rep = s->rep->flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (resync);
|
} while (resync);
|
||||||
@ -3895,15 +3905,15 @@ int process_srv_conn(struct session *t)
|
|||||||
/*
|
/*
|
||||||
* Produces data for the session <s> depending on its source. Expects to be
|
* Produces data for the session <s> depending on its source. Expects to be
|
||||||
* called with client socket shut down on input. Right now, only statistics can
|
* called with client socket shut down on input. Right now, only statistics can
|
||||||
* be produced. It stops by itself by unsetting the SN_SELF_GEN flag from the
|
* be produced. It stops by itself by unsetting the BF_HIJACK flag from the
|
||||||
* session, which it uses to keep on being called when there is free space in
|
* buffer, which it uses to keep on being called when there is free space in
|
||||||
* the buffer, or simply by letting an empty buffer upon return. It returns 1
|
* the buffer, or simply by letting an empty buffer upon return. It returns 1
|
||||||
* when it wants to stop sending data, otherwise 0.
|
* when it wants to stop sending data, otherwise 0.
|
||||||
*/
|
*/
|
||||||
int produce_content(struct session *s)
|
int produce_content(struct session *s)
|
||||||
{
|
{
|
||||||
if (s->data_source == DATA_SRC_NONE) {
|
if (s->data_source == DATA_SRC_NONE) {
|
||||||
s->flags &= ~SN_SELF_GEN;
|
buffer_stop_hijack(s->rep);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (s->data_source == DATA_SRC_STATS) {
|
else if (s->data_source == DATA_SRC_STATS) {
|
||||||
@ -3922,7 +3932,7 @@ int produce_content(struct session *s)
|
|||||||
s->flags |= SN_ERR_PRXCOND;
|
s->flags |= SN_ERR_PRXCOND;
|
||||||
if (!(s->flags & SN_FINST_MASK))
|
if (!(s->flags & SN_FINST_MASK))
|
||||||
s->flags |= SN_FINST_R;
|
s->flags |= SN_FINST_R;
|
||||||
s->flags &= ~SN_SELF_GEN;
|
buffer_stop_hijack(s->rep);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5297,10 +5307,9 @@ int stats_check_uri_auth(struct session *t, struct proxy *backend)
|
|||||||
/* The request is valid, the user is authenticated. Let's start sending
|
/* The request is valid, the user is authenticated. Let's start sending
|
||||||
* data.
|
* data.
|
||||||
*/
|
*/
|
||||||
EV_FD_CLR(t->req->prod->fd, DIR_RD);
|
buffer_shutw_now(t->req);
|
||||||
buffer_shutr(t->req);
|
buffer_shutr_now(t->rep);
|
||||||
buffer_shutr(t->rep);
|
buffer_start_hijack(t->rep);
|
||||||
buffer_set_rlim(t->req, BUFSIZE); /* no more rewrite needed */
|
|
||||||
t->logs.tv_request = now;
|
t->logs.tv_request = now;
|
||||||
t->data_source = DATA_SRC_STATS;
|
t->data_source = DATA_SRC_STATS;
|
||||||
t->data_state = DATA_ST_INIT;
|
t->data_state = DATA_ST_INIT;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user