From: Mathieu Desnoyers Date: Sat, 24 Aug 2019 23:02:18 +0000 (-0700) Subject: Fix: kernel/ust snapshot backward compat for 2.10 relay X-Git-Tag: v2.12.0-rc1~466 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=3b9677124ab48bddc945ca67947c49b87b5853e0 Fix: kernel/ust snapshot backward compat for 2.10 relay Ensure the snapshots are saved in the right subdirectory on older relay daemons (2.10 and before). Signed-off-by: Mathieu Desnoyers Signed-off-by: Jérémie Galarneau --- diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 48aa79298..1b73978f2 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -4476,6 +4476,8 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, session->kernel_session->consumer; snapshot_kernel_consumer_output = consumer_copy_output(snapshot_output->consumer); + strcpy(snapshot_kernel_consumer_output->chunk_path, + snapshot_chunk_name); ret = consumer_copy_sockets(snapshot_kernel_consumer_output, original_kernel_consumer_output); if (ret < 0) { @@ -4496,6 +4498,8 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, original_ust_consumer_output = session->ust_session->consumer; snapshot_ust_consumer_output = consumer_copy_output(snapshot_output->consumer); + strcpy(snapshot_ust_consumer_output->chunk_path, + snapshot_chunk_name); ret = consumer_copy_sockets(snapshot_ust_consumer_output, original_ust_consumer_output); if (ret < 0) { diff --git a/src/bin/lttng-sessiond/consumer.c b/src/bin/lttng-sessiond/consumer.c index d6a6e8cbd..eeba2a2ab 100644 --- a/src/bin/lttng-sessiond/consumer.c +++ b/src/bin/lttng-sessiond/consumer.c @@ -38,6 +38,62 @@ #include "utils.h" #include "lttng-sessiond.h" +/* + * Return allocated full pathname of the session using the consumer trace path + * and subdir if available. + * + * The caller can safely free(3) the returned value. On error, NULL is + * returned. + */ +char *setup_channel_trace_path(struct consumer_output *consumer, + const char *session_path) +{ + int ret; + char *pathname; + + assert(consumer); + assert(session_path); + + health_code_update(); + + /* + * Allocate the string ourself to make sure we never exceed + * LTTNG_PATH_MAX. + */ + pathname = zmalloc(LTTNG_PATH_MAX); + if (!pathname) { + goto error; + } + + /* Get correct path name destination */ + if (consumer->type == CONSUMER_DST_NET && + consumer->relay_major_version == 2 && + consumer->relay_minor_version < 11) { + ret = snprintf(pathname, LTTNG_PATH_MAX, "%s%s/%s%s", + consumer->dst.net.base_dir, + consumer->chunk_path, consumer->domain_subdir, + session_path); + } else { + ret = snprintf(pathname, LTTNG_PATH_MAX, "%s%s", + consumer->domain_subdir, session_path); + } + DBG3("Consumer trace path relative to current trace chunk: \"%s\"", + pathname); + if (ret < 0) { + PERROR("Failed to format channel path"); + goto error; + } else if (ret >= LTTNG_PATH_MAX) { + ERR("Truncation occurred while formatting channel path"); + ret = -1; + goto error; + } + + return pathname; +error: + free(pathname); + return NULL; +} + /* * Send a data payload using a given consumer socket of size len. * diff --git a/src/bin/lttng-sessiond/consumer.h b/src/bin/lttng-sessiond/consumer.h index 3d5fc6fc9..1590788cc 100644 --- a/src/bin/lttng-sessiond/consumer.h +++ b/src/bin/lttng-sessiond/consumer.h @@ -325,4 +325,7 @@ int consumer_trace_chunk_exists(struct consumer_socket *socket, struct lttng_trace_chunk *chunk, enum consumer_trace_chunk_exists_status *result); +char *setup_channel_trace_path(struct consumer_output *consumer, + const char *session_path); + #endif /* _CONSUMER_H */ diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index 955fd3ac2..53072f971 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -1260,6 +1260,7 @@ enum lttng_error_code kernel_snapshot_record( struct consumer_socket *socket; struct lttng_ht_iter iter; struct ltt_kernel_metadata *saved_metadata; + char *trace_path = NULL; assert(ksess); assert(ksess->consumer); @@ -1285,6 +1286,12 @@ enum lttng_error_code kernel_snapshot_record( goto error_open_stream; } + trace_path = setup_channel_trace_path(ksess->consumer, + DEFAULT_KERNEL_TRACE_DIR); + if (!trace_path) { + status = LTTNG_ERR_INVALID; + goto error; + } /* Send metadata to consumer and snapshot everything. */ cds_lfht_for_each_entry(output->socks->ht, &iter.iter, socket, node.node) { @@ -1303,7 +1310,7 @@ enum lttng_error_code kernel_snapshot_record( cds_list_for_each_entry(chan, &ksess->channel_list.head, list) { status = consumer_snapshot_channel(socket, chan->key, output, 0, ksess->uid, ksess->gid, - DEFAULT_KERNEL_TRACE_DIR, wait, + trace_path, wait, nb_packets_per_stream); if (status != LTTNG_OK) { (void) kernel_consumer_destroy_metadata(socket, @@ -1314,8 +1321,7 @@ enum lttng_error_code kernel_snapshot_record( /* Snapshot metadata, */ status = consumer_snapshot_channel(socket, ksess->metadata->key, output, - 1, ksess->uid, ksess->gid, - DEFAULT_KERNEL_TRACE_DIR, wait, 0); + 1, ksess->uid, ksess->gid, trace_path, wait, 0); if (status != LTTNG_OK) { goto error_consumer; } @@ -1341,6 +1347,7 @@ error: ksess->metadata = saved_metadata; ksess->metadata_stream_fd = saved_metadata_fd; rcu_read_unlock(); + free(trace_path); return status; } diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 8c9277cae..56860d714 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -5883,7 +5883,6 @@ enum lttng_error_code ust_app_snapshot_record( enum lttng_error_code status = LTTNG_OK; struct lttng_ht_iter iter; struct ust_app *app; - char pathname[PATH_MAX]; assert(usess); assert(output); @@ -5898,6 +5897,8 @@ enum lttng_error_code ust_app_snapshot_record( cds_list_for_each_entry(reg, &usess->buffer_reg_uid_list, lnode) { struct buffer_reg_channel *reg_chan; struct consumer_socket *socket; + char *trace_path = NULL; + char pathname[PATH_MAX]; if (!reg->registry->reg.ust->metadata_key) { /* Skip since no metadata is present */ @@ -5925,22 +5926,28 @@ enum lttng_error_code ust_app_snapshot_record( status = LTTNG_ERR_INVALID; goto error; } - + trace_path = setup_channel_trace_path(usess->consumer, pathname); + if (!trace_path) { + status = LTTNG_ERR_INVALID; + goto error; + } /* Add the UST default trace dir to path. */ cds_lfht_for_each_entry(reg->registry->channels->ht, &iter.iter, reg_chan, node.node) { status = consumer_snapshot_channel(socket, reg_chan->consumer_key, output, 0, usess->uid, - usess->gid, pathname, wait, + usess->gid, trace_path, wait, nb_packets_per_stream); if (status != LTTNG_OK) { + free(trace_path); goto error; } } status = consumer_snapshot_channel(socket, reg->registry->reg.ust->metadata_key, output, 1, - usess->uid, usess->gid, pathname, wait, 0); + usess->uid, usess->gid, trace_path, wait, 0); + free(trace_path); if (status != LTTNG_OK) { goto error; } @@ -5955,6 +5962,8 @@ enum lttng_error_code ust_app_snapshot_record( struct ust_app_channel *ua_chan; struct ust_app_session *ua_sess; struct ust_registry_session *registry; + char *trace_path = NULL; + char pathname[PATH_MAX]; ua_sess = lookup_session_by_app(usess, app); if (!ua_sess) { @@ -5979,7 +5988,11 @@ enum lttng_error_code ust_app_snapshot_record( PERROR("snprintf snapshot path"); goto error; } - + trace_path = setup_channel_trace_path(usess->consumer, pathname); + if (!trace_path) { + status = LTTNG_ERR_INVALID; + goto error; + } cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter, ua_chan, node.node) { status = consumer_snapshot_channel(socket, @@ -5988,14 +6001,16 @@ enum lttng_error_code ust_app_snapshot_record( .uid, ua_sess->effective_credentials .gid, - pathname, wait, + trace_path, wait, nb_packets_per_stream); switch (status) { case LTTNG_OK: break; case LTTNG_ERR_CHAN_NOT_FOUND: + free(trace_path); continue; default: + free(trace_path); goto error; } } @@ -6009,7 +6024,8 @@ enum lttng_error_code ust_app_snapshot_record( registry->metadata_key, output, 1, ua_sess->effective_credentials.uid, ua_sess->effective_credentials.gid, - pathname, wait, 0); + trace_path, wait, 0); + free(trace_path); switch (status) { case LTTNG_OK: break; diff --git a/src/bin/lttng-sessiond/ust-consumer.c b/src/bin/lttng-sessiond/ust-consumer.c index f9a29e49e..9ab54e9d7 100644 --- a/src/bin/lttng-sessiond/ust-consumer.c +++ b/src/bin/lttng-sessiond/ust-consumer.c @@ -34,62 +34,6 @@ #include "session.h" #include "lttng-sessiond.h" -/* - * Return allocated full pathname of the session using the consumer trace path - * and subdir if available. - * - * The caller can safely free(3) the returned value. On error, NULL is - * returned. - */ -static char *setup_channel_trace_path(struct consumer_output *consumer, - struct ust_app_session *ua_sess) -{ - int ret; - char *pathname; - - assert(consumer); - assert(ua_sess); - - health_code_update(); - - /* - * Allocate the string ourself to make sure we never exceed - * LTTNG_PATH_MAX. - */ - pathname = zmalloc(LTTNG_PATH_MAX); - if (!pathname) { - goto error; - } - - /* Get correct path name destination */ - if (consumer->type == CONSUMER_DST_NET && - consumer->relay_major_version == 2 && - consumer->relay_minor_version < 11) { - ret = snprintf(pathname, LTTNG_PATH_MAX, "%s%s/%s%s", - consumer->dst.net.base_dir, - consumer->chunk_path, consumer->domain_subdir, - ua_sess->path); - } else { - ret = snprintf(pathname, LTTNG_PATH_MAX, "%s%s", - consumer->domain_subdir, ua_sess->path); - } - DBG3("Userspace consumer trace path relative to current trace chunk: \"%s\"", - pathname); - if (ret < 0) { - PERROR("Failed to format channel path"); - goto error; - } else if (ret >= LTTNG_PATH_MAX) { - ERR("Truncation occurred while formatting channel path"); - ret = -1; - goto error; - } - - return pathname; -error: - free(pathname); - return NULL; -} - /* * Send a single channel to the consumer using command ASK_CHANNEL_CREATION. * @@ -122,7 +66,7 @@ static int ask_channel_creation(struct ust_app_session *ua_sess, is_local_trace = consumer->net_seq_index == -1ULL; /* Format the channel's path (relative to the current trace chunk). */ - pathname = setup_channel_trace_path(consumer, ua_sess); + pathname = setup_channel_trace_path(consumer, ua_sess->path); if (!pathname) { ret = -1; goto error;