From: David Goulet Date: Tue, 9 Jul 2013 14:50:25 +0000 (-0400) Subject: Fix: snapshot support for UST and kernel in same session X-Git-Tag: v2.3.0-rc1~48 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=af706bb7e9bda5d6b95414165681abe422f1541e;p=lttng-tools.git Fix: snapshot support for UST and kernel in same session Signed-off-by: David Goulet --- diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 60a4ef2fb..903dfd36d 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -2254,27 +2254,6 @@ int cmd_snapshot_add_output(struct ltt_session *session, goto free_error; } - /* - * Copy sockets so the snapshot output can use them on destroy. - */ - - if (session->ust_session) { - ret = consumer_copy_sockets(new_output->consumer, - session->ust_session->consumer); - if (ret < 0) { - goto free_error; - } - new_output->ust_sockets_copied = 1; - } - if (session->kernel_session) { - ret = consumer_copy_sockets(new_output->consumer, - session->kernel_session->consumer); - if (ret < 0) { - goto free_error; - } - new_output->kernel_sockets_copied = 1; - } - rcu_read_lock(); snapshot_add_output(&session->snapshot, new_output); if (id) { @@ -2478,24 +2457,28 @@ static int record_kernel_snapshot(struct ltt_kernel_session *ksess, goto error; } - if (!output->kernel_sockets_copied) { - ret = consumer_copy_sockets(output->consumer, ksess->consumer); - if (ret < 0) { - goto error; - } - output->kernel_sockets_copied = 1; + /* + * Copy kernel session sockets so we can communicate with the right + * consumer for the snapshot record command. + */ + ret = consumer_copy_sockets(output->consumer, ksess->consumer); + if (ret < 0) { + goto error; } ret = set_relayd_for_snapshot(ksess->consumer, output, session); if (ret < 0) { - goto error; + goto error_snapshot; } ret = kernel_snapshot_record(ksess, output, wait); if (ret < 0) { - goto error; + goto error_snapshot; } +error_snapshot: + /* Clean up copied sockets so this output can use some other later on. */ + consumer_destroy_output_sockets(output->consumer); error: return ret; } @@ -2522,24 +2505,28 @@ static int record_ust_snapshot(struct ltt_ust_session *usess, goto error; } - if (!output->ust_sockets_copied) { - ret = consumer_copy_sockets(output->consumer, usess->consumer); - if (ret < 0) { - goto error; - } - output->ust_sockets_copied = 1; + /* + * Copy kernel session sockets so we can communicate with the right + * consumer for the snapshot record command. + */ + ret = consumer_copy_sockets(output->consumer, usess->consumer); + if (ret < 0) { + goto error; } ret = set_relayd_for_snapshot(usess->consumer, output, session); if (ret < 0) { - goto error; + goto error_snapshot; } ret = ust_app_snapshot_record(usess, output, wait); if (ret < 0) { - goto error; + goto error_snapshot; } +error_snapshot: + /* Clean up copied sockets so this output can use some other later on. */ + consumer_destroy_output_sockets(output->consumer); error: return ret; } diff --git a/src/bin/lttng-sessiond/consumer.c b/src/bin/lttng-sessiond/consumer.c index d3c561c9e..b1ccbc108 100644 --- a/src/bin/lttng-sessiond/consumer.c +++ b/src/bin/lttng-sessiond/consumer.c @@ -408,6 +408,28 @@ error: return output; } +/* + * Iterate over the consumer output socket hash table and destroy them. The + * socket file descriptor are only closed if the consumer output was + * registered meaning it's an external consumer. + */ +void consumer_destroy_output_sockets(struct consumer_output *obj) +{ + struct lttng_ht_iter iter; + struct consumer_socket *socket; + + if (!obj->socks) { + return; + } + + rcu_read_lock(); + cds_lfht_for_each_entry(obj->socks->ht, &iter.iter, socket, node.node) { + consumer_del_socket(socket, obj); + consumer_destroy_socket(socket); + } + rcu_read_unlock(); +} + /* * Delete the consumer_output object from the list and free the ptr. * @@ -419,17 +441,9 @@ void consumer_destroy_output(struct consumer_output *obj) return; } - if (obj->socks) { - struct lttng_ht_iter iter; - struct consumer_socket *socket; - - rcu_read_lock(); - cds_lfht_for_each_entry(obj->socks->ht, &iter.iter, socket, node.node) { - consumer_del_socket(socket, obj); - consumer_destroy_socket(socket); - } - rcu_read_unlock(); + consumer_destroy_output_sockets(obj); + if (obj->socks) { /* Finally destroy HT */ ht_cleanup_push(obj->socks); } diff --git a/src/bin/lttng-sessiond/consumer.h b/src/bin/lttng-sessiond/consumer.h index c3c8dfb7f..c219420ca 100644 --- a/src/bin/lttng-sessiond/consumer.h +++ b/src/bin/lttng-sessiond/consumer.h @@ -165,6 +165,7 @@ void consumer_del_socket(struct consumer_socket *sock, void consumer_destroy_socket(struct consumer_socket *sock); int consumer_copy_sockets(struct consumer_output *dst, struct consumer_output *src); +void consumer_destroy_output_sockets(struct consumer_output *obj); struct consumer_output *consumer_create_output(enum consumer_dst_type type); struct consumer_output *consumer_copy_output(struct consumer_output *obj); diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index c329650c9..60b55d25a 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -4876,6 +4876,7 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, int ret = 0; struct lttng_ht_iter iter; struct ust_app *app; + char pathname[PATH_MAX]; assert(usess); assert(output); @@ -4903,10 +4904,19 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, goto error; } + /* Add the UST default trace dir to path. */ + memset(pathname, 0, sizeof(pathname)); + ret = snprintf(pathname, sizeof(pathname), DEFAULT_UST_TRACE_DIR "/%s", + ua_sess->path); + if (ret < 0) { + PERROR("snprintf snapshot path"); + goto error; + } + cds_lfht_for_each_entry(ua_sess->channels->ht, &chan_iter.iter, ua_chan, node.node) { ret = consumer_snapshot_channel(socket, ua_chan->key, output, 0, - ua_sess->euid, ua_sess->egid, ua_sess->path, wait); + ua_sess->euid, ua_sess->egid, pathname, wait); if (ret < 0) { goto error; } @@ -4915,7 +4925,7 @@ int ust_app_snapshot_record(struct ltt_ust_session *usess, registry = get_session_registry(ua_sess); assert(registry); ret = consumer_snapshot_channel(socket, registry->metadata_key, output, - 1, ua_sess->euid, ua_sess->egid, ua_sess->path, wait); + 1, ua_sess->euid, ua_sess->egid, pathname, wait); if (ret < 0) { goto error; }