]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: trace: automatically start in waiting mode with "start <evt>"
authorWilly Tarreau <w@1wt.eu>
Tue, 6 Aug 2024 09:45:54 +0000 (11:45 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 7 Aug 2024 14:02:59 +0000 (16:02 +0200)
The doc clearly says that "start <evt>" should leave the trace in pause
mode until the indicated event appears. However it's not what's happening,
the state is not changed until one command uses "now", so it's typically
needed to configure the events with "start <evt>" then enable the waiting
mode using "pause now". This is counter-intuitive and does not match the
doc, so let's fix it so that "start <evt>" switches from stopped to waiting
as long as at least one event is enabled.

This can be backported to all versions.

src/trace.c

index 8f6519dfb9307779bc3009a126bab05872481ec7..2d1257c9762fe4522234ace9c5d4acc5b24398eb 100644 (file)
@@ -508,6 +508,13 @@ static int trace_parse_statement(char **args, char **msg)
                        return LOG_WARNING;
                }
 
+               /* state transitions:
+                *   - "start now" => TRACE_STATE_RUNNING
+                *   - "stop now"  => TRACE_STATE_STOPPED
+                *   - "pause now" => TRACE_STATE_WAITING
+                *   - "start <evt>" && STATE_STOPPED => TRACE_STATE_WAITING
+                */
+
                if (strcmp(name, "now") == 0 && ev_ptr != &src->report_events) {
                        HA_ATOMIC_STORE(ev_ptr, 0);
                        if (ev_ptr == &src->pause_events) {
@@ -526,9 +533,16 @@ static int trace_parse_statement(char **args, char **msg)
 
                if (strcmp(name, "none") == 0)
                        HA_ATOMIC_STORE(ev_ptr, 0);
-               else if (strcmp(name, "any") == 0)
+               else if (strcmp(name, "any") == 0) {
+                       enum trace_state old = TRACE_STATE_STOPPED;
+
                        HA_ATOMIC_STORE(ev_ptr, ~0);
+                       if (ev_ptr == &src->start_events)
+                               HA_ATOMIC_CAS(&src->state, &old, TRACE_STATE_WAITING);
+               }
                else {
+                       enum trace_state old = TRACE_STATE_STOPPED;
+
                        ev = trace_find_event(src->known_events, name);
                        if (!ev) {
                                memprintf(msg, "No such trace event '%s'", name);
@@ -539,6 +553,9 @@ static int trace_parse_statement(char **args, char **msg)
                                HA_ATOMIC_OR(ev_ptr, ev->mask);
                        else
                                HA_ATOMIC_AND(ev_ptr, ~ev->mask);
+
+                       if (ev_ptr == &src->start_events && HA_ATOMIC_LOAD(ev_ptr) != 0)
+                               HA_ATOMIC_CAS(&src->state, &old, TRACE_STATE_WAITING);
                }
        }
        else if (strcmp(args[2], "sink") == 0) {