lttng/session-descriptor.h \
lttng/destruction-handle.h \
lttng/clear.h \
- lttng/clear-handle.h
+ lttng/clear-handle.h \
+ lttng/tracker.h
lttngactioninclude_HEADERS= \
lttng/action/action.h \
lttng/userspace-probe-internal.h \
lttng/session-internal.h \
lttng/session-descriptor-internal.h \
+ lttng/tracker-internal.h \
version.h \
version.i
#include <lttng/notification/notification.h>
#include <lttng/trigger/trigger.h>
#include <lttng/rotation.h>
+#include <lttng/tracker.h>
#ifdef __cplusplus
extern "C" {
#include <lttng/constant.h>
-enum lttng_tracker_type {
- LTTNG_TRACKER_PID = 0,
- LTTNG_TRACKER_VPID = 1,
- LTTNG_TRACKER_UID = 2,
- LTTNG_TRACKER_GID = 3,
- LTTNG_TRACKER_VUID = 4,
- LTTNG_TRACKER_VGID = 5,
-};
-
-enum lttng_tracker_id_type {
- LTTNG_ID_UNKNOWN = -1,
- LTTNG_ID_ALL = 0,
- LTTNG_ID_VALUE = 1,
- LTTNG_ID_STRING = 2,
-};
-
-struct lttng_tracker_id {
- enum lttng_tracker_id_type type;
- int value;
- char *string;
-};
-
struct lttng_handle;
struct lttng_session_descriptor;
struct lttng_destruction_handle;
extern int lttng_set_session_shm_path(const char *session_name,
const char *shm_path);
-/*
- * Add ID to session tracker.
- *
- * tracker_type is the type of tracker.
- * id the id to track.
- *
- * Return 0 on success else a negative LTTng error code.
- */
-extern int lttng_track_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id);
-
-/*
- * Remove ID from session tracker.
- *
- * tracker_type is the type of tracker.
- * id the id to untrack.
- *
- * Return 0 on success else a negative LTTng error code.
- */
-extern int lttng_untrack_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id);
-
-/*
- * List IDs in the tracker.
- *
- * tracker_type is the type of tracker.
- * ids is set to an allocated array of IDs currently tracked. On
- * success, ids and the strings it contains must be freed by the
- * caller.
- * nr_ids is set to the number of entries contained by the ids array.
- *
- * Returns 0 on success, else a negative LTTng error code.
- */
-extern int lttng_list_tracker_ids(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- struct lttng_tracker_id **ids,
- size_t *nr_ids);
-
-/*
- * Add PID to session tracker.
- *
- * A pid argument >= 0 adds the PID to the session tracker.
- * A pid argument of -1 means "track all PIDs".
- *
- * Return 0 on success else a negative LTTng error code.
- */
-extern int lttng_track_pid(struct lttng_handle *handle, int pid);
-
-/*
- * Remove PID from session tracker.
- *
- * A pid argument >= 0 removes the PID from the session tracker.
- * A pid argument of -1 means "untrack all PIDs".
- *
- * Return 0 on success else a negative LTTng error code.
- */
-extern int lttng_untrack_pid(struct lttng_handle *handle, int pid);
-
-/*
- * List PIDs in the tracker.
- *
- * enabled is set to whether the PID tracker is enabled.
- * pids is set to an allocated array of PIDs currently tracked. On
- * success, pids must be freed by the caller.
- * nr_pids is set to the number of entries contained by the pids array.
- *
- * Returns 0 on success, else a negative LTTng error code.
- */
-extern int lttng_list_tracker_pids(struct lttng_handle *handle,
- int *enabled, int32_t **pids, size_t *nr_pids);
-
#ifdef __cplusplus
}
#endif
--- /dev/null
+/*
+ * Copyright (C) 2019 - Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License, version 2.1 only,
+ * as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LTTNG_TRACKER_INTERNAL_H
+#define LTTNG_TRACKER_INTERNAL_H
+
+#include <lttng/constant.h>
+#include <common/macros.h>
+#include <lttng/tracker.h>
+#include <stdbool.h>
+
+struct lttng_tracker_id {
+ enum lttng_tracker_id_type type;
+ int value;
+ char *string;
+};
+
+LTTNG_HIDDEN
+bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left,
+ const struct lttng_tracker_id *right);
+
+LTTNG_HIDDEN
+struct lttng_tracker_id *lttng_tracker_id_copy(
+ const struct lttng_tracker_id *orig);
+
+#endif /* LTTNG_TRACKER_INTERNAL_H */
--- /dev/null
+/*
+ * Copyright (C) 2019 - Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License, version 2.1 only,
+ * as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef LTTNG_TRACKER_H
+#define LTTNG_TRACKER_H
+
+#include <lttng/constant.h>
+#include <common/macros.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum lttng_tracker_type {
+ LTTNG_TRACKER_PID = 0,
+ LTTNG_TRACKER_VPID = 1,
+ LTTNG_TRACKER_UID = 2,
+ LTTNG_TRACKER_GID = 3,
+ LTTNG_TRACKER_VUID = 4,
+ LTTNG_TRACKER_VGID = 5,
+};
+
+enum lttng_tracker_id_type {
+ LTTNG_ID_UNKNOWN = -1,
+ LTTNG_ID_ALL = 0,
+ LTTNG_ID_VALUE = 1,
+ LTTNG_ID_STRING = 2,
+};
+
+enum lttng_tracker_id_status {
+ /* Invalid tracker id parameter. */
+ LTTNG_TRACKER_ID_STATUS_INVALID = -1,
+ LTTNG_TRACKER_ID_STATUS_OK = 0,
+ /* Tracker id parameter is unset. */
+ LTTNG_TRACKER_ID_STATUS_UNSET = 1,
+};
+
+struct lttng_handle;
+struct lttng_tracker_id;
+
+/*
+ * Create a tracker id for the passed tracker type.
+ * Users must set the tracker id using the matching API call.
+ *
+ * On success, the caller is responsible for calling lttng_tracker_id_destroy.
+ * On error, return NULL.
+ */
+extern struct lttng_tracker_id *lttng_tracker_id_create(void);
+
+/*
+ * Configure the tracker id using the numerical representation of the resource
+ * to be tracked/untracked.
+ *
+ * If the tracker id was already configured, calling this function will replace
+ * the previous configuration and free memory as necessary.
+ *
+ * Returns LTTNG_TRACKER_ID_STATUS_OK on success,
+ * LTTNG_TRACKER_ID_STATUS_INVALID is the passed parameter is invalid.
+ */
+extern enum lttng_tracker_id_status lttng_tracker_id_set_value(
+ struct lttng_tracker_id *id, int value);
+
+/*
+ * Configure the tracker id using the string representation of the resource to
+ * be tracked/untracked.
+ *
+ * If the tracker id was already configured, calling this function will replace
+ * the previous configuration and free memory as necessary.
+ *
+ * Returns LTTNG_TRACKER_ID_STATUS_OK on success,
+ * LTTNG_TRACKER_ID_STATUS_INVALID if the passed parameter is invalid.
+ */
+extern enum lttng_tracker_id_status lttng_tracker_id_set_string(
+ struct lttng_tracker_id *id, const char *value);
+
+/*
+ * Configure the tracker id to track/untrack all resources for the tracker type.
+ *
+ * If the tracker id was already configured, calling this function will replace
+ * the previous configuration and free memory as necessary.
+ *
+ * Returns LTTNG_TRACKER_ID_STATUS_OK on success,
+ * LTTNG_TRACKER_ID_STATUS_INVALID if the passed parameter is invalid.
+ */
+extern enum lttng_tracker_id_status lttng_tracker_id_set_all(
+ struct lttng_tracker_id *id);
+
+/*
+ * Destroys (frees) a tracker id.
+ */
+extern void lttng_tracker_id_destroy(struct lttng_tracker_id *id);
+
+/*
+ * Returns the type of the tracker id.
+ */
+extern enum lttng_tracker_id_type lttng_tracker_id_get_type(
+ const struct lttng_tracker_id *id);
+
+/*
+ * Returns the value of the tracker id.
+ *
+ * Returns LTTNG_TRACKER_ID_OK on success,
+ * LTTNG_TRACKER_ID_STATUS_INVALID when the tracker is not of type
+ * LTTNG_ID_VALUE,
+ * LTTNG_TRACKER_ID_STATUS_UNSET when the tracker is not set.
+ */
+extern enum lttng_tracker_id_status lttng_tracker_id_get_value(
+ const struct lttng_tracker_id *id, int *value);
+
+/*
+ * Returns the string representation of the tracker id.
+ *
+ * Returns LTTNG_TRACKER_ID_OK on success,
+ * LTTNG_TRACKER_ID_STATUS_INVALID when the tracker is not of type
+ * LTTNG_ID_STRING,
+ * LTTNG_TRACKER_ID_STATUS_UNSET when the tracker is not set.
+ */
+extern enum lttng_tracker_id_status lttng_tracker_id_get_string(
+ const struct lttng_tracker_id *id, const char **value);
+
+/*
+ * Destroys (frees) an array of tracker id.
+ */
+extern void lttng_tracker_ids_destroy(
+ struct lttng_tracker_id **ids, size_t nr_ids);
+
+/*
+ * Add ID to session tracker.
+ *
+ * tracker_type is the type of tracker.
+ * id is the lttng_tracker_type to track.
+ *
+ * Returns 0 on success else a negative LTTng error code.
+ */
+extern int lttng_track_id(struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type,
+ const struct lttng_tracker_id *id);
+
+/*
+ * Remove ID from session tracker.
+ *
+ * tracker_type is the type of tracker.
+ * id is the lttng_tracker_type to untrack.
+ * Returns 0 on success else a negative LTTng error code.
+ */
+extern int lttng_untrack_id(struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type,
+ const struct lttng_tracker_id *id);
+
+/*
+ * List IDs in the tracker.
+ *
+ * tracker_type is the type of tracker.
+ * ids is set to an allocated array of IDs currently tracked.
+ * On success, ids must be freed using lttng_tracker_id_destroy on each
+ * constituent of the returned array or using lttng_tracker_ids_destroy.
+ * nr_ids is set to the number of entries contained by the ids array.
+ *
+ * Returns 0 on success, else a negative LTTng error code.
+ */
+extern int lttng_list_tracker_ids(struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type,
+ struct lttng_tracker_id ***ids,
+ size_t *nr_ids);
+
+/*
+ * Backward compatibility.
+ * Add PID to session tracker.
+ *
+ * A pid argument >= 0 adds the PID to the session tracker.
+ * A pid argument of -1 means "track all PIDs".
+ *
+ * Returns 0 on success else a negative LTTng error code.
+ */
+extern int lttng_track_pid(struct lttng_handle *handle, int pid);
+
+/*
+ * Backward compatibility.
+ * Remove PID from session tracker.
+ *
+ * A pid argument >= 0 removes the PID from the session tracker.
+ * A pid argument of -1 means "untrack all PIDs".
+ *
+ * Returns 0 on success else a negative LTTng error code.
+ */
+extern int lttng_untrack_pid(struct lttng_handle *handle, int pid);
+
+/*
+ * Backward compatibility
+ * List PIDs in the tracker.
+ *
+ * enabled is set to whether the PID tracker is enabled.
+ * pids is set to an allocated array of PIDs currently tracked. On
+ * success, pids must be freed by the caller.
+ * nr_pids is set to the number of entries contained by the pids array.
+ *
+ * Returns 0 on success, else a negative LTTng error code.
+ */
+extern int lttng_list_tracker_pids(struct lttng_handle *handle,
+ int *enabled,
+ int32_t **pids,
+ size_t *nr_pids);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LTTNG_TRACKER_H */
}
case LTTNG_TRACK_ID:
{
- struct lttng_tracker_id id;
+ struct lttng_tracker_id *id = NULL;
+ enum lttng_tracker_id_status status;
- memset(&id, 0, sizeof(id));
- id.type = cmd_ctx->lsm->u.id_tracker.id_type;
- switch (id.type) {
+ id = lttng_tracker_id_create();
+ if (!id) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+
+ switch (cmd_ctx->lsm->u.id_tracker.id_type) {
case LTTNG_ID_ALL:
+ status = lttng_tracker_id_set_all(id);
break;
case LTTNG_ID_VALUE:
- id.value = cmd_ctx->lsm->u.id_tracker.u.value;
+ status = lttng_tracker_id_set_value(
+ id, cmd_ctx->lsm->u.id_tracker.u.value);
break;
case LTTNG_ID_STRING:
{
const size_t var_len = cmd_ctx->lsm->u.id_tracker.u.var_len;
+ char *string = NULL;
- id.string = zmalloc(var_len);
- if (!id.string) {
+ string = zmalloc(var_len);
+ if (!string) {
+ lttng_tracker_id_destroy(id);
ret = LTTNG_ERR_NOMEM;
goto error;
}
DBG("Receiving var len tracker id string from client");
- ret = lttcomm_recv_unix_sock(*sock, id.string, var_len);
+ ret = lttcomm_recv_unix_sock(*sock, string, var_len);
if (ret <= 0) {
DBG("Nothing received");
*sock_error = 1;
- free(id.string);
+ free(string);
+ lttng_tracker_id_destroy(id);
ret = LTTNG_ERR_INVALID;
goto error;
}
- if (strnlen(id.string, var_len) != var_len - 1) {
+ if (strnlen(string, var_len) != var_len - 1) {
DBG("String received as tracker ID is not NULL-terminated");
- free(id.string);
+ free(string);
+ lttng_tracker_id_destroy(id);
ret = LTTNG_ERR_INVALID;
goto error;
}
+
+ status = lttng_tracker_id_set_string(id, string);
+ free(string);
break;
}
default:
+ lttng_tracker_id_destroy(id);
ret = LTTNG_ERR_INVALID;
goto error;
}
+
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ERR("Invalid value for tracker id");
+ ret = LTTNG_ERR_INVALID;
+ lttng_tracker_id_destroy(id);
+ goto error;
+ }
+
ret = cmd_track_id(cmd_ctx->session,
cmd_ctx->lsm->u.id_tracker.tracker_type,
- cmd_ctx->lsm->domain.type, &id);
- free(id.string);
+ cmd_ctx->lsm->domain.type, id);
+ lttng_tracker_id_destroy(id);
break;
}
case LTTNG_UNTRACK_ID:
{
- struct lttng_tracker_id id;
+ struct lttng_tracker_id *id = NULL;
+ enum lttng_tracker_id_status status;
+
+ id = lttng_tracker_id_create();
- memset(&id, 0, sizeof(id));
- id.type = cmd_ctx->lsm->u.id_tracker.id_type;
- switch (id.type) {
+ switch (cmd_ctx->lsm->u.id_tracker.id_type) {
case LTTNG_ID_ALL:
+ status = lttng_tracker_id_set_all(id);
break;
case LTTNG_ID_VALUE:
- id.value = cmd_ctx->lsm->u.id_tracker.u.value;
+ status = lttng_tracker_id_set_value(
+ id, cmd_ctx->lsm->u.id_tracker.u.value);
break;
case LTTNG_ID_STRING:
{
const size_t var_len = cmd_ctx->lsm->u.id_tracker.u.var_len;
+ char *string = NULL;
- id.string = zmalloc(var_len);
- if (!id.string) {
+ string = zmalloc(var_len);
+ if (!string) {
ret = LTTNG_ERR_NOMEM;
+ lttng_tracker_id_destroy(id);
goto error;
}
DBG("Receiving var len tracker id string from client");
- ret = lttcomm_recv_unix_sock(*sock, id.string, var_len);
+ ret = lttcomm_recv_unix_sock(*sock, string, var_len);
if (ret <= 0) {
DBG("Nothing received");
*sock_error = 1;
- free(id.string);
+ lttng_tracker_id_destroy(id);
+ free(string);
ret = LTTNG_ERR_INVALID;
goto error;
}
- if (strnlen(id.string, var_len) != var_len - 1) {
+ if (strnlen(string, var_len) != var_len - 1) {
DBG("String received as tracker ID is not NULL-terminated");
- free(id.string);
+ lttng_tracker_id_destroy(id);
+ free(string);
ret = LTTNG_ERR_INVALID;
goto error;
}
+ status = lttng_tracker_id_set_string(id, string);
+ free(string);
break;
}
default:
+ lttng_tracker_id_destroy(id);
ret = LTTNG_ERR_INVALID;
goto error;
}
+
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ERR("Invalid tracker id");
+ lttng_tracker_id_destroy(id);
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+
ret = cmd_untrack_id(cmd_ctx->session,
cmd_ctx->lsm->u.id_tracker.tracker_type,
- cmd_ctx->lsm->domain.type, &id);
- free(id.string);
+ cmd_ctx->lsm->domain.type, id);
+ lttng_tracker_id_destroy(id);
break;
}
case LTTNG_ENABLE_EVENT:
case LTTNG_LIST_TRACKER_IDS:
{
struct lttcomm_tracker_command_header cmd_header;
- struct lttng_tracker_id *ids = NULL;
+ struct lttng_tracker_id **ids = NULL;
ssize_t nr_ids, i;
struct lttng_dynamic_buffer buf;
lttng_dynamic_buffer_init(&buf);
for (i = 0; i < nr_ids; i++) {
- struct lttng_tracker_id *id = &ids[i];
+ struct lttng_tracker_id *id = ids[i];
struct lttcomm_tracker_id_header id_hdr;
size_t var_data_len = 0;
+ enum lttng_tracker_id_status status;
+ const char *string;
+ int value;
memset(&id_hdr, 0, sizeof(id_hdr));
- id_hdr.type = id->type;
- switch (id->type) {
+ id_hdr.type = lttng_tracker_id_get_type(id);
+ switch (id_hdr.type) {
case LTTNG_ID_ALL:
break;
case LTTNG_ID_VALUE:
- id_hdr.u.value = id->value;
+ status = lttng_tracker_id_get_value(id, &value);
+ id_hdr.u.value = value;
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = LTTNG_ERR_INVALID;
+ goto error_list_tracker;
+ }
break;
case LTTNG_ID_STRING:
+ status = lttng_tracker_id_get_string(
+ id, &string);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = LTTNG_ERR_INVALID;
+ goto error_list_tracker;
+ }
+
id_hdr.u.var_data_len = var_data_len =
- strlen(id->string) + 1;
+ strlen(string) + 1;
break;
default:
ret = LTTNG_ERR_INVALID;
- goto error;
+ goto error_list_tracker;
}
ret = lttng_dynamic_buffer_append(
&buf, &id_hdr, sizeof(id_hdr));
if (ret) {
ret = LTTNG_ERR_NOMEM;
- goto error;
+ goto error_list_tracker;
}
ret = lttng_dynamic_buffer_append(
- &buf, id->string, var_data_len);
+ &buf, string, var_data_len);
if (ret) {
ret = LTTNG_ERR_NOMEM;
- goto error;
+ goto error_list_tracker;
}
- free(id->string);
}
cmd_header.nb_tracker_id = nr_ids;
ret = setup_lttng_msg(cmd_ctx, buf.data, buf.size, &cmd_header,
sizeof(cmd_header));
+ error_list_tracker:
+ lttng_tracker_ids_destroy(ids, nr_ids);
free(ids);
lttng_dynamic_buffer_reset(&buf);
if (ret < 0) {
ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type,
struct ltt_session *session,
enum lttng_domain_type domain,
- struct lttng_tracker_id **ids)
+ struct lttng_tracker_id ***ids)
{
int ret;
ssize_t nr_pids = 0;
ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type,
struct ltt_session *session,
enum lttng_domain_type domain,
- struct lttng_tracker_id **ids);
+ struct lttng_tracker_id ***ids);
int cmd_data_pending(struct ltt_session *session);
{
int ret, value;
struct lttng_tracker_list *tracker_list;
- struct lttng_tracker_id *saved_ids;
- ssize_t saved_ids_count, i;
+ struct lttng_tracker_id **saved_ids;
+ ssize_t saved_ids_count;
ret = lttng_tracker_id_lookup_string(tracker_type, id, &value);
if (ret != LTTNG_OK) {
ERR("Error on tracker add error handling.\n");
}
end:
- for (i = 0; i < saved_ids_count; i++) {
- free(saved_ids[i].string);
- }
+ lttng_tracker_ids_destroy(saved_ids, saved_ids_count);
free(saved_ids);
return ret;
}
{
int ret, value;
struct lttng_tracker_list *tracker_list;
- struct lttng_tracker_id *saved_ids;
- ssize_t saved_ids_count, i;
+ struct lttng_tracker_id **saved_ids;
+ ssize_t saved_ids_count;
ret = lttng_tracker_id_lookup_string(tracker_type, id, &value);
if (ret != LTTNG_OK) {
ERR("Error on tracker remove error handling.\n");
}
end:
- for (i = 0; i < saved_ids_count; i++) {
- free(saved_ids[i].string);
- }
+ lttng_tracker_ids_destroy(saved_ids, saved_ids_count);
free(saved_ids);
return ret;
}
*/
ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type,
struct ltt_kernel_session *session,
- struct lttng_tracker_id **_ids)
+ struct lttng_tracker_id ***_ids)
{
struct lttng_tracker_list *tracker_list;
int init_kernel_workarounds(void);
ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type,
struct ltt_kernel_session *session,
- struct lttng_tracker_id **_ids);
+ struct lttng_tracker_id ***_ids);
int kernel_supports_ring_buffer_snapshot_sample_positions(void);
int kernel_supports_ring_buffer_packet_sequence_number(void);
int init_kernel_tracer(void);
{
int ret = LTTNG_OK;
ssize_t nr_ids = 0, i;
- struct lttng_tracker_id *ids = NULL;
+ struct lttng_tracker_id **ids = NULL;
const char *element_id_tracker, *element_target_id, *element_id;
+ struct lttng_tracker_id *id;
+ enum lttng_tracker_id_status status;
+ int value;
+ const char *string;
switch (tracker_type) {
case LTTNG_TRACKER_PID:
goto end;
}
- if (nr_ids == 1 && ids[0].type == LTTNG_ID_ALL) {
+ if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) {
/* Tracking all, nothing to output. */
ret = LTTNG_OK;
goto end;
} else {
/* Tracking list. */
for (i = 0; i < nr_ids; i++) {
- switch (ids[i].type) {
+ id = ids[i];
+ switch (lttng_tracker_id_get_type(id)) {
case LTTNG_ID_VALUE:
ret = config_writer_open_element(
writer, element_target_id);
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+ status = lttng_tracker_id_get_value(id, &value);
ret = config_writer_write_element_unsigned_int(
- writer, element_id,
- ids[i].value);
+ writer, element_id, value);
break;
case LTTNG_ID_STRING:
ret = config_writer_open_element(
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+ status = lttng_tracker_id_get_string(
+ id, &string);
ret = config_writer_write_element_string(writer,
- config_element_name,
- ids[i].string);
+ config_element_name, string);
break;
default:
/* Unexpected. */
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
/* /$element_target_id */
ret = config_writer_close_element(writer);
ret = LTTNG_OK;
end:
+ lttng_tracker_ids_destroy(ids, nr_ids);
free(ids);
return ret;
}
struct ust_id_tracker *id_tracker;
struct lttng_tracker_list *tracker_list;
int value;
- struct lttng_tracker_id *saved_ids;
- ssize_t saved_ids_count, i;
+ struct lttng_tracker_id **saved_ids;
+ ssize_t saved_ids_count;
if (tracker_type == LTTNG_TRACKER_PID) {
DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
ERR("Error on tracker add error handling.\n");
}
end:
- for (i = 0; i < saved_ids_count; i++) {
- free(saved_ids[i].string);
- }
+ lttng_tracker_ids_destroy(saved_ids, saved_ids_count);
free(saved_ids);
return retval;
}
struct ust_id_tracker *id_tracker;
struct lttng_tracker_list *tracker_list;
int value;
- struct lttng_tracker_id *saved_ids;
- ssize_t saved_ids_count, i;
+ struct lttng_tracker_id **saved_ids;
+ ssize_t saved_ids_count;
if (tracker_type == LTTNG_TRACKER_PID) {
DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
ERR("Error on tracker remove error handling.\n");
}
end:
- for (i = 0; i < saved_ids_count; i++) {
- free(saved_ids[i].string);
- }
+ lttng_tracker_ids_destroy(saved_ids, saved_ids_count);
free(saved_ids);
return retval;
}
*/
ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type,
struct ltt_ust_session *session,
- struct lttng_tracker_id **_ids)
+ struct lttng_tracker_id ***_ids)
{
struct lttng_tracker_list *tracker_list;
ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type,
struct ltt_ust_session *session,
- struct lttng_tracker_id **_ids);
+ struct lttng_tracker_id ***_ids);
#else /* HAVE_LIBLTTNG_UST_CTL */
#include <common/hashtable/hashtable.h>
#include <common/hashtable/utils.h>
#include <lttng/lttng-error.h>
+#include <lttng/tracker-internal.h>
#define FALLBACK_USER_BUFLEN 16384
#define FALLBACK_GROUP_BUFLEN 16384
tracker_node = caa_container_of(
node, struct lttng_tracker_list_node, ht_node);
- if (tracker_node->id.type != tracker_key->type) {
- return 0;
- }
- switch (tracker_node->id.type) {
- case LTTNG_ID_ALL:
- return 1;
- case LTTNG_ID_VALUE:
- if (tracker_node->id.value != tracker_key->value) {
- return 0;
- }
- break;
- case LTTNG_ID_STRING:
- if (strcmp(tracker_node->id.string, tracker_key->string) != 0) {
- return 0;
- }
- break;
- default:
- return 0;
- }
- return 1;
+
+ return lttng_tracker_id_is_equal(tracker_node->id, tracker_key);
}
static unsigned long hash_tracker_key(
const struct lttng_tracker_id *tracker_key)
{
unsigned long key_hash = 0;
+ int value;
+ const char *string;
+ enum lttng_tracker_id_type type;
+
+ /* We do not care for invalid state during hash computation */
+ type = lttng_tracker_id_get_type(tracker_key);
+ (void) lttng_tracker_id_get_value(tracker_key, &value);
+ (void) lttng_tracker_id_get_string(tracker_key, &string);
- switch (tracker_key->type) {
+ switch (type) {
case LTTNG_ID_ALL:
break;
case LTTNG_ID_VALUE:
key_hash ^= hash_key_ulong(
- (void *) (unsigned long) tracker_key->value,
- lttng_ht_seed);
+ (void *) (unsigned long) value, lttng_ht_seed);
break;
case LTTNG_ID_STRING:
- key_hash ^= hash_key_str(tracker_key->string, lttng_ht_seed);
+ key_hash ^= hash_key_str(string, lttng_ht_seed);
break;
case LTTNG_ID_UNKNOWN:
break;
}
- key_hash ^= hash_key_ulong((void *) (unsigned long) tracker_key->type,
- lttng_ht_seed);
+ key_hash ^= hash_key_ulong(
+ (void *) (unsigned long) type, lttng_ht_seed);
return key_hash;
}
-static struct lttng_tracker_id *lttng_tracker_list_lookup(
+static struct lttng_tracker_id **lttng_tracker_list_lookup(
const struct lttng_tracker_list *tracker_list,
const struct lttng_tracker_id *key)
{
struct lttng_tracker_list_node *n = caa_container_of(
head, struct lttng_tracker_list_node, rcu_head);
- free(n->id.string);
+ lttng_tracker_id_destroy(n->id);
free(n);
}
int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list,
const struct lttng_tracker_id *_id)
{
- struct lttng_tracker_id *id;
- struct lttng_tracker_list_node *n;
+ struct lttng_tracker_id **id;
+ struct lttng_tracker_list_node *n = NULL;
int ret;
- if (_id->type == LTTNG_ID_ALL) {
+ if (lttng_tracker_id_get_type(_id) == LTTNG_ID_ALL) {
/* Track all, so remove each individual item. */
lttng_tracker_list_reset(tracker_list);
- return LTTNG_OK;
+ ret = LTTNG_OK;
+ goto error;
}
rcu_read_lock();
id = lttng_tracker_list_lookup(tracker_list, _id);
*/
rcu_read_unlock();
if (id) {
- return LTTNG_ERR_ID_TRACKED;
+ ret = LTTNG_ERR_ID_TRACKED;
+ goto error;
}
n = zmalloc(sizeof(*n));
if (!n) {
- return LTTNG_ERR_NOMEM;
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
}
- n->id = *_id;
- if (_id->type == LTTNG_ID_STRING) {
- n->id.string = strdup(_id->string);
- if (!n->id.string) {
- ret = LTTNG_ERR_NOMEM;
- goto error;
- }
- } else {
- n->id.string = NULL;
+
+ n->id = lttng_tracker_id_copy(_id);
+ if (!n->id) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
}
cds_list_add_tail(&n->list_node, &tracker_list->list_head);
tracker_list->state = LTTNG_TRACK_LIST;
rcu_read_lock();
- cds_lfht_add(tracker_list->ht, hash_tracker_key(&n->id), &n->ht_node);
+ cds_lfht_add(tracker_list->ht, hash_tracker_key(n->id), &n->ht_node);
rcu_read_unlock();
return LTTNG_OK;
const struct lttng_tracker_id *_id)
{
enum lttng_error_code ret = LTTNG_OK;
- struct lttng_tracker_id *id;
+ struct lttng_tracker_id **id;
struct lttng_tracker_list_node *n;
- if (_id->type == LTTNG_ID_ALL) {
+ if (lttng_tracker_id_get_type(_id) == LTTNG_ID_ALL) {
/* Untrack all. */
lttng_tracker_list_reset(tracker_list);
/* Set state to "track none". */
const struct lttng_tracker_id *id,
int *result)
{
- switch (id->type) {
+ enum lttng_tracker_id_status status;
+ int value;
+ const char *string;
+
+ switch (lttng_tracker_id_get_type(id)) {
case LTTNG_ID_ALL:
*result = -1;
return LTTNG_OK;
case LTTNG_ID_VALUE:
+ status = lttng_tracker_id_get_value(id, &value);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ return LTTNG_ERR_INVALID;
+ }
*result = id->value;
return LTTNG_OK;
case LTTNG_ID_STRING:
+ status = lttng_tracker_id_get_string(id, &string);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ return LTTNG_ERR_INVALID;
+ }
switch (tracker_type) {
case LTTNG_TRACKER_PID:
case LTTNG_TRACKER_VPID:
case LTTNG_TRACKER_UID:
case LTTNG_TRACKER_VUID:
DBG("Lookup of tracker UID/VUID by name.");
- return lttng_lookup_user(id->string, result);
+ return lttng_lookup_user(string, result);
case LTTNG_TRACKER_GID:
case LTTNG_TRACKER_VGID:
DBG("Lookup of tracker GID/VGID by name.");
- return lttng_lookup_group(id->string, result);
+ return lttng_lookup_group(string, result);
default:
return LTTNG_ERR_INVALID;
}
/*
* Protected by session mutex held by caller.
- * On success, _ids and the strings it contains must be freed by caller.
+ * On success, _ids and the ids it contains must be freed by the caller.
*/
ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list,
- struct lttng_tracker_id **_ids)
+ struct lttng_tracker_id ***_ids)
{
struct lttng_tracker_list_node *n;
ssize_t count = 0, i = 0, retval = 0;
- struct lttng_tracker_id *ids;
+ struct lttng_tracker_id **ids;
+ enum lttng_tracker_id_status status;
switch (tracker_list->state) {
case LTTNG_TRACK_LIST:
}
cds_list_for_each_entry (
n, &tracker_list->list_head, list_node) {
- ids[i].type = n->id.type;
- ids[i].value = n->id.value;
- if (ids[i].type == LTTNG_ID_STRING) {
- ids[i].string = strdup(n->id.string);
- if (!ids[i].string) {
- retval = -LTTNG_ERR_NOMEM;
- goto error;
- }
+ ids[i] = lttng_tracker_id_copy(n->id);
+ if (!ids[i]) {
+ retval = -LTTNG_ERR_NOMEM;
+ goto error;
}
i++;
}
retval = -LTTNG_ERR_NOMEM;
goto end;
}
- ids->type = LTTNG_TRACK_ALL;
+ ids[0] = lttng_tracker_id_create();
+ status = lttng_tracker_id_set_all(ids[0]);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ERR("Invalid tracker id for track all");
+ retval = -LTTNG_ERR_INVALID;
+ goto error;
+ }
*_ids = ids;
retval = 1;
break;
return retval;
error:
- for (i = 0; i < count; i++) {
- free(ids[i].string);
- }
+ lttng_tracker_ids_destroy(ids, count);
free(ids);
return retval;
}
int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list,
- struct lttng_tracker_id *_ids,
+ struct lttng_tracker_id **_ids,
size_t count)
{
size_t i;
lttng_tracker_list_reset(tracker_list);
- if (count == 1 && _ids[0].type == LTTNG_ID_ALL) {
+ if (count == 1 && lttng_tracker_id_get_type(_ids[0])) {
/* Track all. */
return LTTNG_OK;
}
return LTTNG_OK;
}
for (i = 0; i < count; i++) {
- struct lttng_tracker_id *id = &_ids[i];
+ struct lttng_tracker_id *id = _ids[i];
int ret;
ret = lttng_tracker_list_add(tracker_list, id);
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include <lttng/session.h>
+#include <lttng/tracker.h>
#include <urcu.h>
#include <urcu/list.h>
#include <urcu/rculfhash.h>
/* Tracker ID */
struct lttng_tracker_list_node {
- struct lttng_tracker_id id;
+ struct lttng_tracker_id *id;
struct cds_list_head list_node;
struct cds_lfht_node ht_node;
const struct lttng_tracker_id *id,
int *result);
ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list,
- struct lttng_tracker_id **_ids);
+ struct lttng_tracker_id ***_ids);
int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list,
- struct lttng_tracker_id *_ids,
+ struct lttng_tracker_id **_ids,
size_t count);
#endif /* _LTT_TRACKER_H */
#include <common/mi-lttng.h>
#include <common/time.h>
#include <lttng/constant.h>
+#include <lttng/tracker.h>
#include "../command.h"
{
int ret = 0;
int enabled = 1;
- struct lttng_tracker_id *ids = NULL;
+ struct lttng_tracker_id **ids = NULL;
size_t nr_ids, i;
ret = lttng_list_tracker_ids(handle, tracker_type, &ids, &nr_ids);
if (ret) {
return ret;
}
- if (nr_ids == 1 && ids[0].type == LTTNG_ID_ALL) {
+ if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) {
enabled = 0;
}
if (enabled) {
}
for (i = 0; i < nr_ids; i++) {
- struct lttng_tracker_id *id = &ids[i];
+ struct lttng_tracker_id *id = ids[i];
+ enum lttng_tracker_id_status status;
+ int value;
+ const char *value_string;
+
+ switch (lttng_tracker_id_get_type(id)) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ status = lttng_tracker_id_get_value(id, &value);
+ break;
+ case LTTNG_ID_STRING:
+ status = lttng_tracker_id_get_string(
+ id, &value_string);
+ break;
+ case LTTNG_ID_UNKNOWN:
+ ret = CMD_ERROR;
+ goto end;
+ }
+
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ERR("Invalid state for tracker id");
+ ret = CMD_ERROR;
+ goto end;
+ }
if (i) {
_MSG(",");
}
- switch (id->type) {
+ switch (lttng_tracker_id_get_type(id)) {
case LTTNG_ID_ALL:
_MSG(" *");
break;
case LTTNG_ID_VALUE:
- _MSG(" %d", ids[i].value);
+ _MSG(" %d", value);
break;
case LTTNG_ID_STRING:
- _MSG(" %s", ids[i].string);
+ _MSG(" %s", value_string);
break;
case LTTNG_ID_UNKNOWN:
- return CMD_ERROR;
+ ERR("Invalid state for tracker id");
+ ret = CMD_ERROR;
+ goto end;
}
/* Mi */
}
}
end:
- for (i = 0; i < nr_ids; i++) {
- free(ids[i].string);
- }
- free(ids);
+ lttng_tracker_ids_destroy(ids, nr_ids);
return ret;
}
struct id_list {
size_t nr;
- struct lttng_tracker_id *array;
+ struct lttng_tracker_id **array;
};
static char *opt_session_name;
static struct id_list *alloc_id_list(size_t nr_items)
{
struct id_list *id_list;
- struct lttng_tracker_id *items;
+ struct lttng_tracker_id **items;
id_list = zmalloc(sizeof(*id_list));
if (!id_list) {
}
nr_items = list->nr;
for (i = 0; i < nr_items; i++) {
- struct lttng_tracker_id *item = &list->array[i];
-
- free(item->string);
+ struct lttng_tracker_id *item = list->array[i];
+ lttng_tracker_id_destroy(item);
}
free(list);
}
-static int parse_id_string(
- const char *_id_string, int all, struct id_list **_id_list)
+static int parse_id_string(const char *_id_string,
+ int all,
+ struct id_list **_id_list,
+ enum lttng_tracker_type tracker_type)
{
const char *one_id_str;
char *iter;
goto error;
}
if (all) {
- /* Empty ID string means all IDs */
+ enum lttng_tracker_id_status status;
+ /* Empty `ID string means all IDs */
id_list = alloc_id_list(1);
if (!id_list) {
ERR("Out of memory");
retval = CMD_ERROR;
goto error;
}
- id_list->array[0].type = LTTNG_ID_ALL;
+
+ id_list->array[0] = lttng_tracker_id_create();
+ if (id_list->array[0] == NULL) {
+ ERR("Out of memory");
+ retval = CMD_ERROR;
+ goto error;
+ }
+
+ status = lttng_tracker_id_set_all(id_list->array[0]);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ERR("Invalid value for tracker id");
+ retval = CMD_ERROR;
+ goto error;
+ }
goto assign;
}
count = 0;
one_id_str = strtok_r(id_string, ",", &iter);
while (one_id_str != NULL) {
+ enum lttng_tracker_id_status status;
struct lttng_tracker_id *item;
+ item = lttng_tracker_id_create();
+ if (item == NULL) {
+ ERR("Out of memory");
+ retval = CMD_ERROR;
+ goto error;
+ }
- item = &id_list->array[count++];
+ id_list->array[count++] = item;
if (isdigit(one_id_str[0])) {
unsigned long v;
v = strtoul(one_id_str, NULL, 10);
- item->type = LTTNG_ID_VALUE;
- item->value = (int) v;
+ status = lttng_tracker_id_set_value(item, (int) v);
+ if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
+ ERR("Invalid value");
+ retval = CMD_ERROR;
+ goto error;
+ }
} else {
- item->type = LTTNG_ID_STRING;
- item->string = strdup(one_id_str);
- if (!item->string) {
- PERROR("Failed to allocate ID string");
+ status = lttng_tracker_id_set_string(item, one_id_str);
+ if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
+ ERR("Failed to set ID string");
retval = CMD_ERROR;
goto error;
}
}
assign:
+ /* SUCCESS */
*_id_list = id_list;
- goto end; /* SUCCESS */
+ goto end;
- /* ERROR */
error:
+ /* ERROR */
free_id_list(id_list);
end:
free(id_string);
retval = CMD_ERROR;
goto end;
}
- ret = parse_id_string(id_string, all, &id_list);
+ ret = parse_id_string(id_string, all, &id_list, tracker_type);
if (ret != CMD_SUCCESS) {
ERR("Error parsing %s string", tracker_str);
retval = CMD_ERROR;
}
for (i = 0; i < id_list->nr; i++) {
- struct lttng_tracker_id *item = &id_list->array[i];
+ struct lttng_tracker_id *item = id_list->array[i];
+ enum lttng_tracker_id_type type =
+ lttng_tracker_id_get_type(item);
+ enum lttng_tracker_id_status status =
+ LTTNG_TRACKER_ID_STATUS_OK;
+ int value;
+ const char *value_string;
+
+ switch (type) {
+ case LTTNG_ID_ALL:
+ /* Nothing to check */
+ break;
+ case LTTNG_ID_VALUE:
+ status = lttng_tracker_id_get_value(item, &value);
+ break;
+ case LTTNG_ID_STRING:
+ status = lttng_tracker_id_get_string(
+ item, &value_string);
+ break;
+ default:
+ retval = CMD_ERROR;
+ goto end;
+ }
- switch (item->type) {
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ERR("Tracker id object is in an invalid state");
+ retval = CMD_ERROR;
+ goto end;
+ }
+
+ switch (type) {
case LTTNG_ID_ALL:
DBG("%s all IDs", cmd_str);
break;
case LTTNG_ID_VALUE:
- DBG("%s ID %d", cmd_str, item->value);
+ DBG("%s ID %d", cmd_str, value);
break;
case LTTNG_ID_STRING:
- DBG("%s ID '%s'", cmd_str, item->string);
+ DBG("%s ID '%s'", cmd_str, value_string);
break;
default:
retval = CMD_ERROR;
goto end;
}
+
ret = cmd_func(handle, tracker_type, item);
if (ret) {
char *msg = NULL;
break;
}
if (msg) {
- switch (item->type) {
+ switch (type) {
case LTTNG_ID_ALL:
WARN("All %ss %s in session %s",
tracker_str, msg,
break;
case LTTNG_ID_VALUE:
WARN("%s %i %s in session %s",
- tracker_str,
- item->value, msg,
+ tracker_str, value, msg,
session_name);
break;
case LTTNG_ID_STRING:
WARN("%s '%s' %s in session %s",
tracker_str,
- item->string, msg,
+ value_string, msg,
session_name);
break;
default:
}
}
} else {
- switch (item->type) {
+ switch (type) {
case LTTNG_ID_ALL:
MSG("All %ss %sed in session %s", tracker_str,
cmd_str, session_name);
break;
case LTTNG_ID_VALUE:
MSG("%s %i %sed in session %s", tracker_str,
- item->value, cmd_str,
- session_name);
+ value, cmd_str, session_name);
break;
case LTTNG_ID_STRING:
MSG("%s '%s' %sed in session %s", tracker_str,
- item->string, cmd_str,
+ value_string, cmd_str,
session_name);
break;
default:
userspace-probe.c \
utils.c utils.h \
uuid.c uuid.h \
+ tracker.c \
waiter.c waiter.h
if HAVE_ELF_H
const char *element_id;
const char *element_id_alias;
const char *element_name;
+ enum lttng_tracker_id_status status;
assert(handle);
assert(id_tracker_node);
/* Go through all id target node */
child = xmlChildElementCount(targets_node);
if (child == 0) {
- struct lttng_tracker_id tracker_id;
+ struct lttng_tracker_id *tracker_id = NULL;
+ tracker_id = lttng_tracker_id_create();
+ if (tracker_id == NULL) {
+ ret = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+ status = lttng_tracker_id_set_all(tracker_id);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = LTTNG_ERR_INVALID;
+ goto end;
+ }
- tracker_id.type = LTTNG_ID_ALL;
/* The session is explicitly set to target nothing. */
- ret = lttng_untrack_id(handle, tracker_type, &tracker_id);
+ ret = lttng_untrack_id(handle, tracker_type, tracker_id);
+ lttng_tracker_id_destroy(tracker_id);
if (ret) {
goto end;
}
element_id_alias))) {
int64_t id;
xmlChar *content = NULL;
- struct lttng_tracker_id tracker_id;
+ struct lttng_tracker_id *tracker_id = NULL;
content = xmlNodeGetContent(node);
if (!content) {
goto end;
}
- tracker_id.type = LTTNG_ID_VALUE;
- tracker_id.value = (int) id;
+ tracker_id = lttng_tracker_id_create();
+ if (tracker_id == NULL) {
+ ret = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ status = lttng_tracker_id_set_value(
+ tracker_id, id);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ lttng_tracker_id_destroy(tracker_id);
+ ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
ret = lttng_track_id(handle, tracker_type,
- &tracker_id);
+ tracker_id);
+ lttng_tracker_id_destroy(tracker_id);
if (ret) {
goto end;
}
if (element_name && !strcmp((const char *) node->name,
element_name)) {
xmlChar *content = NULL;
- struct lttng_tracker_id tracker_id;
+ struct lttng_tracker_id *tracker_id = NULL;
content = xmlNodeGetContent(node);
if (!content) {
ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
goto end;
}
- tracker_id.type = LTTNG_ID_STRING;
- tracker_id.string = (char *) content;
+
+ tracker_id = lttng_tracker_id_create();
+ if (tracker_id == NULL) {
+ ret = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ status = lttng_tracker_id_set_string(tracker_id,
+ (const char *) content);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ lttng_tracker_id_destroy(tracker_id);
+ ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+
ret = lttng_track_id(handle, tracker_type,
- &tracker_id);
+ tracker_id);
+ lttng_tracker_id_destroy(tracker_id);
free(content);
if (ret) {
goto end;
#include <common/config/session-config.h>
#include <common/defaults.h>
#include <lttng/snapshot-internal.h>
+#include <lttng/tracker-internal.h>
#include <lttng/channel.h>
#include "mi-lttng.h"
{
int ret;
const char *element_id_tracker, *element_target_id;
+ enum lttng_tracker_id_status status;
+ int value;
+ const char *string;
ret = get_tracker_elements(
tracker_type, &element_id_tracker, &element_target_id);
return ret;
}
- switch (id->type) {
+ switch (lttng_tracker_id_get_type(id)) {
case LTTNG_ID_ALL:
ret = mi_lttng_writer_open_element(writer, element_target_id);
if (ret) {
if (ret) {
goto end;
}
+
+ status = lttng_tracker_id_get_value(id, &value);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = -1;
+ goto end;
+ }
+
ret = mi_lttng_writer_write_element_signed_int(
- writer, config_element_id, id->value);
+ writer, config_element_id, value);
if (ret) {
goto end;
}
if (ret) {
goto end;
}
+
+ status = lttng_tracker_id_get_string(id, &string);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = -1;
+ goto end;
+ }
+
ret = mi_lttng_writer_write_element_string(
- writer, config_element_name, id->string);
+ writer, config_element_name, string);
if (ret) {
goto end;
}
--- /dev/null
+/*
+ * Copyright (C) 2019 - Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License, version 2.1 only,
+ * as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <assert.h>
+#include <common/defaults.h>
+#include <common/error.h>
+#include <common/macros.h>
+#include <common/sessiond-comm/sessiond-comm.h>
+#include <common/uri.h>
+#include <lttng/tracker-internal.h>
+#include <stdio.h>
+#include <time.h>
+
+struct lttng_tracker_id *lttng_tracker_id_create(void)
+{
+ struct lttng_tracker_id *id;
+
+ id = zmalloc(sizeof(*id));
+ if (!id) {
+ goto error;
+ }
+
+ id->type = LTTNG_ID_UNKNOWN;
+ id->string = NULL;
+ id->value = -1;
+ return id;
+error:
+ lttng_tracker_id_destroy(id);
+ return NULL;
+}
+
+enum lttng_tracker_id_status lttng_tracker_id_set_value(
+ struct lttng_tracker_id *id, int value)
+{
+ assert(id);
+
+ if (value < 0) {
+ return LTTNG_TRACKER_ID_STATUS_INVALID;
+ }
+
+ id->type = LTTNG_ID_VALUE;
+ id->value = value;
+ return LTTNG_TRACKER_ID_STATUS_OK;
+}
+
+enum lttng_tracker_id_status lttng_tracker_id_set_string(
+ struct lttng_tracker_id *id, const char *value)
+{
+ assert(id);
+ assert(value);
+
+ id->type = LTTNG_ID_STRING;
+ id->string = strdup(value);
+ if (id->string == NULL) {
+ /* No memory left */
+ goto error;
+ }
+
+ return LTTNG_TRACKER_ID_STATUS_OK;
+error:
+ return LTTNG_TRACKER_ID_STATUS_INVALID;
+}
+
+enum lttng_tracker_id_status lttng_tracker_id_set_all(
+ struct lttng_tracker_id *id)
+{
+ assert(id);
+
+ id->type = LTTNG_ID_ALL;
+
+ return LTTNG_TRACKER_ID_STATUS_OK;
+}
+
+void lttng_tracker_id_destroy(struct lttng_tracker_id *id)
+{
+ if (id == NULL) {
+ return;
+ }
+
+ if (id->string != NULL) {
+ free(id->string);
+ }
+
+ free(id);
+}
+
+void lttng_tracker_ids_destroy(struct lttng_tracker_id **ids, size_t nr_ids)
+{
+ if (ids == NULL) {
+ return;
+ }
+
+ for (int i = 0; i < nr_ids; i++) {
+ lttng_tracker_id_destroy(ids[i]);
+ }
+}
+
+enum lttng_tracker_id_type lttng_tracker_id_get_type(
+ const struct lttng_tracker_id *id)
+{
+ assert(id);
+ return id->type;
+}
+
+enum lttng_tracker_id_status lttng_tracker_id_get_value(
+ const struct lttng_tracker_id *id, int *value)
+{
+ assert(id);
+ if (id->type == LTTNG_ID_UNKNOWN) {
+ return LTTNG_TRACKER_ID_STATUS_UNSET;
+ }
+
+ if (id->type != LTTNG_ID_VALUE) {
+ return LTTNG_TRACKER_ID_STATUS_INVALID;
+ }
+
+ *value = id->value;
+ return LTTNG_TRACKER_ID_STATUS_OK;
+}
+
+bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left,
+ const struct lttng_tracker_id *right)
+{
+ if (left->type != right->type) {
+ return 0;
+ }
+
+ switch (left->type) {
+ case LTTNG_ID_ALL:
+ return 1;
+ case LTTNG_ID_VALUE:
+ if (left->value != right->value) {
+ return 0;
+ }
+ break;
+ case LTTNG_ID_STRING:
+ if (strcmp(left->string, right->string) != 0) {
+ return 0;
+ }
+ break;
+ default:
+ /*
+ * Normally this should return true, but comparing unset tracker
+ * id is "invalid".
+ */
+ return 0;
+ }
+ return 1;
+}
+
+struct lttng_tracker_id *lttng_tracker_id_copy(
+ const struct lttng_tracker_id *orig)
+{
+ struct lttng_tracker_id *copy = NULL;
+ enum lttng_tracker_id_status status;
+
+ copy = lttng_tracker_id_create();
+ if (copy == NULL) {
+ goto error;
+ }
+
+ switch (orig->type) {
+ case LTTNG_ID_ALL:
+ status = lttng_tracker_id_set_all(copy);
+ break;
+ case LTTNG_ID_VALUE:
+ status = lttng_tracker_id_set_value(copy, orig->value);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ goto error;
+ }
+ break;
+ case LTTNG_ID_STRING:
+ status = lttng_tracker_id_set_string(copy, orig->string);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ goto error;
+ }
+ break;
+ default:
+ status = LTTNG_TRACKER_ID_STATUS_OK;
+ break;
+ }
+
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ goto error;
+ }
+
+ return copy;
+error:
+ lttng_tracker_id_destroy(copy);
+ return NULL;
+}
+
+enum lttng_tracker_id_status lttng_tracker_id_get_string(
+ const struct lttng_tracker_id *id, const char **value)
+{
+ assert(id);
+ if (id->type == LTTNG_ID_UNKNOWN) {
+ *value = NULL;
+ return LTTNG_TRACKER_ID_STATUS_UNSET;
+ }
+
+ if (id->type != LTTNG_ID_STRING) {
+ *value = NULL;
+ return LTTNG_TRACKER_ID_STATUS_INVALID;
+ }
+
+ *value = id->string;
+ return LTTNG_TRACKER_ID_STATUS_OK;
+}
#include <lttng/session-internal.h>
#include <lttng/session-descriptor-internal.h>
#include <lttng/destruction-handle.h>
+#include <lttng/tracker-internal.h>
#include "filter/filter-ast.h"
#include "filter/filter-parser.h"
return lttng_ctl_ask_sessiond(&lsm, NULL);
}
-static int lttng_track_untrack_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id,
- enum lttcomm_sessiond_command cmd)
-{
- struct lttcomm_session_msg lsm;
- char *var_data = NULL;
- size_t var_data_len = 0;
-
- /* NULL arguments are forbidden. No default values. */
- if (handle == NULL) {
- return -LTTNG_ERR_INVALID;
- }
-
- memset(&lsm, 0, sizeof(lsm));
-
- lsm.cmd_type = cmd;
- lsm.u.id_tracker.tracker_type = tracker_type;
- lsm.u.id_tracker.id_type = id->type;
- switch (id->type) {
- case LTTNG_ID_ALL:
- break;
- case LTTNG_ID_VALUE:
- lsm.u.id_tracker.u.value = id->value;
- break;
- case LTTNG_ID_STRING:
- var_data = id->string;
- var_data_len = strlen(var_data) + 1; /* Includes \0. */
- lsm.u.id_tracker.u.var_len = var_data_len;
- break;
- default:
- return -LTTNG_ERR_INVALID;
- }
-
- COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
-
- lttng_ctl_copy_string(lsm.session.name, handle->session_name,
- sizeof(lsm.session.name));
-
- return lttng_ctl_ask_sessiond_varlen_no_cmd_header(
- &lsm, var_data, var_data_len, NULL);
-}
-
-/*
- * Add ID to session tracker.
- * Return 0 on success else a negative LTTng error code.
- */
-int lttng_track_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id)
-{
- return lttng_track_untrack_id(handle, tracker_type, id, LTTNG_TRACK_ID);
-}
-
-/*
- * Remove ID from session tracker.
- * Return 0 on success else a negative LTTng error code.
- */
-int lttng_untrack_id(struct lttng_handle *handle,
- enum lttng_tracker_type tracker_type,
- const struct lttng_tracker_id *id)
-{
- return lttng_track_untrack_id(
- handle, tracker_type, id, LTTNG_UNTRACK_ID);
-}
-
-/*
- * Add PID to session tracker.
- * Return 0 on success else a negative LTTng error code.
- */
-int lttng_track_pid(struct lttng_handle *handle, int pid)
-{
- struct lttng_tracker_id id;
-
- id.type = LTTNG_TRACKER_PID;
- id.value = pid;
- return lttng_track_id(handle, LTTNG_TRACKER_PID, &id);
-}
-
-/*
- * Remove PID from session tracker.
- * Return 0 on success else a negative LTTng error code.
- */
-int lttng_untrack_pid(struct lttng_handle *handle, int pid)
-{
- struct lttng_tracker_id id;
-
- id.type = LTTNG_TRACKER_PID;
- id.value = pid;
- return lttng_untrack_id(handle, LTTNG_TRACKER_PID, &id);
-}
-
/*
* Lists all available tracepoints of domain.
* Sets the contents of the events array.
*
* tracker_type is the type of tracker.
* ids is set to an allocated array of IDs currently tracked. On
- * success, ids and all the strings it contains must be freed by the caller.
+ * success, ids and contained ids must be freed/destroy by the caller.
* nr_ids is set to the number of entries contained by the ids array.
*
* Returns 0 on success, else a negative LTTng error code.
*/
int lttng_list_tracker_ids(struct lttng_handle *handle,
enum lttng_tracker_type tracker_type,
- struct lttng_tracker_id **_ids,
+ struct lttng_tracker_id ***_ids,
size_t *_nr_ids)
{
int ret, i;
char *cmd_payload = NULL, *p;
size_t cmd_header_len;
size_t nr_ids = 0;
- struct lttng_tracker_id *ids = NULL;
+ struct lttng_tracker_id **ids = NULL;
if (handle == NULL) {
return -LTTNG_ERR_INVALID;
for (i = 0; i < nr_ids; i++) {
struct lttcomm_tracker_id_header *tracker_id;
struct lttng_tracker_id *id;
+ enum lttng_tracker_id_status status;
tracker_id = (struct lttcomm_tracker_id_header *) p;
p += sizeof(struct lttcomm_tracker_id_header);
- id = &ids[i];
+ id = lttng_tracker_id_create();
+ if (!id) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto error;
+ }
- id->type = tracker_id->type;
switch (tracker_id->type) {
case LTTNG_ID_ALL:
+ status = lttng_tracker_id_set_all(id);
break;
case LTTNG_ID_VALUE:
id->value = tracker_id->u.value;
+ status = lttng_tracker_id_set_value(
+ id, tracker_id->u.value);
break;
case LTTNG_ID_STRING:
- id->string = strdup(p);
- if (!id->string) {
- ret = -LTTNG_ERR_NOMEM;
- goto error;
- }
+ status = lttng_tracker_id_set_string(id, p);
p += tracker_id->u.var_data_len;
break;
default:
goto error;
}
+
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = -LTTNG_ERR_INVALID;
+ goto error;
+ }
+
+ /* Assign the new object to the list */
+ ids[i] = id;
}
free(cmd_payload);
*_ids = ids;
return 0;
error:
- if (ids) {
- for (i = 0; i < nr_ids; i++) {
- free(ids[i].string);
- }
- free(ids);
- }
+ lttng_tracker_ids_destroy(ids, nr_ids);
+ free(ids);
free(cmd_payload);
free(cmd_header);
return ret;
int lttng_list_tracker_pids(struct lttng_handle *handle,
int *_enabled, int32_t **_pids, size_t *_nr_pids)
{
- struct lttng_tracker_id *ids = NULL;
+ struct lttng_tracker_id **ids = NULL;
size_t nr_ids = 0;
int *pids = NULL;
int ret = 0, i;
+ enum lttng_tracker_id_status status;
ret = lttng_list_tracker_ids(handle, LTTNG_TRACKER_PID, &ids, &nr_ids);
if (ret < 0)
return ret;
- if (nr_ids == 1 && ids[0].type == LTTNG_ID_ALL) {
+ if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) {
*_enabled = 0;
goto end;
}
goto end;
}
for (i = 0; i < nr_ids; i++) {
- struct lttng_tracker_id *id = &ids[i];
+ struct lttng_tracker_id *id = ids[i];
- if (id->type != LTTNG_ID_VALUE) {
+ status = lttng_tracker_id_get_value(id, &pids[i]);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
ret = -LTTNG_ERR_UNK;
goto end;
}
- pids[i] = id->value;
}
*_pids = pids;
*_nr_pids = nr_ids;
end:
- for (i = 0; i < nr_ids; i++) {
- free(ids[i].string);
- }
+ lttng_tracker_ids_destroy(ids, nr_ids);
free(ids);
if (ret < 0) {
free(pids);
return ret;
}
+static int lttng_track_untrack_id(struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type,
+ const struct lttng_tracker_id *id,
+ enum lttcomm_sessiond_command cmd)
+{
+ int ret;
+ struct lttcomm_session_msg lsm;
+ const char *var_data;
+ size_t var_data_len = 0;
+ int value;
+ enum lttng_tracker_id_status status;
+
+ /* NULL arguments are forbidden. No default values. */
+ if (handle == NULL) {
+ goto error;
+ }
+
+ memset(&lsm, 0, sizeof(lsm));
+
+ lsm.cmd_type = cmd;
+ lsm.u.id_tracker.tracker_type = tracker_type;
+ lsm.u.id_tracker.id_type = lttng_tracker_id_get_type(id);
+ switch (lsm.u.id_tracker.id_type) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ status = lttng_tracker_id_get_value(id, &value);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ goto error;
+ }
+ lsm.u.id_tracker.u.value = value;
+ break;
+ case LTTNG_ID_STRING:
+ status = lttng_tracker_id_get_string(id, &var_data);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ goto error;
+ }
+ var_data_len = strlen(var_data) + 1; /* Includes \0. */
+ lsm.u.id_tracker.u.var_len = var_data_len;
+ break;
+ default:
+ goto error;
+ }
+
+ COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
+
+ lttng_ctl_copy_string(lsm.session.name, handle->session_name,
+ sizeof(lsm.session.name));
+
+ ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(
+ &lsm, (char *) var_data, var_data_len, NULL);
+ return ret;
+error:
+ return -LTTNG_ERR_INVALID;
+}
+
+/*
+ * Add ID to session tracker.
+ * Return 0 on success else a negative LTTng error code.
+ */
+int lttng_track_id(struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type,
+ const struct lttng_tracker_id *id)
+{
+ return lttng_track_untrack_id(handle, tracker_type, id, LTTNG_TRACK_ID);
+}
+
+/*
+ * Remove ID from session tracker.
+ * Return 0 on success else a negative LTTng error code.
+ */
+int lttng_untrack_id(struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type,
+ const struct lttng_tracker_id *id)
+{
+ return lttng_track_untrack_id(
+ handle, tracker_type, id, LTTNG_UNTRACK_ID);
+}
+
+/*
+ * Add PID to session tracker.
+ * Return 0 on success else a negative LTTng error code.
+ */
+int lttng_track_pid(struct lttng_handle *handle, int pid)
+{
+ int ret;
+ struct lttng_tracker_id *id = NULL;
+ enum lttng_tracker_id_status status;
+
+ id = lttng_tracker_id_create();
+ status = lttng_tracker_id_set_value(id, pid);
+ if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
+ ret = -LTTNG_ERR_INVALID;
+ goto error;
+ }
+
+ ret = lttng_track_id(handle, LTTNG_TRACKER_PID, id);
+error:
+ lttng_tracker_id_destroy(id);
+ return ret;
+}
+
+/*
+ * Remove PID from session tracker.
+ * Return 0 on success else a negative LTTng error code.
+ */
+int lttng_untrack_pid(struct lttng_handle *handle, int pid)
+{
+ int ret;
+ struct lttng_tracker_id *id = NULL;
+ enum lttng_tracker_id_status status;
+
+ id = lttng_tracker_id_create();
+ status = lttng_tracker_id_set_value(id, pid);
+ if (status == LTTNG_TRACKER_ID_STATUS_INVALID) {
+ ret = -LTTNG_ERR_INVALID;
+ goto error;
+ }
+
+ ret = lttng_untrack_id(handle, LTTNG_TRACKER_PID, id);
+error:
+ lttng_tracker_id_destroy(id);
+ return ret;
+}
+
/*
* lib constructor.
*/