From 9b6c7ec5aebd1b1e3610ea54bbd0d6d4e9efaa82 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 8 Nov 2012 14:08:28 -0500 Subject: [PATCH] Fix: Enable event after start command Refer to the bug tracker for more information on this bug. In a nutshell, it was not possible to enable channel/event after a start command has been issued (for both kernel and UST). Note that it is still NOT possible to enable a channel after a start but the use case here was the following: $ lttng create $ lttng start $ lttng enable-event -a -u (or -k) The first starts does NOT create a kernel or UST session so the following enable event creates the session for the given domain but failed to start the session after. https://bugs.lttng.org/issues/346 https://bugs.lttng.org/issues/394 Fixes #346 #394 Signed-off-by: David Goulet --- src/bin/lttng-sessiond/cmd.c | 145 +++++++++++++++++--------- src/bin/lttng-sessiond/session.h | 3 + src/bin/lttng-sessiond/trace-kernel.h | 2 + 3 files changed, 102 insertions(+), 48 deletions(-) diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 46a758e27..e4e03e88c 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -670,6 +670,71 @@ error: return ret; } +/* + * Start a kernel session by opening all necessary streams. + */ +static int start_kernel_session(struct ltt_kernel_session *ksess, int wpipe) +{ + int ret; + struct ltt_kernel_channel *kchan; + + /* Open kernel metadata */ + if (ksess->metadata == NULL) { + ret = kernel_open_metadata(ksess); + if (ret < 0) { + ret = LTTNG_ERR_KERN_META_FAIL; + goto error; + } + } + + /* Open kernel metadata stream */ + if (ksess->metadata_stream_fd < 0) { + ret = kernel_open_metadata_stream(ksess); + if (ret < 0) { + ERR("Kernel create metadata stream failed"); + ret = LTTNG_ERR_KERN_STREAM_FAIL; + goto error; + } + } + + /* For each channel */ + cds_list_for_each_entry(kchan, &ksess->channel_list.head, list) { + if (kchan->stream_count == 0) { + ret = kernel_open_channel_stream(kchan); + if (ret < 0) { + ret = LTTNG_ERR_KERN_STREAM_FAIL; + goto error; + } + /* Update the stream global counter */ + ksess->stream_count_global += ret; + } + } + + /* Setup kernel consumer socket and send fds to it */ + ret = init_kernel_tracing(ksess); + if (ret < 0) { + ret = LTTNG_ERR_KERN_START_FAIL; + goto error; + } + + /* This start the kernel tracing */ + ret = kernel_start_session(ksess); + if (ret < 0) { + ret = LTTNG_ERR_KERN_START_FAIL; + goto error; + } + + /* Quiescent wait after starting trace */ + kernel_wait_quiescent(wpipe); + + ksess->started = 1; + + ret = LTTNG_OK; + +error: + return ret; +} + /* * Command LTTNG_DISABLE_CHANNEL processed by the client thread. */ @@ -765,7 +830,19 @@ int cmd_enable_channel(struct ltt_session *session, goto error; } - kernel_wait_quiescent(kernel_tracer_fd); + kernel_wait_quiescent(wpipe); + + /* + * If the session was previously started, start as well this newly + * created kernel session so the events/channels enabled *after* the + * start actually work. + */ + if (session->started && !session->kernel_session->started) { + ret = start_kernel_session(session->kernel_session, wpipe); + if (ret != LTTNG_OK) { + goto error; + } + } break; } case LTTNG_DOMAIN_UST: @@ -780,6 +857,17 @@ int cmd_enable_channel(struct ltt_session *session, } else { ret = channel_ust_enable(usess, domain, uchan); } + + /* Start the UST session if the session was already started. */ + if (session->started && !usess->start_trace) { + ret = ust_app_start_trace_all(usess); + if (ret < 0) { + ret = LTTNG_ERR_UST_START_FAIL; + goto error; + } + ret = LTTNG_OK; + usess->start_trace = 1; + } break; } #if 0 @@ -1378,7 +1466,6 @@ int cmd_start_trace(struct ltt_session *session) int ret; struct ltt_kernel_session *ksession; struct ltt_ust_session *usess; - struct ltt_kernel_channel *kchan; assert(session); @@ -1402,54 +1489,10 @@ int cmd_start_trace(struct ltt_session *session) /* Kernel tracing */ if (ksession != NULL) { - /* Open kernel metadata */ - if (ksession->metadata == NULL) { - ret = kernel_open_metadata(ksession); - if (ret < 0) { - ret = LTTNG_ERR_KERN_META_FAIL; - goto error; - } - } - - /* Open kernel metadata stream */ - if (ksession->metadata_stream_fd < 0) { - ret = kernel_open_metadata_stream(ksession); - if (ret < 0) { - ERR("Kernel create metadata stream failed"); - ret = LTTNG_ERR_KERN_STREAM_FAIL; - goto error; - } - } - - /* For each channel */ - cds_list_for_each_entry(kchan, &ksession->channel_list.head, list) { - if (kchan->stream_count == 0) { - ret = kernel_open_channel_stream(kchan); - if (ret < 0) { - ret = LTTNG_ERR_KERN_STREAM_FAIL; - goto error; - } - /* Update the stream global counter */ - ksession->stream_count_global += ret; - } - } - - /* Setup kernel consumer socket and send fds to it */ - ret = init_kernel_tracing(ksession); - if (ret < 0) { - ret = LTTNG_ERR_KERN_START_FAIL; - goto error; - } - - /* This start the kernel tracing */ - ret = kernel_start_session(ksession); - if (ret < 0) { - ret = LTTNG_ERR_KERN_START_FAIL; + ret = start_kernel_session(ksession, kernel_tracer_fd); + if (ret != LTTNG_OK) { goto error; } - - /* Quiescent wait after starting trace */ - kernel_wait_quiescent(kernel_tracer_fd); } /* Flag session that trace should start automatically */ @@ -1463,6 +1506,8 @@ int cmd_start_trace(struct ltt_session *session) } } + session->started = 1; + ret = LTTNG_OK; error: @@ -1519,6 +1564,8 @@ int cmd_stop_trace(struct ltt_session *session) } kernel_wait_quiescent(kernel_tracer_fd); + + ksession->started = 0; } if (usess) { @@ -1531,6 +1578,8 @@ int cmd_stop_trace(struct ltt_session *session) } } + session->started = 0; + ret = LTTNG_OK; error: diff --git a/src/bin/lttng-sessiond/session.h b/src/bin/lttng-sessiond/session.h index 1b40373e9..8a3504f43 100644 --- a/src/bin/lttng-sessiond/session.h +++ b/src/bin/lttng-sessiond/session.h @@ -85,6 +85,9 @@ struct ltt_session { /* Indicates whether or not we have to spawn consumer(s) */ unsigned int start_consumer; + + /* Did a start command occured before the kern/ust session creation? */ + unsigned int started; }; /* Prototypes */ diff --git a/src/bin/lttng-sessiond/trace-kernel.h b/src/bin/lttng-sessiond/trace-kernel.h index 96a3664b4..ed5b33189 100644 --- a/src/bin/lttng-sessiond/trace-kernel.h +++ b/src/bin/lttng-sessiond/trace-kernel.h @@ -110,6 +110,8 @@ struct ltt_kernel_session { struct consumer_output *tmp_consumer; /* Tracing session id */ unsigned int id; + /* Session is started and active */ + unsigned int started; }; /* -- 2.34.1