X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=5a122d8d3c8dcf7e7f361b34f69f46c4680c0d22;hp=1dec61ea17b6ba7f74e122e37a7df99afa2e07c6;hb=1f4962443;hpb=e3876bf0e1d1be72170b53e9fcb39f3108f069dc diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 1dec61ea1..5a122d8d3 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -2572,6 +2572,8 @@ int cmd_start_trace(struct ltt_session *session) unsigned long nb_chan = 0; struct ltt_kernel_session *ksession; struct ltt_ust_session *usess; + const bool session_rotated_after_last_stop = + session->rotated_after_last_stop; assert(session); @@ -2585,6 +2587,22 @@ int cmd_start_trace(struct ltt_session *session) goto error; } + if (session->rotation_state == LTTNG_ROTATION_STATE_ONGOING && + !session->current_trace_chunk) { + /* + * A rotation was launched while the session was stopped and + * it has not been completed yet. It is not possible to start + * the session since starting the session here would require a + * rotation from "NULL" to a new trace chunk. That rotation + * would overlap with the ongoing rotation, which is not + * supported. + */ + WARN("Refusing to start session \"%s\" as a rotation launched after the last \"stop\" is still ongoing", + session->name); + ret = LTTNG_ERR_ROTATION_PENDING; + goto error; + } + /* * Starting a session without channel is useless since after that it's not * possible to enable channel thus inform the client. @@ -2600,21 +2618,45 @@ int cmd_start_trace(struct ltt_session *session) goto error; } + session->active = 1; + session->rotated_after_last_stop = false; if (session->output_traces && !session->current_trace_chunk) { - struct lttng_trace_chunk *trace_chunk; + if (!session->has_been_started) { + struct lttng_trace_chunk *trace_chunk; - trace_chunk = session_create_new_trace_chunk( - session, NULL, NULL, NULL); - if (!trace_chunk) { - ret = LTTNG_ERR_CREATE_DIR_FAIL; - goto error; - } - assert(!session->current_trace_chunk); - ret = session_set_trace_chunk(session, trace_chunk, NULL); - lttng_trace_chunk_put(trace_chunk); - if (ret) { - ret = LTTNG_ERR_CREATE_TRACE_CHUNK_FAIL_CONSUMER; - goto error; + DBG("Creating initial trace chunk of session \"%s\"", + session->name); + trace_chunk = session_create_new_trace_chunk( + session, NULL, NULL, NULL); + if (!trace_chunk) { + ret = LTTNG_ERR_CREATE_DIR_FAIL; + goto error; + } + assert(!session->current_trace_chunk); + ret = session_set_trace_chunk(session, trace_chunk, + NULL); + lttng_trace_chunk_put(trace_chunk); + if (ret) { + ret = LTTNG_ERR_CREATE_TRACE_CHUNK_FAIL_CONSUMER; + goto error; + } + } else { + DBG("Rotating session \"%s\" from its current \"NULL\" trace chunk to a new chunk", + session->name); + /* + * Rotate existing streams into the new chunk. + * This is a "quiet" rotation has no client has + * explicitly requested this operation. + * + * There is also no need to wait for the rotation + * to complete as it will happen immediately. No data + * was produced as the session was stopped, so the + * rotation should happen on reception of the command. + */ + ret = cmd_rotate_session(session, NULL, true); + if (ret != LTTNG_OK) { + goto error; + } } } @@ -2637,10 +2679,6 @@ int cmd_start_trace(struct ltt_session *session) } } - /* Flag this after a successful start. */ - session->has_been_started = 1; - session->active = 1; - /* * Clear the flag that indicates that a rotation was done while the * session was stopped. @@ -2661,6 +2699,15 @@ int cmd_start_trace(struct ltt_session *session) ret = LTTNG_OK; error: + if (ret == LTTNG_OK) { + /* Flag this after a successful start. */ + session->has_been_started |= 1; + } else { + session->active = 0; + /* Restore initial state on error. */ + session->rotated_after_last_stop = + session_rotated_after_last_stop; + } return ret; } @@ -2740,24 +2787,15 @@ error: } /* - * Command LTTNG_SET_CONSUMER_URI processed by the client thread. + * Set the base_path of the session only if subdir of a control uris is set. + * Return LTTNG_OK on success, otherwise LTTNG_ERR_*. */ -int cmd_set_consumer_uri(struct ltt_session *session, size_t nb_uri, +static int set_session_base_path_from_uris(struct ltt_session *session, + size_t nb_uri, struct lttng_uri *uris) { - int ret, i; - struct ltt_kernel_session *ksess = session->kernel_session; - struct ltt_ust_session *usess = session->ust_session; - - assert(session); - assert(uris); - assert(nb_uri > 0); - - /* Can't set consumer URI if the session is active. */ - if (session->active) { - ret = LTTNG_ERR_TRACE_ALREADY_STARTED; - goto error; - } + int ret; + size_t i; for (i = 0; i < nb_uri; i++) { if (uris[i].stype != LTTNG_STREAM_CONTROL || @@ -2774,11 +2812,47 @@ int cmd_set_consumer_uri(struct ltt_session *session, size_t nb_uri, /* Set session base_path */ session->base_path = strdup(uris[i].subdir); if (!session->base_path) { - PERROR("Copying base path: %s", uris[i].subdir); + PERROR("Failed to copy base path \"%s\" to session \"%s\"", + uris[i].subdir, session->name); + ret = LTTNG_ERR_NOMEM; goto error; } - DBG2("Setting base path for session %" PRIu64 ": %s", - session->id, session->base_path); + DBG2("Setting base path \"%s\" for session \"%s\"", + session->base_path, session->name); + } + ret = LTTNG_OK; +error: + return ret; +} + +/* + * Command LTTNG_SET_CONSUMER_URI processed by the client thread. + */ +int cmd_set_consumer_uri(struct ltt_session *session, size_t nb_uri, + struct lttng_uri *uris) +{ + int ret, i; + struct ltt_kernel_session *ksess = session->kernel_session; + struct ltt_ust_session *usess = session->ust_session; + + assert(session); + assert(uris); + assert(nb_uri > 0); + + /* Can't set consumer URI if the session is active. */ + if (session->active) { + ret = LTTNG_ERR_TRACE_ALREADY_STARTED; + goto error; + } + + /* + * Set the session base path if any. This is done inside + * cmd_set_consumer_uri to preserve backward compatibility of the + * previous session creation api vs the session descriptor api. + */ + ret = set_session_base_path_from_uris(session, nb_uri, uris); + if (ret != LTTNG_OK) { + goto error; } /* Set the "global" consumer URIs */