Adapt the userspace probe objects to use the lttng_payload interface.
This streamlines the acquisition of the file descriptors when those
objects are serialized.
File descriptors are transmitted in both directions between liblttng-ctl
and the session daemon making it possible (and safe) to compare
userspace probe instances.
Currently the event listing API does not allow us to express userspace
probe locations that contain a file descriptor. This is an unfortunate
consequence of returning a "flat" array to list events.
Indeed, we can't store a file descriptor in the userspace probe
locations returned to the user in this API since the destructors of the
probe locations are never called. The user simply free()'s the returned
array, which would leak the file descriptors.
The consequence of this is that we can't allow the creation of event
rules using a probe location returned by an lttng_list_events() call.
This is not unsolvable, but I'm not sure if there really is a use-case
for this.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I0f710cbe9deabfd163206fd03618eba183f3d1d2
#include <lttng/userspace-probe.h>
#include <common/macros.h>
-#include <common/dynamic-buffer.h>
-#include <common/buffer-view.h>
+#include <stdbool.h>
+
+struct lttng_payload;
+struct lttng_payload_view;
+struct lttng_dynamic_buffer;
typedef bool (*userspace_probe_location_equal_cb)(
const struct lttng_userspace_probe_location *a,
LTTNG_HIDDEN
int lttng_userspace_probe_location_serialize(
const struct lttng_userspace_probe_location *location,
- struct lttng_dynamic_buffer *buffer,
- int *binary_fd);
+ struct lttng_payload *payload);
LTTNG_HIDDEN
-int lttng_userspace_probe_location_create_from_buffer(
- const struct lttng_buffer_view *buffer,
+int lttng_userspace_probe_location_create_from_payload(
+ struct lttng_payload_view *view,
struct lttng_userspace_probe_location **probe_location);
LTTNG_HIDDEN
# link on liblttngctl for check if relayd is already alive.
lttng_relayd_LDADD = -lurcu-common -lurcu \
+ $(top_builddir)/src/common/libcommon.la \
$(top_builddir)/src/common/sessiond-comm/libsessiond-comm.la \
$(top_builddir)/src/common/hashtable/libhashtable.la \
- $(top_builddir)/src/common/libcommon.la \
$(top_builddir)/src/common/compat/libcompat.la \
$(top_builddir)/src/common/index/libindex.la \
$(top_builddir)/src/common/health/libhealth.la \
#include "common/payload.h"
#include "common/payload-view.h"
#include "common/sessiond-comm/sessiond-comm.h"
+#include "common/payload.h"
+#include "common/payload-view.h"
#include "lttng/lttng-error.h"
#include "lttng/tracker.h"
#include <common/compat/getenv.h>
};
lttng_dynamic_buffer_set_size(&cmd_ctx->reply_payload.buffer, 0);
+ lttng_dynamic_array_clear(&cmd_ctx->reply_payload._fds);
cmd_ctx->lttng_msg_size = total_msg_size;
return ret;
}
+static int setup_empty_lttng_msg(struct command_ctx *cmd_ctx)
+{
+ int ret;
+ const struct lttcomm_lttng_msg llm = {};
+
+ lttng_dynamic_buffer_set_size(&cmd_ctx->reply_payload.buffer, 0);
+
+ /* Append place-holder reply header. */
+ ret = lttng_dynamic_buffer_append(
+ &cmd_ctx->reply_payload.buffer, &llm, sizeof(llm));
+ if (ret) {
+ goto end;
+ }
+
+ cmd_ctx->lttng_msg_size = sizeof(llm);
+end:
+ return ret;
+}
+
+static void update_lttng_msg(struct command_ctx *cmd_ctx, size_t cmd_header_len,
+ size_t payload_len)
+{
+ const size_t header_len = sizeof(struct lttcomm_lttng_msg);
+ const size_t total_msg_size = header_len + cmd_header_len + payload_len;
+ const struct lttcomm_lttng_msg llm = {
+ .cmd_type = cmd_ctx->lsm.cmd_type,
+ .pid = cmd_ctx->lsm.domain.attr.pid,
+ .cmd_header_size = cmd_header_len,
+ .data_size = payload_len,
+ };
+ struct lttcomm_lttng_msg *p_llm;
+
+ assert(cmd_ctx->reply_payload.buffer.size >= sizeof(llm));
+
+ p_llm = (typeof(p_llm)) cmd_ctx->reply_payload.buffer.data;
+
+ /* Update existing header. */
+ memcpy(p_llm, &llm, sizeof(llm));
+
+ cmd_ctx->lttng_msg_size = total_msg_size;
+}
+
/*
* Start the thread_manage_consumer. This must be done after a lttng-consumerd
* exec or it will fail.
{
int fd, ret;
struct lttng_userspace_probe_location *probe_location;
- const struct lttng_userspace_probe_location_lookup_method *lookup = NULL;
- struct lttng_dynamic_buffer probe_location_buffer;
- struct lttng_buffer_view buffer_view;
+ struct lttng_payload probe_location_payload;
/*
- * Create a buffer to store the serialized version of the probe
+ * Create a payload to store the serialized version of the probe
* location.
*/
- lttng_dynamic_buffer_init(&probe_location_buffer);
- ret = lttng_dynamic_buffer_set_size(&probe_location_buffer,
+ lttng_payload_init(&probe_location_payload);
+
+ ret = lttng_dynamic_buffer_set_size(&probe_location_payload.buffer,
cmd_ctx->lsm.u.enable.userspace_probe_location_len);
if (ret) {
ret = LTTNG_ERR_NOMEM;
/*
* Receive the probe location.
*/
- ret = lttcomm_recv_unix_sock(sock, probe_location_buffer.data,
- probe_location_buffer.size);
+ ret = lttcomm_recv_unix_sock(sock, probe_location_payload.buffer.data,
+ probe_location_payload.buffer.size);
if (ret <= 0) {
DBG("Nothing recv() from client var len data... continuing");
*sock_error = 1;
- lttng_dynamic_buffer_reset(&probe_location_buffer);
- ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
- goto error;
- }
-
- buffer_view = lttng_buffer_view_from_dynamic_buffer(
- &probe_location_buffer, 0, probe_location_buffer.size);
-
- /*
- * Extract the probe location from the serialized version.
- */
- ret = lttng_userspace_probe_location_create_from_buffer(
- &buffer_view, &probe_location);
- if (ret < 0) {
- WARN("Failed to create a userspace probe location from the received buffer");
- lttng_dynamic_buffer_reset( &probe_location_buffer);
ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
goto error;
}
goto error;
}
- /*
- * Set the file descriptor received from the client through the unix
- * socket in the probe location.
- */
- lookup = lttng_userspace_probe_location_get_lookup_method(probe_location);
- if (!lookup) {
- ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
+ ret = lttng_payload_push_fd(&probe_location_payload, fd);
+ if (ret) {
+ ERR("Failed to add userspace probe file descriptor to payload");
+ ret = LTTNG_ERR_NOMEM;
goto error;
}
- /*
- * From the kernel tracer's perspective, all userspace probe event types
- * are all the same: a file and an offset.
- */
- switch (lttng_userspace_probe_location_lookup_method_get_type(lookup)) {
- case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
- ret = lttng_userspace_probe_location_function_set_binary_fd(
- probe_location, fd);
- break;
- case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
- ret = lttng_userspace_probe_location_tracepoint_set_binary_fd(
- probe_location, fd);
- break;
- default:
- ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
- goto error;
- }
+ {
+ struct lttng_payload_view view = lttng_payload_view_from_payload(
+ &probe_location_payload, 0, -1);
- if (ret) {
+ /* Extract the probe location from the serialized version. */
+ ret = lttng_userspace_probe_location_create_from_payload(
+ &view, &probe_location);
+ }
+ if (ret < 0) {
+ WARN("Failed to create a userspace probe location from the received buffer");
ret = LTTNG_ERR_PROBE_LOCATION_INVAL;
goto error;
}
goto error;
}
- lttng_dynamic_buffer_reset(&probe_location_buffer);
error:
+ lttng_payload_reset(&probe_location_payload);
return ret;
}
}
case LTTNG_LIST_EVENTS:
{
- ssize_t nb_event;
- struct lttng_event *events = NULL;
- struct lttcomm_event_command_header cmd_header;
- size_t total_size;
-
- memset(&cmd_header, 0, sizeof(cmd_header));
- /* Extended infos are included at the end of events */
- nb_event = cmd_list_events(cmd_ctx->lsm.domain.type,
- cmd_ctx->session, cmd_ctx->lsm.u.list.channel_name,
- &events, &total_size);
-
- if (nb_event < 0) {
- /* Return value is a negative lttng_error_code. */
- ret = -nb_event;
- goto error;
+ ssize_t list_ret;
+ struct lttcomm_event_command_header cmd_header = {};
+ size_t original_payload_size;
+ size_t payload_size;
+
+ ret = setup_empty_lttng_msg(cmd_ctx);
+ if (ret) {
+ ret = LTTNG_ERR_NOMEM;
+ goto setup_error;
}
- cmd_header.nb_events = nb_event;
- ret = setup_lttng_msg(cmd_ctx, events, total_size,
- &cmd_header, sizeof(cmd_header));
- free(events);
+ original_payload_size = cmd_ctx->reply_payload.buffer.size;
- if (ret < 0) {
- goto setup_error;
+ /* Extended infos are included at the end of the payload. */
+ list_ret = cmd_list_events(cmd_ctx->lsm.domain.type,
+ cmd_ctx->session,
+ cmd_ctx->lsm.u.list.channel_name,
+ &cmd_ctx->reply_payload);
+ if (list_ret < 0) {
+ /* Return value is a negative lttng_error_code. */
+ ret = -list_ret;
+ goto error;
}
+ payload_size = cmd_ctx->reply_payload.buffer.size -
+ sizeof(cmd_header) - original_payload_size;
+ update_lttng_msg(cmd_ctx, sizeof(cmd_header), payload_size);
+
ret = LTTNG_OK;
break;
}
cmd_ctx.session = NULL;
lttng_dynamic_buffer_set_size(&cmd_ctx.reply_payload.buffer, 0);
lttng_dynamic_array_clear(&cmd_ctx.reply_payload._fds);
+ cmd_ctx.lttng_msg_size = 0;
DBG("Accepting client command ...");
lttng_payload_view_from_payload(
&cmd_ctx.reply_payload,
0, -1);
- const struct lttcomm_lttng_msg *llm = (typeof(
+ struct lttcomm_lttng_msg *llm = (typeof(
llm)) cmd_ctx.reply_payload.buffer.data;
assert(cmd_ctx.reply_payload.buffer.size >=
sizeof(llm));
assert(cmd_ctx.lttng_msg_size == cmd_ctx.reply_payload.buffer.size);
+ llm->fd_count = lttng_payload_view_get_fd_count(&view);
+
DBG("Sending response (size: %d, retcode: %s (%d))",
cmd_ctx.lttng_msg_size,
lttng_strerror(-llm->ret_code),
}
}
-static int increment_extended_len(const char *filter_expression,
- struct lttng_event_exclusion *exclusion,
- const struct lttng_userspace_probe_location *probe_location,
- size_t *extended_len)
-{
- int ret = 0;
-
- *extended_len += sizeof(struct lttcomm_event_extended_header);
-
- if (filter_expression) {
- *extended_len += strlen(filter_expression) + 1;
- }
-
- if (exclusion) {
- *extended_len += exclusion->count * LTTNG_SYMBOL_NAME_LEN;
- }
-
- if (probe_location) {
- ret = lttng_userspace_probe_location_serialize(probe_location,
- NULL, NULL);
- if (ret < 0) {
- goto end;
- }
- *extended_len += ret;
- }
- ret = 0;
-end:
- return ret;
-}
-
static int append_extended_info(const char *filter_expression,
struct lttng_event_exclusion *exclusion,
struct lttng_userspace_probe_location *probe_location,
- void **extended_at)
+ struct lttng_payload *payload)
{
int ret = 0;
size_t filter_len = 0;
size_t nb_exclusions = 0;
size_t userspace_probe_location_len = 0;
- struct lttng_dynamic_buffer location_buffer;
- struct lttcomm_event_extended_header extended_header;
+ struct lttcomm_event_extended_header extended_header = {};
+ struct lttcomm_event_extended_header *p_extended_header;
+ const size_t original_payload_size = payload->buffer.size;
+
+ ret = lttng_dynamic_buffer_append(&payload->buffer, &extended_header,
+ sizeof(extended_header));
+ if (ret) {
+ goto end;
+ }
if (filter_expression) {
filter_len = strlen(filter_expression) + 1;
+ ret = lttng_dynamic_buffer_append(&payload->buffer,
+ filter_expression, filter_len);
+ if (ret) {
+ goto end;
+ }
}
if (exclusion) {
+ const size_t len = exclusion->count * LTTNG_SYMBOL_NAME_LEN;
+
nb_exclusions = exclusion->count;
+
+ ret = lttng_dynamic_buffer_append(
+ &payload->buffer, &exclusion->names, len);
+ if (ret) {
+ goto end;
+ }
}
if (probe_location) {
- lttng_dynamic_buffer_init(&location_buffer);
+ const size_t size_before_probe = payload->buffer.size;
+
ret = lttng_userspace_probe_location_serialize(probe_location,
- &location_buffer, NULL);
+ payload);
if (ret < 0) {
ret = -1;
goto end;
}
- userspace_probe_location_len = location_buffer.size;
+
+ userspace_probe_location_len =
+ payload->buffer.size - size_before_probe;
}
/* Set header fields */
- extended_header.filter_len = filter_len;
- extended_header.nb_exclusions = nb_exclusions;
- extended_header.userspace_probe_location_len = userspace_probe_location_len;
+ p_extended_header = (struct lttcomm_event_extended_header *)
+ (payload->buffer.data + original_payload_size);
- /* Copy header */
- memcpy(*extended_at, &extended_header, sizeof(extended_header));
- *extended_at += sizeof(extended_header);
+ p_extended_header->filter_len = filter_len;
+ p_extended_header->nb_exclusions = nb_exclusions;
+ p_extended_header->userspace_probe_location_len =
+ userspace_probe_location_len;
- /* Copy filter string */
- if (filter_expression) {
- memcpy(*extended_at, filter_expression, filter_len);
- *extended_at += filter_len;
- }
-
- /* Copy exclusion names */
- if (exclusion) {
- size_t len = nb_exclusions * LTTNG_SYMBOL_NAME_LEN;
-
- memcpy(*extended_at, &exclusion->names, len);
- *extended_at += len;
- }
-
- if (probe_location) {
- memcpy(*extended_at, location_buffer.data, location_buffer.size);
- *extended_at += location_buffer.size;
- lttng_dynamic_buffer_reset(&location_buffer);
- }
ret = 0;
end:
return ret;
* Return number of events in list on success or else a negative value.
*/
static int list_lttng_agent_events(struct agent *agt,
- struct lttng_event **events, size_t *total_size)
+ struct lttng_payload *payload)
{
- int i = 0, ret = 0;
- unsigned int nb_event = 0;
- struct agent_event *event;
- struct lttng_event *tmp_events = NULL;
+ int nb_events = 0, ret = 0;
+ const struct agent_event *agent_event;
struct lttng_ht_iter iter;
- size_t extended_len = 0;
- void *extended_at;
assert(agt);
- assert(events);
DBG3("Listing agent events");
rcu_read_lock();
- nb_event = lttng_ht_get_count(agt->events);
- rcu_read_unlock();
- if (nb_event == 0) {
- ret = nb_event;
- *total_size = 0;
- goto error;
- }
-
- /* Compute required extended infos size */
- extended_len = nb_event * sizeof(struct lttcomm_event_extended_header);
-
- /*
- * This is only valid because the commands which add events are
- * processed in the same thread as the listing.
- */
- rcu_read_lock();
- cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) {
- ret = increment_extended_len(event->filter_expression, NULL, NULL,
- &extended_len);
+ cds_lfht_for_each_entry (
+ agt->events->ht, &iter.iter, agent_event, node.node) {
+ struct lttng_event event = {
+ .enabled = agent_event->enabled,
+ .loglevel = agent_event->loglevel_value,
+ .loglevel_type = agent_event->loglevel_type,
+ };
+
+ strncpy(event.name, agent_event->name, sizeof(event.name));
+ event.name[sizeof(event.name) - 1] = '\0';
+
+ ret = lttng_dynamic_buffer_append(
+ &payload->buffer, &event, sizeof(event));
if (ret) {
- DBG("Error computing the length of extended info message");
- ret = -LTTNG_ERR_FATAL;
- goto error;
+ ERR("Failed to append event to payload");
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
}
- }
- rcu_read_unlock();
- *total_size = nb_event * sizeof(*tmp_events) + extended_len;
- tmp_events = zmalloc(*total_size);
- if (!tmp_events) {
- PERROR("zmalloc agent events session");
- ret = -LTTNG_ERR_FATAL;
- goto error;
+ nb_events++;
}
- extended_at = ((uint8_t *) tmp_events) +
- nb_event * sizeof(struct lttng_event);
-
- rcu_read_lock();
- cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) {
- strncpy(tmp_events[i].name, event->name, sizeof(tmp_events[i].name));
- tmp_events[i].name[sizeof(tmp_events[i].name) - 1] = '\0';
- tmp_events[i].enabled = event->enabled;
- tmp_events[i].loglevel = event->loglevel_value;
- tmp_events[i].loglevel_type = event->loglevel_type;
- i++;
-
- /* Append extended info */
- ret = append_extended_info(event->filter_expression, NULL, NULL,
- &extended_at);
+ cds_lfht_for_each_entry (
+ agt->events->ht, &iter.iter, agent_event, node.node) {
+ /* Append extended info. */
+ ret = append_extended_info(agent_event->filter_expression, NULL,
+ NULL, payload);
if (ret) {
- DBG("Error appending extended info message");
- ret = -LTTNG_ERR_FATAL;
- goto error;
+ ERR("Failed to append extended event info to payload");
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
}
}
- *events = tmp_events;
- ret = nb_event;
- assert(nb_event == i);
-
+ ret = nb_events;
end:
rcu_read_unlock();
return ret;
-error:
- free(tmp_events);
- goto end;
}
/*
*/
static int list_lttng_ust_global_events(char *channel_name,
struct ltt_ust_domain_global *ust_global,
- struct lttng_event **events, size_t *total_size)
+ struct lttng_payload *payload)
{
- int i = 0, ret = 0;
- unsigned int nb_event = 0;
+ int ret = 0;
+ unsigned int nb_events = 0;
struct lttng_ht_iter iter;
- struct lttng_ht_node_str *node;
- struct ltt_ust_channel *uchan;
- struct ltt_ust_event *uevent;
- struct lttng_event *tmp;
- size_t extended_len = 0;
- void *extended_at;
+ const struct lttng_ht_node_str *node;
+ const struct ltt_ust_channel *uchan;
+ const struct ltt_ust_event *uevent;
DBG("Listing UST global events for channel %s", channel_name);
rcu_read_lock();
- lttng_ht_lookup(ust_global->channels, (void *)channel_name, &iter);
+ lttng_ht_lookup(ust_global->channels, (void *) channel_name, &iter);
node = lttng_ht_iter_get_node_str(&iter);
if (node == NULL) {
ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
uchan = caa_container_of(&node->node, struct ltt_ust_channel, node.node);
- nb_event = lttng_ht_get_count(uchan->events);
- if (nb_event == 0) {
- ret = nb_event;
- *total_size = 0;
- goto end;
- }
-
- DBG3("Listing UST global %d events", nb_event);
+ DBG3("Listing UST global events");
- /* Compute required extended infos size */
cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent, node.node) {
+ struct lttng_event event = {};
+
if (uevent->internal) {
- nb_event--;
continue;
}
- ret = increment_extended_len(uevent->filter_expression,
- uevent->exclusion, NULL, &extended_len);
- if (ret) {
- DBG("Error computing the length of extended info message");
- ret = -LTTNG_ERR_FATAL;
- goto end;
- }
- }
- if (nb_event == 0) {
- /* All events are internal, skip. */
- ret = 0;
- *total_size = 0;
- goto end;
- }
-
- *total_size = nb_event * sizeof(struct lttng_event) + extended_len;
- tmp = zmalloc(*total_size);
- if (tmp == NULL) {
- ret = -LTTNG_ERR_FATAL;
- goto end;
- }
-
- extended_at = ((uint8_t *) tmp) + nb_event * sizeof(struct lttng_event);
+ strncpy(event.name, uevent->attr.name, sizeof(event.name));
+ event.name[sizeof(event.name) - 1] = '\0';
- cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent, node.node) {
- if (uevent->internal) {
- /* This event should remain hidden from clients */
- continue;
- }
- strncpy(tmp[i].name, uevent->attr.name, LTTNG_SYMBOL_NAME_LEN);
- tmp[i].name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
- tmp[i].enabled = uevent->enabled;
+ event.enabled = uevent->enabled;
switch (uevent->attr.instrumentation) {
case LTTNG_UST_TRACEPOINT:
- tmp[i].type = LTTNG_EVENT_TRACEPOINT;
+ event.type = LTTNG_EVENT_TRACEPOINT;
break;
case LTTNG_UST_PROBE:
- tmp[i].type = LTTNG_EVENT_PROBE;
+ event.type = LTTNG_EVENT_PROBE;
break;
case LTTNG_UST_FUNCTION:
- tmp[i].type = LTTNG_EVENT_FUNCTION;
+ event.type = LTTNG_EVENT_FUNCTION;
break;
}
- tmp[i].loglevel = uevent->attr.loglevel;
+ event.loglevel = uevent->attr.loglevel;
switch (uevent->attr.loglevel_type) {
case LTTNG_UST_LOGLEVEL_ALL:
- tmp[i].loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
+ event.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
break;
case LTTNG_UST_LOGLEVEL_RANGE:
- tmp[i].loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
+ event.loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
break;
case LTTNG_UST_LOGLEVEL_SINGLE:
- tmp[i].loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
+ event.loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
break;
}
+
if (uevent->filter) {
- tmp[i].filter = 1;
+ event.filter = 1;
}
+
if (uevent->exclusion) {
- tmp[i].exclusion = 1;
+ event.exclusion = 1;
}
- i++;
- /* Append extended info */
+ ret = lttng_dynamic_buffer_append(&payload->buffer, &event, sizeof(event));
+ if (ret) {
+ ERR("Failed to append event to payload");
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ nb_events++;
+ }
+
+ cds_lfht_for_each_entry(uchan->events->ht, &iter.iter, uevent, node.node) {
+ /* Append extended info. */
ret = append_extended_info(uevent->filter_expression,
- uevent->exclusion, NULL, &extended_at);
+ uevent->exclusion, NULL, payload);
if (ret) {
- DBG("Error appending extended info message");
+ ERR("Failed to append extended event info to payload");
ret = -LTTNG_ERR_FATAL;
goto end;
}
}
- ret = nb_event;
- *events = tmp;
+ ret = nb_events;
end:
rcu_read_unlock();
return ret;
*/
static int list_lttng_kernel_events(char *channel_name,
struct ltt_kernel_session *kernel_session,
- struct lttng_event **events, size_t *total_size)
+ struct lttng_payload *payload)
{
- int i = 0, ret;
+ int ret;
unsigned int nb_event;
- struct ltt_kernel_event *event;
- struct ltt_kernel_channel *kchan;
- size_t extended_len = 0;
- void *extended_at;
+ const struct ltt_kernel_event *kevent;
+ const struct ltt_kernel_channel *kchan;
kchan = trace_kernel_get_channel_by_name(channel_name, kernel_session);
if (kchan == NULL) {
DBG("Listing events for channel %s", kchan->channel->name);
- if (nb_event == 0) {
- *total_size = 0;
- *events = NULL;
- goto end;
- }
-
- /* Compute required extended infos size */
- cds_list_for_each_entry(event, &kchan->events_list.head, list) {
- ret = increment_extended_len(event->filter_expression, NULL,
- event->userspace_probe_location,
- &extended_len);
- if (ret) {
- DBG("Error computing the length of extended info message");
- ret = -LTTNG_ERR_FATAL;
- goto error;
- }
- }
-
- *total_size = nb_event * sizeof(struct lttng_event) + extended_len;
- *events = zmalloc(*total_size);
- if (*events == NULL) {
- ret = -LTTNG_ERR_FATAL;
- goto error;
- }
+ /* Kernel channels */
+ cds_list_for_each_entry(kevent, &kchan->events_list.head , list) {
+ struct lttng_event event = {};
- extended_at = ((void *) *events) +
- nb_event * sizeof(struct lttng_event);
+ strncpy(event.name, kevent->event->name, sizeof(event.name));
+ event.name[sizeof(event.name) - 1] = '\0';
+ event.enabled = kevent->enabled;
+ event.filter = (unsigned char) !!kevent->filter_expression;
- /* Kernel channels */
- cds_list_for_each_entry(event, &kchan->events_list.head , list) {
- strncpy((*events)[i].name, event->event->name, LTTNG_SYMBOL_NAME_LEN);
- (*events)[i].name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
- (*events)[i].enabled = event->enabled;
- (*events)[i].filter =
- (unsigned char) !!event->filter_expression;
-
- switch (event->event->instrumentation) {
+ switch (kevent->event->instrumentation) {
case LTTNG_KERNEL_TRACEPOINT:
- (*events)[i].type = LTTNG_EVENT_TRACEPOINT;
+ event.type = LTTNG_EVENT_TRACEPOINT;
break;
case LTTNG_KERNEL_KRETPROBE:
- (*events)[i].type = LTTNG_EVENT_FUNCTION;
- memcpy(&(*events)[i].attr.probe, &event->event->u.kprobe,
+ event.type = LTTNG_EVENT_FUNCTION;
+ memcpy(&event.attr.probe, &kevent->event->u.kprobe,
sizeof(struct lttng_kernel_kprobe));
break;
case LTTNG_KERNEL_KPROBE:
- (*events)[i].type = LTTNG_EVENT_PROBE;
- memcpy(&(*events)[i].attr.probe, &event->event->u.kprobe,
+ event.type = LTTNG_EVENT_PROBE;
+ memcpy(&event.attr.probe, &kevent->event->u.kprobe,
sizeof(struct lttng_kernel_kprobe));
break;
case LTTNG_KERNEL_UPROBE:
- (*events)[i].type = LTTNG_EVENT_USERSPACE_PROBE;
+ event.type = LTTNG_EVENT_USERSPACE_PROBE;
break;
case LTTNG_KERNEL_FUNCTION:
- (*events)[i].type = LTTNG_EVENT_FUNCTION;
- memcpy(&((*events)[i].attr.ftrace), &event->event->u.ftrace,
+ event.type = LTTNG_EVENT_FUNCTION;
+ memcpy(&event.attr.ftrace, &kevent->event->u.ftrace,
sizeof(struct lttng_kernel_function));
break;
case LTTNG_KERNEL_NOOP:
- (*events)[i].type = LTTNG_EVENT_NOOP;
+ event.type = LTTNG_EVENT_NOOP;
break;
case LTTNG_KERNEL_SYSCALL:
- (*events)[i].type = LTTNG_EVENT_SYSCALL;
+ event.type = LTTNG_EVENT_SYSCALL;
break;
case LTTNG_KERNEL_ALL:
/* fall-through. */
assert(0);
break;
}
- i++;
- /* Append extended info */
- ret = append_extended_info(event->filter_expression, NULL,
- event->userspace_probe_location, &extended_at);
+ ret = lttng_dynamic_buffer_append(
+ &payload->buffer, &event, sizeof(event));
+ if (ret) {
+ ERR("Failed to append event to payload");
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+ }
+
+ cds_list_for_each_entry(kevent, &kchan->events_list.head , list) {
+ /* Append extended info. */
+ ret = append_extended_info(kevent->filter_expression, NULL,
+ kevent->userspace_probe_location, payload);
if (ret) {
DBG("Error appending extended info message");
ret = -LTTNG_ERR_FATAL;
end:
return nb_event;
-
error:
return ret;
}
*/
ssize_t cmd_list_events(enum lttng_domain_type domain,
struct ltt_session *session, char *channel_name,
- struct lttng_event **events, size_t *total_size)
+ struct lttng_payload *payload)
{
int ret = 0;
- ssize_t nb_event = 0;
+ ssize_t nb_events = 0;
+ struct lttcomm_event_command_header cmd_header = {};
+ const size_t cmd_header_offset = payload->buffer.size;
+
+ ret = lttng_dynamic_buffer_append(
+ &payload->buffer, &cmd_header, sizeof(cmd_header));
+ if (ret) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
+ }
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
if (session->kernel_session != NULL) {
- nb_event = list_lttng_kernel_events(channel_name,
- session->kernel_session, events,
- total_size);
+ nb_events = list_lttng_kernel_events(channel_name,
+ session->kernel_session, payload);
}
break;
case LTTNG_DOMAIN_UST:
{
if (session->ust_session != NULL) {
- nb_event = list_lttng_ust_global_events(channel_name,
- &session->ust_session->domain_global, events,
- total_size);
+ nb_events = list_lttng_ust_global_events(channel_name,
+ &session->ust_session->domain_global,
+ payload);
}
break;
}
cds_lfht_for_each_entry(session->ust_session->agents->ht,
&iter.iter, agt, node.node) {
if (agt->domain == domain) {
- nb_event = list_lttng_agent_events(
- agt, events,
- total_size);
+ nb_events = list_lttng_agent_events(
+ agt, payload);
break;
}
}
goto error;
}
- return nb_event;
+ ((struct lttcomm_event_command_header *) (payload->buffer.data +
+ cmd_header_offset))->nb_events = (uint32_t) nb_events;
+
+ return nb_events;
error:
/* Return negative value to differentiate return code */
struct lttng_domain **domains);
ssize_t cmd_list_events(enum lttng_domain_type domain,
struct ltt_session *session, char *channel_name,
- struct lttng_event **events, size_t *total_size);
+ struct lttng_payload *payload);
ssize_t cmd_list_channels(enum lttng_domain_type domain,
struct ltt_session *session, struct lttng_channel **channels);
ssize_t cmd_list_domains(struct ltt_session *session,
/*
* Save a reference to the probe location used during
- * the listing of events. Close its FD since it won't
- * be needed for listing.
+ * the listing of events.
*/
userspace_probe_location =
lttng_userspace_probe_location_copy(location);
- ret = lttng_userspace_probe_location_function_set_binary_fd(
- userspace_probe_location, -1);
- if (ret) {
- goto error;
- }
break;
case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
/* Get the file descriptor on the target binary. */
/*
* Save a reference to the probe location used during the listing of
- * events. Close its FD since it won't be needed for listing.
+ * events.
*/
userspace_probe_location =
lttng_userspace_probe_location_copy(location);
- ret = lttng_userspace_probe_location_tracepoint_set_binary_fd(
- userspace_probe_location, -1);
- if (ret) {
- goto error;
- }
break;
default:
DBG("Unsupported lookup method type");
};
}
+LTTNG_HIDDEN
+struct lttng_payload_view lttng_payload_view_init_from_buffer(
+ const char *src, size_t offset, ptrdiff_t len)
+{
+ return (struct lttng_payload_view) {
+ .buffer = lttng_buffer_view_init(
+ src, offset, len)
+ };
+}
+
LTTNG_HIDDEN
int lttng_payload_view_get_fd_count(struct lttng_payload_view *payload_view)
{
const struct lttng_buffer_view *view, size_t offset,
ptrdiff_t len);
+/**
+ * Return a payload view referencing a subset of the memory referenced by a raw
+ * pointer.
+ *
+ * @src Source buffer to reference
+ * @offset Offset to apply to the source memory buffer
+ * @len Length of the memory contents to reference.
+ *
+ * Note that a payload view never assumes the ownership of the memory it
+ * references.
+ */
+LTTNG_HIDDEN
+struct lttng_payload_view lttng_payload_view_init_from_buffer(
+ const char *src, size_t offset, ptrdiff_t len);
+
/**
* Get the number of file descriptors left in a payload view.
*
*/
#include "payload.h"
+#include <common/dynamic-array.h>
+#include <common/dynamic-buffer.h>
+#include <common/error.h>
LTTNG_HIDDEN
void lttng_payload_init(struct lttng_payload *payload)
lttng_dynamic_array_init(&payload->_fds, sizeof(int), NULL);
}
+LTTNG_HIDDEN
+int lttng_payload_copy(const struct lttng_payload *src_payload,
+ struct lttng_payload *dst_payload)
+{
+ int ret;
+ size_t i;
+
+ lttng_payload_init(dst_payload);
+ ret = lttng_dynamic_buffer_append_buffer(
+ &dst_payload->buffer, &src_payload->buffer);
+ if (ret) {
+ goto error;
+ }
+
+ for (i = 0; i < lttng_dynamic_array_get_count(&src_payload->_fds);
+ i++) {
+ int dst_fd;
+ const int src_fd = *((int *) lttng_dynamic_array_get_element(
+ &src_payload->_fds, i));
+
+ dst_fd = dup(src_fd);
+ if (dst_fd < 0) {
+ PERROR("Failed to duplicate file descriptor while copying a payload");
+ ret = dst_fd;
+ goto error;
+ }
+
+ ret = lttng_payload_push_fd(dst_payload, dst_fd);
+ if (ret) {
+ const int close_ret = close(dst_fd);
+
+ if (close_ret < 0) {
+ PERROR("Failed to close duplicated file descriptor while copying a payload");
+ }
+
+ goto error;
+ }
+ }
+
+end:
+ return ret;
+error:
+ lttng_payload_reset(dst_payload);
+ goto end;
+}
+
LTTNG_HIDDEN
void lttng_payload_reset(struct lttng_payload *payload)
{
LTTNG_HIDDEN
void lttng_payload_init(struct lttng_payload *payload);
+/* Copy a payload. */
+LTTNG_HIDDEN
+int lttng_payload_copy(const struct lttng_payload *src_payload,
+ struct lttng_payload *dst_payload);
+
/* Release any memory used by the payload. */
LTTNG_HIDDEN
void lttng_payload_reset(struct lttng_payload *payload);
uint32_t pid; /* pid_t */
uint32_t cmd_header_size;
uint32_t data_size;
+ uint32_t fd_count;
} LTTNG_PACKED;
struct lttcomm_lttng_output_id {
* Returns the size of data sent, or negative error value.
*/
LTTNG_HIDDEN
-ssize_t lttcomm_send_creds_unix_sock(int sock, void *buf, size_t len)
+ssize_t lttcomm_send_creds_unix_sock(int sock, const void *buf, size_t len)
{
struct msghdr msg;
struct iovec iov[1];
memset(&msg, 0, sizeof(msg));
- iov[0].iov_base = buf;
+ iov[0].iov_base = (void *) buf;
iov[0].iov_len = len;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
ssize_t lttcomm_send_unix_sock_non_block(int sock, const void *buf, size_t len);
LTTNG_HIDDEN
-ssize_t lttcomm_send_creds_unix_sock(int sock, void *buf, size_t len);
+ssize_t lttcomm_send_creds_unix_sock(int sock, const void *buf, size_t len);
LTTNG_HIDDEN
ssize_t lttcomm_recv_creds_unix_sock(int sock, void *buf, size_t len,
lttng_sock_cred *creds);
*
*/
+#include "lttng/lttng-error.h"
#include <assert.h>
#include <common/compat/string.h>
#include <common/error.h>
static
int lttng_userspace_probe_location_lookup_method_serialize(
struct lttng_userspace_probe_location_lookup_method *method,
- struct lttng_dynamic_buffer *buffer)
+ struct lttng_payload *payload)
{
int ret;
struct lttng_userspace_probe_location_lookup_method_comm
lookup_method_comm.type = (int8_t) (method ? method->type :
LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT);
- if (buffer) {
- ret = lttng_dynamic_buffer_append(buffer, &lookup_method_comm,
+ if (payload) {
+ ret = lttng_dynamic_buffer_append(&payload->buffer, &lookup_method_comm,
sizeof(lookup_method_comm));
if (ret) {
goto end;
static
int lttng_userspace_probe_location_function_serialize(
const struct lttng_userspace_probe_location *location,
- struct lttng_dynamic_buffer *buffer,
- int *binary_fd)
+ struct lttng_payload *payload)
{
int ret;
size_t function_name_len, binary_path_len;
goto end;
}
- if (binary_fd && location_function->binary_fd < 0) {
+ if (payload && location_function->binary_fd < 0) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- if (binary_fd) {
- *binary_fd = location_function->binary_fd;
- }
-
function_name_len = strlen(location_function->function_name);
if (function_name_len == 0) {
ret = -LTTNG_ERR_INVALID;
location_function_comm.function_name_len = function_name_len + 1;
location_function_comm.binary_path_len = binary_path_len + 1;
- if (buffer) {
- ret = lttng_dynamic_buffer_append(buffer,
+ if (payload) {
+ ret = lttng_dynamic_buffer_append(&payload->buffer,
&location_function_comm,
sizeof(location_function_comm));
if (ret) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- ret = lttng_dynamic_buffer_append(buffer,
+ ret = lttng_dynamic_buffer_append(&payload->buffer,
location_function->function_name,
location_function_comm.function_name_len);
if (ret) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- ret = lttng_dynamic_buffer_append(buffer,
+ ret = lttng_dynamic_buffer_append(&payload->buffer,
location_function->binary_path,
location_function_comm.binary_path_len);
if (ret) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
+ ret = lttng_payload_push_fd(
+ payload, location_function->binary_fd);
+ if (ret) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
}
ret = sizeof(location_function_comm) +
location_function_comm.function_name_len +
static
int lttng_userspace_probe_location_tracepoint_serialize(
const struct lttng_userspace_probe_location *location,
- struct lttng_dynamic_buffer *buffer,
- int *binary_fd)
+ struct lttng_payload *payload)
{
int ret;
size_t probe_name_len, provider_name_len, binary_path_len;
goto end;
}
- if (binary_fd && location_tracepoint->binary_fd < 0) {
+ if (payload && location_tracepoint->binary_fd < 0) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- if (binary_fd) {
- *binary_fd = location_tracepoint->binary_fd;
- }
-
probe_name_len = strlen(location_tracepoint->probe_name);
if (probe_name_len == 0) {
ret = -LTTNG_ERR_INVALID;
location_tracepoint_comm.provider_name_len = provider_name_len + 1;
location_tracepoint_comm.binary_path_len = binary_path_len + 1;
- if (buffer) {
- ret = lttng_dynamic_buffer_append(buffer,
+ if (payload) {
+ ret = lttng_dynamic_buffer_append(&payload->buffer,
&location_tracepoint_comm,
sizeof(location_tracepoint_comm));
if (ret) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- ret = lttng_dynamic_buffer_append(buffer,
+ ret = lttng_dynamic_buffer_append(&payload->buffer,
location_tracepoint->probe_name,
location_tracepoint_comm.probe_name_len);
if (ret) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- ret = lttng_dynamic_buffer_append(buffer,
+ ret = lttng_dynamic_buffer_append(&payload->buffer,
location_tracepoint->provider_name,
location_tracepoint_comm.provider_name_len);
if (ret) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- ret = lttng_dynamic_buffer_append(buffer,
+ ret = lttng_dynamic_buffer_append(&payload->buffer,
location_tracepoint->binary_path,
location_tracepoint_comm.binary_path_len);
if (ret) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
+ ret = lttng_payload_push_fd(
+ payload, location_tracepoint->binary_fd);
+ if (ret) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
}
+
ret = sizeof(location_tracepoint_comm) +
location_tracepoint_comm.probe_name_len +
location_tracepoint_comm.provider_name_len +
LTTNG_HIDDEN
int lttng_userspace_probe_location_serialize(
const struct lttng_userspace_probe_location *location,
- struct lttng_dynamic_buffer *buffer,
- int *binary_fd)
+ struct lttng_payload *payload)
{
int ret, buffer_use = 0;
struct lttng_userspace_probe_location_comm location_generic_comm;
memset(&location_generic_comm, 0, sizeof(location_generic_comm));
location_generic_comm.type = (int8_t) location->type;
- if (buffer) {
- ret = lttng_dynamic_buffer_append(buffer, &location_generic_comm,
+ if (payload) {
+ ret = lttng_dynamic_buffer_append(&payload->buffer,
+ &location_generic_comm,
sizeof(location_generic_comm));
if (ret) {
goto end;
switch (lttng_userspace_probe_location_get_type(location)) {
case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
ret = lttng_userspace_probe_location_function_serialize(
- location, buffer, binary_fd);
+ location, payload);
break;
case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
ret = lttng_userspace_probe_location_tracepoint_serialize(
- location, buffer, binary_fd);
+ location, payload);
break;
default:
ERR("Unsupported probe location type");
buffer_use += ret;
ret = lttng_userspace_probe_location_lookup_method_serialize(
- location->lookup_method, buffer);
+ location->lookup_method, payload);
if (ret < 0) {
goto end;
}
}
static
-int lttng_userspace_probe_location_function_create_from_buffer(
- const struct lttng_buffer_view *buffer,
+int lttng_userspace_probe_location_function_create_from_payload(
+ struct lttng_payload_view *view,
struct lttng_userspace_probe_location **location)
{
struct lttng_userspace_probe_location_function_comm *location_function_comm;
const char *function_name_src, *binary_path_src;
char *function_name = NULL, *binary_path = NULL;
int ret = 0;
+ size_t expected_size;
+ const int binary_fd = lttng_payload_view_pop_fd(view);
- assert(buffer);
- assert(buffer->data);
assert(location);
+ if (binary_fd < 0) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ if (view->buffer.size < sizeof(*location_function_comm)) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+
location_function_comm =
- (struct lttng_userspace_probe_location_function_comm *) buffer->data;
+ (typeof(location_function_comm)) view->buffer.data;
- const size_t expected_size = sizeof(*location_function_comm) +
+ expected_size = sizeof(*location_function_comm) +
location_function_comm->function_name_len +
location_function_comm->binary_path_len;
- if (buffer->size < expected_size) {
+ if (view->buffer.size < expected_size) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- function_name_src = buffer->data + sizeof(*location_function_comm);
+ function_name_src = view->buffer.data + sizeof(*location_function_comm);
binary_path_src = function_name_src +
location_function_comm->function_name_len;
goto end;
}
+ ret = lttng_userspace_probe_location_function_set_binary_fd(
+ *location, binary_fd);
+ if (ret) {
+ const int close_ret = close(binary_fd);
+
+ if (close_ret) {
+ PERROR("Failed to close userspace probe function binary fd");
+ }
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+
ret = (int) expected_size;
end:
free(function_name);
}
static
-int lttng_userspace_probe_location_tracepoint_create_from_buffer(
- const struct lttng_buffer_view *buffer,
+int lttng_userspace_probe_location_tracepoint_create_from_payload(
+ struct lttng_payload_view *view,
struct lttng_userspace_probe_location **location)
{
struct lttng_userspace_probe_location_tracepoint_comm *location_tracepoint_comm;
const char *probe_name_src, *provider_name_src, *binary_path_src;
char *probe_name = NULL, *provider_name = NULL, *binary_path = NULL;
int ret = 0;
+ size_t expected_size;
+ const int binary_fd = lttng_payload_view_pop_fd(view);
- assert(buffer);
- assert(buffer->data);
assert(location);
+ if (binary_fd < 0) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ if (view->buffer.size < sizeof(*location_tracepoint_comm)) {
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+
location_tracepoint_comm =
- (struct lttng_userspace_probe_location_tracepoint_comm *) buffer->data;
+ (typeof(location_tracepoint_comm)) view->buffer.data;
- const size_t expected_size = sizeof(*location_tracepoint_comm) +
+ expected_size = sizeof(*location_tracepoint_comm) +
location_tracepoint_comm->probe_name_len +
location_tracepoint_comm->provider_name_len +
location_tracepoint_comm->binary_path_len;
- if (buffer->size < expected_size) {
+ if (view->buffer.size < expected_size) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- probe_name_src = buffer->data + sizeof(*location_tracepoint_comm);
+ probe_name_src = view->buffer.data + sizeof(*location_tracepoint_comm);
provider_name_src = probe_name_src +
location_tracepoint_comm->probe_name_len;
binary_path_src = provider_name_src +
goto end;
}
+ ret = lttng_userspace_probe_location_tracepoint_set_binary_fd(
+ *location, binary_fd);
+ if (ret) {
+ const int close_ret = close(binary_fd);
+
+ if (close_ret) {
+ PERROR("Failed to close userspace probe tracepoint binary fd");
+ }
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
+ }
+
ret = (int) expected_size;
end:
free(probe_name);
}
static
-int lttng_userspace_probe_location_lookup_method_create_from_buffer(
- struct lttng_buffer_view *buffer,
+int lttng_userspace_probe_location_lookup_method_create_from_payload(
+ struct lttng_payload_view *view,
struct lttng_userspace_probe_location_lookup_method **lookup_method)
{
int ret;
struct lttng_userspace_probe_location_lookup_method_comm *lookup_comm;
enum lttng_userspace_probe_location_lookup_method_type type;
- assert(buffer);
- assert(buffer->data);
+ assert(view);
assert(lookup_method);
- if (buffer->size < sizeof(*lookup_comm)) {
+ if (view->buffer.size < sizeof(*lookup_comm)) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- lookup_comm = (struct lttng_userspace_probe_location_lookup_method_comm *)
- buffer->data;
+ lookup_comm = (typeof(lookup_comm)) view->buffer.data;
type = (enum lttng_userspace_probe_location_lookup_method_type)
lookup_comm->type;
switch (type) {
}
LTTNG_HIDDEN
-int lttng_userspace_probe_location_create_from_buffer(
- const struct lttng_buffer_view *buffer,
+int lttng_userspace_probe_location_create_from_payload(
+ struct lttng_payload_view *view,
struct lttng_userspace_probe_location **location)
{
struct lttng_userspace_probe_location_lookup_method *lookup_method;
struct lttng_userspace_probe_location_comm *probe_location_comm;
enum lttng_userspace_probe_location_type type;
- struct lttng_buffer_view lookup_method_view;
int consumed = 0;
int ret;
-
- assert(buffer);
- assert(buffer->data);
+ assert(view);
assert(location);
lookup_method = NULL;
- if (buffer->size <= sizeof(*probe_location_comm)) {
+ if (view->buffer.size <= sizeof(*probe_location_comm)) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- probe_location_comm =
- (struct lttng_userspace_probe_location_comm *) buffer->data;
+ probe_location_comm = (typeof(probe_location_comm)) view->buffer.data;
type = (enum lttng_userspace_probe_location_type) probe_location_comm->type;
consumed += sizeof(*probe_location_comm);
switch (type) {
case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
{
- struct lttng_buffer_view view = lttng_buffer_view_from_view(
- buffer, consumed, buffer->size - consumed);
+ struct lttng_payload_view location_view =
+ lttng_payload_view_from_view(
+ view, consumed, -1);
- ret = lttng_userspace_probe_location_function_create_from_buffer(
- &view, location);
+ ret = lttng_userspace_probe_location_function_create_from_payload(
+ &location_view, location);
if (ret < 0) {
goto end;
}
}
case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
{
- struct lttng_buffer_view view = lttng_buffer_view_from_view(
- buffer, consumed, buffer->size - consumed);
+ struct lttng_payload_view location_view =
+ lttng_payload_view_from_view(view, consumed, -1);
- ret = lttng_userspace_probe_location_tracepoint_create_from_buffer(
- &view, location);
+ ret = lttng_userspace_probe_location_tracepoint_create_from_payload(
+ &location_view, location);
if (ret < 0) {
goto end;
}
}
consumed += ret;
- if (buffer->size <= consumed) {
+ if (view->buffer.size <= consumed) {
ret = -LTTNG_ERR_INVALID;
goto end;
}
- lookup_method_view = lttng_buffer_view_from_view(buffer, consumed,
- buffer->size - consumed);
- ret = lttng_userspace_probe_location_lookup_method_create_from_buffer(
- &lookup_method_view, &lookup_method);
+ {
+ struct lttng_payload_view lookup_method_view =
+ lttng_payload_view_from_view(
+ view, consumed, -1);
+
+ ret = lttng_userspace_probe_location_lookup_method_create_from_payload(
+ &lookup_method_view, &lookup_method);
+ }
if (ret < 0) {
ret = -LTTNG_ERR_INVALID;
goto end;
void **user_payload_buf, void **user_cmd_header_buf,
size_t *user_cmd_header_len);
+/*
+ * Sends the lttcomm message to the session daemon and fills the reply payload.
+ *
+ * Return the size of the received data on success or else a negative lttng
+ * error code.
+ */
+LTTNG_HIDDEN
+int lttng_ctl_ask_sessiond_payload(struct lttng_payload_view *message,
+ struct lttng_payload *reply);
+
/*
* Calls lttng_ctl_ask_sessiond_fds_varlen() with no expected command header.
*/
* Receive data from the sessiond socket.
*
* On success, returns the number of bytes received (>=0)
- * On error, returns -1 (recvmsg() error) or -ENOTCONN
+ * On error, returns a negative lttng_error_code.
*/
static int recv_data_sessiond(void *buf, size_t len)
{
return ret;
}
+/*
+ * Receive a payload from the session daemon by appending to an existing
+ * payload.
+ * On success, returns the number of bytes received (>=0)
+ * On error, returns a negative lttng_error_code.
+ */
+static int recv_payload_sessiond(struct lttng_payload *payload, size_t len)
+{
+ int ret;
+ const size_t original_payload_size = payload->buffer.size;
+
+ ret = lttng_dynamic_buffer_set_size(
+ &payload->buffer, payload->buffer.size + len);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ ret = recv_data_sessiond(
+ payload->buffer.data + original_payload_size, len);
+end:
+ return ret;
+}
+
/*
* Check if we are in the specified group.
*
connected = 1;
}
- /* Send command to session daemon */
ret = send_session_msg(lsm);
if (ret < 0) {
/* Ret value is a valid lttng error code. */
return ret;
}
+LTTNG_HIDDEN
+int lttng_ctl_ask_sessiond_payload(struct lttng_payload_view *message,
+ struct lttng_payload *reply)
+{
+ int ret;
+ struct lttcomm_lttng_msg llm;
+
+ assert(reply->buffer.size == 0);
+ assert(reply->_fds.size == 0);
+
+ ret = connect_sessiond();
+ if (ret < 0) {
+ ret = -LTTNG_ERR_NO_SESSIOND;
+ goto end;
+ } else {
+ sessiond_socket = ret;
+ connected = 1;
+ }
+
+ /* Send command to session daemon */
+ ret = lttcomm_send_creds_unix_sock(sessiond_socket, message->buffer.data,
+ message->buffer.size);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_FATAL;
+ goto end;
+ }
+
+ if (lttng_payload_view_get_fd_count(message) > 0) {
+ ret = lttcomm_send_fds_unix_sock(sessiond_socket,
+ (const int *) message->_fds.buffer.data,
+ lttng_dynamic_array_get_count(&message->_fds));
+ }
+
+ /* Get header from data transmission */
+ ret = recv_payload_sessiond(reply, sizeof(llm));
+ if (ret < 0) {
+ /* Ret value is a valid lttng error code. */
+ goto end;
+ }
+
+ llm = *((typeof(llm) *) reply->buffer.data);
+
+ /* Check error code if OK */
+ if (llm.ret_code != LTTNG_OK) {
+ ret = -llm.ret_code;
+ goto end;
+ }
+
+ if (llm.cmd_header_size > 0) {
+ ret = recv_payload_sessiond(reply, llm.cmd_header_size);
+ if (ret < 0) {
+ goto end;
+ }
+ }
+
+ /* Get command header from data transmission */
+ if (llm.data_size > 0) {
+ ret = recv_payload_sessiond(reply, llm.data_size);
+ if (ret < 0) {
+ goto end;
+ }
+ }
+
+ if (llm.fd_count > 0) {
+ ret = lttng_dynamic_array_set_count(&reply->_fds, llm.fd_count);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ ret = lttcomm_recv_fds_unix_sock(sessiond_socket,
+ (int *) reply->_fds.buffer.data, llm.fd_count);
+ if (ret > 0 && ret != llm.fd_count * sizeof(int)) {
+ ret = -LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ } else if (ret <= 0) {
+ ret = -LTTNG_ERR_FATAL;
+ goto end;
+ }
+ }
+
+ /* Don't return the llm header to the caller. */
+ memmove(reply->buffer.data, reply->buffer.data + sizeof(llm),
+ reply->buffer.size - sizeof(llm));
+ ret = lttng_dynamic_buffer_set_size(
+ &reply->buffer, reply->buffer.size - sizeof(llm));
+ if (ret) {
+ /* Can't happen as size is reduced. */
+ abort();
+ }
+
+ ret = reply->buffer.size;
+
+end:
+ disconnect_sessiond();
+ return ret;
+}
+
/*
* Create lttng handle and return pointer.
*
int exclusion_count, char **exclusion_list)
{
struct lttcomm_session_msg lsm;
- struct lttng_dynamic_buffer send_buffer;
- int ret = 0, i, fd_to_send = -1;
- bool send_fd = false;
+ struct lttng_payload payload;
+ int ret = 0, i;
unsigned int free_filter_expression = 0;
struct filter_parser_ctx *ctx = NULL;
/*
* We have either a filter or some exclusions, so we need to set up
- * a variable-length memory block from where to send the data.
+ * a variable-length payload from where to send the data.
*/
- lttng_dynamic_buffer_init(&send_buffer);
+ lttng_payload_init(&payload);
/*
* Cast as non-const since we may replace the filter expression
}
}
- ret = lttng_dynamic_buffer_set_capacity(&send_buffer,
- lsm.u.enable.bytecode_len
- + lsm.u.enable.expression_len
- + LTTNG_SYMBOL_NAME_LEN * exclusion_count);
+ ret = lttng_dynamic_buffer_set_capacity(&payload.buffer,
+ lsm.u.enable.bytecode_len +
+ lsm.u.enable.expression_len +
+ LTTNG_SYMBOL_NAME_LEN *
+ exclusion_count);
if (ret) {
ret = -LTTNG_ERR_EXCLUSION_NOMEM;
goto mem_error;
goto mem_error;
}
- ret = lttng_dynamic_buffer_append(&send_buffer,
- *(exclusion_list + i),
- LTTNG_SYMBOL_NAME_LEN);
+ ret = lttng_dynamic_buffer_append(&payload.buffer,
+ *(exclusion_list + i), LTTNG_SYMBOL_NAME_LEN);
if (ret) {
goto mem_error;
}
/* Add filter expression next. */
if (filter_expression) {
- ret = lttng_dynamic_buffer_append(&send_buffer,
+ ret = lttng_dynamic_buffer_append(&payload.buffer,
filter_expression, lsm.u.enable.expression_len);
if (ret) {
goto mem_error;
}
/* Add filter bytecode next. */
if (ctx && lsm.u.enable.bytecode_len != 0) {
- ret = lttng_dynamic_buffer_append(&send_buffer,
+ ret = lttng_dynamic_buffer_append(&payload.buffer,
&ctx->bytecode->b, lsm.u.enable.bytecode_len);
if (ret) {
goto mem_error;
* number of bytes that was appended to the buffer.
*/
ret = lttng_userspace_probe_location_serialize(
- ev_ext->probe_location, &send_buffer,
- &fd_to_send);
+ ev_ext->probe_location, &payload);
if (ret < 0) {
goto mem_error;
}
- send_fd = fd_to_send >= 0;
/*
* Set the size of the userspace probe location element
* of the buffer so that the receiving side knows where
}
}
- ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
- send_fd ? &fd_to_send : NULL,
- send_fd ? 1 : 0,
- send_buffer.size ? send_buffer.data : NULL,
- send_buffer.size, NULL, NULL, 0);
+ {
+ struct lttng_payload_view view = lttng_payload_view_from_payload(
+ &payload, 0, -1);
+ int fd_count = lttng_payload_view_get_fd_count(&view);
+ int fd_to_send;
+
+ if (fd_count < 0) {
+ goto mem_error;
+ }
+
+ assert(fd_count == 0 || fd_count == 1);
+ if (fd_count == 1) {
+ ret = lttng_payload_view_pop_fd(&view);
+ if (ret < 0) {
+ goto mem_error;
+ }
+
+ fd_to_send = ret;
+ }
+
+ ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm,
+ fd_count ? &fd_to_send : NULL, fd_count,
+ view.buffer.size ? view.buffer.data : NULL,
+ view.buffer.size, NULL, NULL, 0);
+ }
mem_error:
if (filter_expression && ctx) {
* Return directly to the caller and don't ask the sessiond since
* something went wrong in the parsing of data above.
*/
- lttng_dynamic_buffer_reset(&send_buffer);
+ lttng_payload_reset(&payload);
return ret;
ask_sessiond:
const char *channel_name, struct lttng_event **events)
{
int ret;
- struct lttcomm_session_msg lsm;
- struct lttcomm_event_command_header *cmd_header = NULL;
- size_t cmd_header_len;
+ struct lttcomm_session_msg lsm = {};
+ const struct lttcomm_event_command_header *cmd_header = NULL;
uint32_t nb_events, i;
- void *comm_ext_at;
- char *reception_buffer = NULL;
+ const void *comm_ext_at;
struct lttng_dynamic_buffer listing;
size_t storage_req;
+ struct lttng_payload payload;
+ struct lttng_payload payload_copy;
+ struct lttng_payload_view lsm_view =
+ lttng_payload_view_init_from_buffer(
+ (const char *) &lsm, 0, sizeof(lsm));
+ struct lttng_buffer_view cmd_header_view;
+ struct lttng_buffer_view cmd_payload_view;
+ struct lttng_buffer_view flat_events_view;
+ struct lttng_buffer_view ext_view;
/* Safety check. An handle and channel name are mandatory */
if (handle == NULL || channel_name == NULL) {
- return -LTTNG_ERR_INVALID;
+ ret = -LTTNG_ERR_INVALID;
+ goto end;
}
- memset(&lsm, 0, sizeof(lsm));
+ lttng_payload_init(&payload);
+ lttng_payload_init(&payload_copy);
+
lsm.cmd_type = LTTNG_LIST_EVENTS;
lttng_ctl_copy_string(lsm.session.name, handle->session_name,
sizeof(lsm.session.name));
sizeof(lsm.u.list.channel_name));
COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
- ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm, NULL, 0, NULL, 0,
- (void **) &reception_buffer, (void **) &cmd_header,
- &cmd_header_len);
+ ret = lttng_ctl_ask_sessiond_payload(&lsm_view, &payload);
if (ret < 0) {
goto end;
}
- if (!cmd_header) {
- ret = -LTTNG_ERR_UNK;
+ /*
+ * A copy of the payload is performed since it will be
+ * consumed twice. Consuming the same payload twice is invalid since
+ * it will cause any received file descriptor to become "shared"
+ * between different instances of the resulting objects.
+ */
+ ret = lttng_payload_copy(&payload, &payload_copy);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
goto end;
}
+ cmd_header_view = lttng_buffer_view_from_dynamic_buffer(
+ &payload.buffer, 0, sizeof(*cmd_header));
+ if (!cmd_header_view.data) {
+ ret = -LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ }
+
+ cmd_header = (typeof(cmd_header)) cmd_header_view.data;
+
/* Set number of events and free command header */
nb_events = cmd_header->nb_events;
if (nb_events > INT_MAX) {
ret = -LTTNG_ERR_OVERFLOW;
goto end;
}
- free(cmd_header);
- cmd_header = NULL;
+
+ cmd_payload_view = lttng_buffer_view_from_dynamic_buffer(
+ &payload.buffer, sizeof(*cmd_header), -1);
/*
* The buffer that is returned must contain a "flat" version of
* - exclusions
* - padding to align to 64-bits
*/
- comm_ext_at = reception_buffer +
- (nb_events * sizeof(struct lttng_event));
+ ext_view = lttng_buffer_view_from_view(&cmd_payload_view,
+ nb_events * sizeof(struct lttng_event), -1);
+ comm_ext_at = ext_view.data;
storage_req = nb_events * sizeof(struct lttng_event);
+ {
+ struct lttng_payload_view payload_view =
+ lttng_payload_view_from_payload(&payload, 0, -1);
- for (i = 0; i < nb_events; i++) {
- struct lttcomm_event_extended_header *ext_comm =
- (struct lttcomm_event_extended_header *) comm_ext_at;
- int probe_storage_req = 0;
-
- comm_ext_at += sizeof(*ext_comm);
- comm_ext_at += ext_comm->filter_len;
- comm_ext_at +=
- ext_comm->nb_exclusions * LTTNG_SYMBOL_NAME_LEN;
+ for (i = 0; i < nb_events; i++) {
+ const struct lttcomm_event_extended_header *ext_comm =
+ (struct lttcomm_event_extended_header *)
+ comm_ext_at;
+ int probe_storage_req = 0;
- if (ext_comm->userspace_probe_location_len) {
- struct lttng_userspace_probe_location *probe_location = NULL;
- struct lttng_buffer_view probe_location_view;
+ comm_ext_at += sizeof(*ext_comm);
+ comm_ext_at += ext_comm->filter_len;
+ comm_ext_at += ext_comm->nb_exclusions *
+ LTTNG_SYMBOL_NAME_LEN;
+
+ if (ext_comm->userspace_probe_location_len) {
+ struct lttng_userspace_probe_location
+ *probe_location = NULL;
+ struct lttng_payload_view probe_location_view = lttng_payload_view_from_view(
+ &payload_view,
+ (const char *) comm_ext_at -
+ payload_view.buffer.data,
+ ext_comm->userspace_probe_location_len);
- probe_location_view = lttng_buffer_view_init(
- comm_ext_at, 0,
- ext_comm->userspace_probe_location_len);
+ /*
+ * Create a temporary userspace probe location
+ * to determine the size needed by a "flattened"
+ * version of that same probe location.
+ */
+ ret = lttng_userspace_probe_location_create_from_payload(
+ &probe_location_view,
+ &probe_location);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
+ goto end;
+ }
- /*
- * Create a temporary userspace probe location to
- * determine the size needed by a "flattened" version
- * of that same probe location.
- */
- ret = lttng_userspace_probe_location_create_from_buffer(
- &probe_location_view, &probe_location);
- if (ret < 0) {
- ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
- goto end;
- }
+ ret = lttng_userspace_probe_location_flatten(
+ probe_location, NULL);
+ lttng_userspace_probe_location_destroy(
+ probe_location);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
+ goto end;
+ }
- ret = lttng_userspace_probe_location_flatten(
- probe_location, NULL);
- lttng_userspace_probe_location_destroy(probe_location);
- if (ret < 0) {
- ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
- goto end;
+ probe_storage_req = ret;
+ comm_ext_at += ext_comm->userspace_probe_location_len;
}
- probe_storage_req = ret;
- comm_ext_at += ext_comm->userspace_probe_location_len;
+ storage_req += sizeof(struct lttng_event_extended);
+ storage_req += ext_comm->filter_len;
+ storage_req += ext_comm->nb_exclusions *
+ LTTNG_SYMBOL_NAME_LEN;
+ /* Padding to ensure the flat probe is aligned. */
+ storage_req = ALIGN_TO(storage_req, sizeof(uint64_t));
+ storage_req += probe_storage_req;
}
-
- storage_req += sizeof(struct lttng_event_extended);
- storage_req += ext_comm->filter_len;
- storage_req += ext_comm->nb_exclusions * LTTNG_SYMBOL_NAME_LEN;
- /* Padding to ensure the flat probe is aligned. */
- storage_req = ALIGN_TO(storage_req, sizeof(uint64_t));
- storage_req += probe_storage_req;
}
lttng_dynamic_buffer_init(&listing);
goto end;
}
- ret = lttng_dynamic_buffer_append(&listing, reception_buffer,
+ cmd_payload_view = lttng_buffer_view_from_dynamic_buffer(
+ &payload_copy.buffer, sizeof(*cmd_header), -1);
+ flat_events_view = lttng_buffer_view_from_view(&cmd_payload_view, 0,
nb_events * sizeof(struct lttng_event));
+ ret = lttng_dynamic_buffer_append_view(&listing, &flat_events_view);
if (ret) {
ret = -LTTNG_ERR_NOMEM;
goto free_dynamic_buffer;
}
- comm_ext_at = reception_buffer +
- (nb_events * sizeof(struct lttng_event));
- for (i = 0; i < nb_events; i++) {
- struct lttng_event *event = (struct lttng_event *)
- (listing.data + (sizeof(struct lttng_event) * i));
- struct lttcomm_event_extended_header *ext_comm =
- (struct lttcomm_event_extended_header *) comm_ext_at;
- struct lttng_event_extended *event_extended =
- (struct lttng_event_extended *)
- (listing.data + listing.size);
-
- /* Insert struct lttng_event_extended. */
- ret = lttng_dynamic_buffer_set_size(&listing,
- listing.size + sizeof(*event_extended));
- if (ret) {
- ret = -LTTNG_ERR_NOMEM;
- goto free_dynamic_buffer;
- }
- event->extended.ptr = event_extended;
-
- comm_ext_at += sizeof(*ext_comm);
-
- /* Insert filter expression. */
- if (ext_comm->filter_len) {
- event_extended->filter_expression = listing.data +
- listing.size;
- ret = lttng_dynamic_buffer_append(&listing, comm_ext_at,
- ext_comm->filter_len);
+ ext_view = lttng_buffer_view_from_view(&cmd_payload_view,
+ nb_events * sizeof(struct lttng_event), -1);
+ comm_ext_at = ext_view.data;
+
+ {
+ struct lttng_payload_view payload_copy_view =
+ lttng_payload_view_from_payload(
+ &payload_copy, 0, -1);
+
+ for (i = 0; i < nb_events; i++) {
+ struct lttng_event *event = (typeof(event))(
+ listing.data +
+ (sizeof(struct lttng_event) * i));
+ const struct lttcomm_event_extended_header *ext_comm =
+ (typeof(ext_comm)) comm_ext_at;
+ struct lttng_event_extended *event_extended =
+ (typeof(event_extended))(listing.data +
+ listing.size);
+
+ /* Insert struct lttng_event_extended. */
+ ret = lttng_dynamic_buffer_set_size(&listing,
+ listing.size + sizeof(*event_extended));
if (ret) {
ret = -LTTNG_ERR_NOMEM;
goto free_dynamic_buffer;
}
- comm_ext_at += ext_comm->filter_len;
- }
+ event->extended.ptr = event_extended;
+
+ comm_ext_at += sizeof(*ext_comm);
+
+ /* Insert filter expression. */
+ if (ext_comm->filter_len) {
+ event_extended->filter_expression =
+ listing.data + listing.size;
+ ret = lttng_dynamic_buffer_append(&listing,
+ comm_ext_at,
+ ext_comm->filter_len);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto free_dynamic_buffer;
+ }
+ comm_ext_at += ext_comm->filter_len;
+ }
- /* Insert exclusions. */
- if (ext_comm->nb_exclusions) {
- event_extended->exclusions.count =
- ext_comm->nb_exclusions;
- event_extended->exclusions.strings =
- listing.data + listing.size;
+ /* Insert exclusions. */
+ if (ext_comm->nb_exclusions) {
+ event_extended->exclusions.count =
+ ext_comm->nb_exclusions;
+ event_extended->exclusions.strings =
+ listing.data + listing.size;
+
+ ret = lttng_dynamic_buffer_append(&listing,
+ comm_ext_at,
+ ext_comm->nb_exclusions *
+ LTTNG_SYMBOL_NAME_LEN);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto free_dynamic_buffer;
+ }
+ comm_ext_at += ext_comm->nb_exclusions *
+ LTTNG_SYMBOL_NAME_LEN;
+ }
- ret = lttng_dynamic_buffer_append(&listing,
- comm_ext_at,
- ext_comm->nb_exclusions * LTTNG_SYMBOL_NAME_LEN);
+ /* Insert padding to align to 64-bits. */
+ ret = lttng_dynamic_buffer_set_size(&listing,
+ ALIGN_TO(listing.size,
+ sizeof(uint64_t)));
if (ret) {
ret = -LTTNG_ERR_NOMEM;
goto free_dynamic_buffer;
}
- comm_ext_at += ext_comm->nb_exclusions * LTTNG_SYMBOL_NAME_LEN;
- }
-
- /* Insert padding to align to 64-bits. */
- ret = lttng_dynamic_buffer_set_size(&listing,
- ALIGN_TO(listing.size, sizeof(uint64_t)));
- if (ret) {
- ret = -LTTNG_ERR_NOMEM;
- goto free_dynamic_buffer;
- }
-
- /* Insert flattened userspace probe location. */
- if (ext_comm->userspace_probe_location_len) {
- struct lttng_userspace_probe_location *probe_location = NULL;
- struct lttng_buffer_view probe_location_view;
- probe_location_view = lttng_buffer_view_init(
- comm_ext_at, 0,
- ext_comm->userspace_probe_location_len);
+ /* Insert flattened userspace probe location. */
+ if (ext_comm->userspace_probe_location_len) {
+ struct lttng_userspace_probe_location
+ *probe_location = NULL;
+ struct lttng_payload_view probe_location_view = lttng_payload_view_from_view(
+ &payload_copy_view,
+ (const char *) comm_ext_at -
+ payload_copy_view.buffer.data,
+ ext_comm->userspace_probe_location_len);
+
+ ret = lttng_userspace_probe_location_create_from_payload(
+ &probe_location_view,
+ &probe_location);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
+ goto free_dynamic_buffer;
+ }
- ret = lttng_userspace_probe_location_create_from_buffer(
- &probe_location_view, &probe_location);
- if (ret < 0) {
- ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
- goto free_dynamic_buffer;
- }
+ event_extended->probe_location = (struct lttng_userspace_probe_location
+ *) (listing.data +
+ listing.size);
+ ret = lttng_userspace_probe_location_flatten(
+ probe_location, &listing);
+ lttng_userspace_probe_location_destroy(
+ probe_location);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
+ goto free_dynamic_buffer;
+ }
- event_extended->probe_location = (struct lttng_userspace_probe_location *)
- (listing.data + listing.size);
- ret = lttng_userspace_probe_location_flatten(
- probe_location, &listing);
- lttng_userspace_probe_location_destroy(probe_location);
- if (ret < 0) {
- ret = -LTTNG_ERR_PROBE_LOCATION_INVAL;
- goto free_dynamic_buffer;
+ comm_ext_at += ext_comm->userspace_probe_location_len;
}
-
- comm_ext_at += ext_comm->userspace_probe_location_len;
}
}
free_dynamic_buffer:
lttng_dynamic_buffer_reset(&listing);
end:
- free(cmd_header);
- free(reception_buffer);
+ lttng_payload_reset(&payload);
+ lttng_payload_reset(&payload_copy);
return ret;
}