diff --git a/include/haproxy/hstream-t.h b/include/haproxy/hstream-t.h index 2eae26a60..8ac52be64 100644 --- a/include/haproxy/hstream-t.h +++ b/include/haproxy/hstream-t.h @@ -5,6 +5,11 @@ #include #include +/* Size in bytes of the prebuilts response buffers */ +#define RESPSIZE 16384 +/* Number of bytes by body response line */ +#define HS_COMMON_RESPONSE_LINE_SZ 50 + /* hastream stream */ struct hstream { enum obj_type obj_type; diff --git a/include/haproxy/hstream.h b/include/haproxy/hstream.h index 7ba0d4d14..20bffd325 100644 --- a/include/haproxy/hstream.h +++ b/include/haproxy/hstream.h @@ -5,7 +5,6 @@ #include struct task *sc_hstream_io_cb(struct task *t, void *ctx, unsigned int state); -void hstream_shutdown(struct stconn *sc); void *hstream_new(struct session *sess, struct stconn *sc, struct buffer *input); #endif /* _HAPROXY_HSTREAM_H */ diff --git a/src/haterm.c b/src/haterm.c index a3b50aec9..a8c07d41e 100644 --- a/src/haterm.c +++ b/src/haterm.c @@ -63,14 +63,10 @@ const char *HTTP_HELP = " - GET /?r=500?s=0?c=0?t=1000 HTTP/1.0\n" "\n"; -/* Size in bytes of the prebuilts response buffers */ -#define RESPSIZE 16384 -/* Number of bytes by body response line */ -#define HS_COMMON_RESPONSE_LINE_SZ 50 -static char common_response[RESPSIZE]; -static char common_chunk_resp[RESPSIZE]; -static char *random_resp; -static int random_resp_len = RESPSIZE; +char common_response[RESPSIZE]; +char common_chunk_resp[RESPSIZE]; +char *random_resp; +int random_resp_len = RESPSIZE; #if defined(USE_LINUX_SPLICE) struct pipe *master_pipe = NULL; @@ -1167,92 +1163,3 @@ void *hstream_new(struct session *sess, struct stconn *sc, struct buffer *input) TRACE_DEVEL("leaving on error", HS_EV_HSTRM_NEW); return NULL; } - -/* Build the response buffers. - * Return 1 if succeeded, -1 if failed. - */ -static int hstream_build_responses(void) -{ - int i; - - for (i = 0; i < sizeof(common_response); i++) { - if (i % HS_COMMON_RESPONSE_LINE_SZ == HS_COMMON_RESPONSE_LINE_SZ - 1) - common_response[i] = '\n'; - else if (i % 10 == 0) - common_response[i] = '.'; - else - common_response[i] = '0' + i % 10; - } - - /* original haterm chunk mode responses are made of 1-byte chunks - * but the haproxy muxes do not support this. At this time - * these responses are handled the same way as for common - * responses with a pre-built buffer. - */ - for (i = 0; i < sizeof(common_chunk_resp); i++) - common_chunk_resp[i] = '1'; - - random_resp = malloc(random_resp_len); - if (!random_resp) { - ha_alert("not enough memory...\n"); - return -1; - } - - for (i = 0; i < random_resp_len; i++) - random_resp[i] = ha_random32() >> 16; - - return 1; -} - -#if defined(USE_LINUX_SPLICE) -static void hstream_init_splicing(void) -{ - if (!(global.tune.options & GTUNE_USE_SPLICE)) - return; - - if (!global.tune.pipesize) - global.tune.pipesize = 65536 * 5 / 4; - - master_pipe = get_pipe(); - if (master_pipe) { - struct iovec v = { .iov_base = common_response, - .iov_len = sizeof(common_response) }; - int total, ret; - - total = ret = 0; - do { - ret = vmsplice(master_pipe->prod, &v, 1, SPLICE_F_NONBLOCK); - if (ret > 0) - total += ret; - } while (ret > 0 && total < global.tune.pipesize); - master_pipesize = total; - - if (master_pipesize < global.tune.pipesize) { - if (master_pipesize < 60*1024) { - /* Older kernels were limited to around 60-61 kB */ - ha_warning("Failed to vmsplice response buffer after %lu bytes, splicing disabled\n", master_pipesize); - global.tune.options &= ~GTUNE_USE_SPLICE; - put_pipe(master_pipe); - master_pipe = NULL; - } - else - ha_warning("Splicing is limited to %lu bytes (too old kernel)\n", master_pipesize); - } - } - else { - ha_warning("Unable to allocate master pipe for splicing, splicing disabled\n"); - global.tune.options &= ~GTUNE_USE_SPLICE; - } -} - -static void hstream_deinit(void) -{ - if (master_pipe) - put_pipe(master_pipe); -} - -REGISTER_POST_DEINIT(hstream_deinit); -INITCALL0(STG_INIT_2, hstream_init_splicing); -#endif - -REGISTER_POST_CHECK(hstream_build_responses); diff --git a/src/haterm_init.c b/src/haterm_init.c index 06752c4ca..962ae8474 100644 --- a/src/haterm_init.c +++ b/src/haterm_init.c @@ -1,8 +1,14 @@ +#define _GNU_SOURCE +#include + #include #include #include #include #include +#include +#include +#include #include static int haterm_debug; @@ -497,3 +503,103 @@ char **copy_argv(int argc, char **argv) return ret; } + + +#if defined(USE_LINUX_SPLICE) + +extern struct pipe *master_pipe; +extern size_t master_pipesize; + +extern char common_response[RESPSIZE]; +extern char common_chunk_resp[RESPSIZE]; +extern char *random_resp; +extern int random_resp_len; + +static void hstream_init_splicing(void) +{ + if (!(global.tune.options & GTUNE_USE_SPLICE)) + return; + + if (!global.tune.pipesize) + global.tune.pipesize = 65536 * 5 / 4; + + master_pipe = get_pipe(); + if (master_pipe) { + struct iovec v = { .iov_base = common_response, + .iov_len = sizeof(common_response) }; + int total, ret; + + total = ret = 0; + do { + ret = vmsplice(master_pipe->prod, &v, 1, SPLICE_F_NONBLOCK); + if (ret > 0) + total += ret; + } while (ret > 0 && total < global.tune.pipesize); + master_pipesize = total; + + if (master_pipesize < global.tune.pipesize) { + if (master_pipesize < 60*1024) { + /* Older kernels were limited to around 60-61 kB */ + ha_warning("Failed to vmsplice response buffer after %lu bytes, splicing disabled\n", master_pipesize); + global.tune.options &= ~GTUNE_USE_SPLICE; + put_pipe(master_pipe); + master_pipe = NULL; + } + else + ha_warning("Splicing is limited to %lu bytes (too old kernel)\n", master_pipesize); + } + } + else { + ha_warning("Unable to allocate master pipe for splicing, splicing disabled\n"); + global.tune.options &= ~GTUNE_USE_SPLICE; + } +} + +static void hstream_deinit(void) +{ + if (master_pipe) + put_pipe(master_pipe); +} + +REGISTER_POST_DEINIT(hstream_deinit); +INITCALL0(STG_INIT_2, hstream_init_splicing); + +/* Build the response buffers. + * Return 1 if succeeded, -1 if failed. + */ +static int hstream_build_responses(void) +{ + int i; + + for (i = 0; i < sizeof(common_response); i++) { + if (i % HS_COMMON_RESPONSE_LINE_SZ == HS_COMMON_RESPONSE_LINE_SZ - 1) + common_response[i] = '\n'; + else if (i % 10 == 0) + common_response[i] = '.'; + else + common_response[i] = '0' + i % 10; + } + + /* original haterm chunk mode responses are made of 1-byte chunks + * but the haproxy muxes do not support this. At this time + * these responses are handled the same way as for common + * responses with a pre-built buffer. + */ + for (i = 0; i < sizeof(common_chunk_resp); i++) + common_chunk_resp[i] = '1'; + + random_resp = malloc(random_resp_len); + if (!random_resp) { + ha_alert("not enough memory...\n"); + return -1; + } + + for (i = 0; i < random_resp_len; i++) + random_resp[i] = ha_random32() >> 16; + + return 1; +} + +REGISTER_POST_CHECK(hstream_build_responses); + +#endif