BUG/MINOR: trace: automatically start in waiting mode with "start <evt>"

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.

(cherry picked from commit 0406efe9ad129e91f8a6c93b780064b3c27ccaa0)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 830fcd308217f0753ea089837a176cda77c80113)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit ceeca03b0eca581b5cfcd2fef39816f0739d8048)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/trace.c b/src/trace.c
index c045a32..e5da88e 100644
--- a/src/trace.c
+++ b/src/trace.c
@@ -447,6 +447,13 @@
 			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) {
@@ -465,9 +472,16 @@
 
 		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);
@@ -478,6 +492,9 @@
 				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) {