]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: haterm: Move all init functions of haterm in haterm_init.c
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 3 Apr 2026 10:20:20 +0000 (12:20 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 3 Apr 2026 13:09:44 +0000 (15:09 +0200)
Functions used to initialize haterm (the splicing and the response buffers)
were defined and registered in haterm.c. The problem is that this file in
compiled with haproxy. So it may be an issue. And for the splicing part,
warnings may be emitted when haproxy is started.

To avoid any issue during haproxy startup and to avoid to initialize some
part of haterm, all init functions were moved into haterm_init.c file.

No backport needed.

include/haproxy/hstream-t.h
include/haproxy/hstream.h
src/haterm.c
src/haterm_init.c

index 2eae26a60f8269734958c1118a0310e9e3838bab..8ac52be64697ab8aa5372c99b95ff73154bba112 100644 (file)
@@ -5,6 +5,11 @@
 #include <haproxy/http-t.h>
 #include <haproxy/obj_type-t.h>
 
+/* 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;
index 7ba0d4d14a52072f324d7e5307ce9ac3abac8d60..20bffd3256bbdc9a7716bbe5e9242f173df11a64 100644 (file)
@@ -5,7 +5,6 @@
 #include <haproxy/hstream-t.h>
 
 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 */
index a3b50aec933fd7c93929ed54ed20957ad3b2e1ff..a8c07d41ef41d2958d88f6a7fd6f5e20de76d754 100644 (file)
@@ -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);
index 06752c4ca2072b75b5e1072608689cc2f818ce93..962ae84746d0af06d522484ef58d189b79d0ce40 100644 (file)
@@ -1,8 +1,14 @@
+#define _GNU_SOURCE
+#include <fcntl.h>
+
 #include <haproxy/api.h>
 #include <haproxy/buf.h>
 #include <haproxy/chunk.h>
 #include <haproxy/errors.h>
 #include <haproxy/global.h>
+#include <haproxy/hstream.h>
+#include <haproxy/pipe.h>
+#include <haproxy/tools.h>
 #include <haproxy/version.h>
 
 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