|
commit f41ca2546e3c35cc389f45428341ec03dade314d
|
|
Author: Willy Tarreau <w@1wt.eu>
|
|
Date: Thu Aug 2 11:05:48 2018 +0200
|
|
|
|
BUG/MEDIUM: cli: make "show fd" thread-safe
|
|
|
|
The "show fd" command was implemented as a debugging aid but it's not
|
|
thread safe. Its features have grown, it can now dump some mux-specific
|
|
parts and is being used in production to capture some useful debugging
|
|
traces. But it will quickly crash the process when used during an H2 load
|
|
test for example, especially when haproxy is built with the DEBUG_UAF
|
|
option. It cannot afford not to be thread safe anymore. Let's make use
|
|
of the new rendez-vous point using thread_isolate() / thread_release()
|
|
to ensure that the data being dumped are not changing under us. The dump
|
|
becomes slightly slower under load but now it's safe.
|
|
|
|
This should be backported to 1.8 along with the rendez-vous point code
|
|
once considered stable enough.
|
|
(cherry picked from commit bf9fd650883b23604b7cd4aabf04fc0c4c8fe7c7)
|
|
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
|
|
|
diff --git a/src/cli.c b/src/cli.c
|
|
index 233c2323..8344fe10 100644
|
|
--- a/src/cli.c
|
|
+++ b/src/cli.c
|
|
@@ -787,10 +787,14 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
|
|
void *ctx = NULL;
|
|
uint32_t conn_flags = 0;
|
|
|
|
+ thread_isolate();
|
|
+
|
|
fdt = fdtab[fd];
|
|
|
|
- if (!fdt.owner)
|
|
+ if (!fdt.owner) {
|
|
+ thread_release();
|
|
goto skip; // closed
|
|
+ }
|
|
|
|
if (fdt.iocb == conn_fd_handler) {
|
|
conn_flags = ((struct connection *)fdt.owner)->flags;
|
|
@@ -855,6 +859,8 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
|
|
li->bind_conf->frontend->id);
|
|
}
|
|
|
|
+ thread_release();
|
|
+
|
|
chunk_appendf(&trash, "\n");
|
|
|
|
if (ci_putchk(si_ic(si), &trash) == -1) {
|