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) {
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;
}
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;
}
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.
*
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);
}
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);
int ret = 0;
struct lttng_ht_iter iter;
struct ust_app *app;
+ char pathname[PATH_MAX];
assert(usess);
assert(output);
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;
}
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;
}