Refactoring: use an opaque lttng_tracker_id type
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Mon, 18 Nov 2019 02:38:21 +0000 (21:38 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 20 Dec 2019 05:30:59 +0000 (00:30 -0500)
Move the tracker and tracker id related API to tracker.h and
tracker-internal.h.

The use of an opaque object mimics the new API for rotation and trigger
etc.

Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Change-Id: I00b876c618d7dcb0dd940189e5250c3f3d64c7e0
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
22 files changed:
include/Makefile.am
include/lttng/lttng.h
include/lttng/session.h
include/lttng/tracker-internal.h [new file with mode: 0644]
include/lttng/tracker.h [new file with mode: 0644]
src/bin/lttng-sessiond/client.c
src/bin/lttng-sessiond/cmd.c
src/bin/lttng-sessiond/cmd.h
src/bin/lttng-sessiond/kernel.c
src/bin/lttng-sessiond/kernel.h
src/bin/lttng-sessiond/save.c
src/bin/lttng-sessiond/trace-ust.c
src/bin/lttng-sessiond/trace-ust.h
src/bin/lttng-sessiond/tracker.c
src/bin/lttng-sessiond/tracker.h
src/bin/lttng/commands/list.c
src/bin/lttng/commands/track-untrack.c
src/common/Makefile.am
src/common/config/session-config.c
src/common/mi-lttng.c
src/common/tracker.c [new file with mode: 0644]
src/lib/lttng-ctl/lttng-ctl.c

index ab5aa5375794501cc5b75930b1b7e123f6f488a2..610f1cb73cd72ef209ba91e1c895d4c5b814ea9b 100644 (file)
@@ -115,7 +115,8 @@ lttnginclude_HEADERS = \
        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 \
@@ -159,5 +160,6 @@ noinst_HEADERS = \
        lttng/userspace-probe-internal.h \
        lttng/session-internal.h \
        lttng/session-descriptor-internal.h \
+       lttng/tracker-internal.h \
        version.h \
        version.i
index 5279bc57d5d2b79b45cd6bfa98291d67ab7f8358..8d001a21f6fa2020ddd5241862e7d59c9d4a1467 100644 (file)
@@ -48,6 +48,7 @@
 #include <lttng/notification/notification.h>
 #include <lttng/trigger/trigger.h>
 #include <lttng/rotation.h>
+#include <lttng/tracker.h>
 
 #ifdef __cplusplus
 extern "C" {
index 06d4f8b9d51a4f5bea02dfb2fa0e0712f7bc945c..b8a2b7dcc91b18fff4b2181c0ad54be7bf0e1a4d 100644 (file)
@@ -25,28 +25,6 @@ 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;
@@ -239,79 +217,6 @@ extern enum lttng_error_code lttng_session_get_creation_time(
 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
diff --git a/include/lttng/tracker-internal.h b/include/lttng/tracker-internal.h
new file mode 100644 (file)
index 0000000..a84d419
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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 */
diff --git a/include/lttng/tracker.h b/include/lttng/tracker.h
new file mode 100644 (file)
index 0000000..2d952a6
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * 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 */
index ae027d5e0d35a1b7bddb4b391d6feeb12aceb27a..2c7bd4787c9371305455dfa7765ab9397d07877f 100644 (file)
@@ -1207,98 +1207,139 @@ error_add_context:
        }
        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:
@@ -1527,7 +1568,7 @@ error_add_context:
        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;
 
@@ -1543,44 +1584,60 @@ error_add_context:
 
                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) {
index f152c1c2ed191269a19aace219679916a88e0cfb..b668b56d48f90559ff3b63bc61723993dc8c23a7 100644 (file)
@@ -2584,7 +2584,7 @@ ssize_t cmd_list_syscalls(struct lttng_event **events)
 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;
index 9329f42cfc84af2e3a9bd9c3bd011032db038549..ee4bf65e74547019fcc323943d8a9139067989f1 100644 (file)
@@ -117,7 +117,7 @@ ssize_t cmd_list_syscalls(struct lttng_event **events);
 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);
 
index 113937536215df1c17044fbd64a9da95115586c8..c5fd30b7ead925f106cfe4d3c1164c6bc21fd5c8 100644 (file)
@@ -707,8 +707,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
 {
        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) {
@@ -813,9 +813,7 @@ int kernel_track_id(enum lttng_tracker_type tracker_type,
                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;
 }
@@ -826,8 +824,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
 {
        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) {
@@ -933,9 +931,7 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type,
                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;
 }
@@ -945,7 +941,7 @@ end:
  */
 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;
 
index cf91cab1be8535749ec982df1bb7640db101b84b..64d95d2351ee802e57ea4a89b8d44b1adb30d454 100644 (file)
@@ -74,7 +74,7 @@ enum lttng_error_code kernel_clear_session(struct ltt_session *session);
 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);
index 59715d0b9d4324152641ff7b620112ad9f62bad1..83019842d74c1e107d9581a6fa1c82ef296c3e2e 100644 (file)
@@ -1837,8 +1837,12 @@ static int save_id_tracker(struct config_writer *writer,
 {
        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:
@@ -1905,7 +1909,7 @@ static int save_id_tracker(struct config_writer *writer,
                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;
@@ -1940,7 +1944,8 @@ static int save_id_tracker(struct config_writer *writer,
        } 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);
@@ -1948,9 +1953,9 @@ static int save_id_tracker(struct config_writer *writer,
                                        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(
@@ -1959,9 +1964,10 @@ static int save_id_tracker(struct config_writer *writer,
                                        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. */
@@ -1972,6 +1978,10 @@ static int save_id_tracker(struct config_writer *writer,
                                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);
@@ -1998,6 +2008,7 @@ static int save_id_tracker(struct config_writer *writer,
 
        ret = LTTNG_OK;
 end:
+       lttng_tracker_ids_destroy(ids, nr_ids);
        free(ids);
        return ret;
 }
index f64f51c280d670b9b83070abb6e2666d97ce51e2..4a7e2610510cd805722315add867db300ea66823 100644 (file)
@@ -918,8 +918,8 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type,
        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.");
@@ -1002,9 +1002,7 @@ end_restore:
                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;
 }
@@ -1021,8 +1019,8 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
        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.");
@@ -1107,9 +1105,7 @@ end_restore:
                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;
 }
@@ -1119,7 +1115,7 @@ end:
  */
 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;
 
index 1f6f534fec96591d6f651dac800a396987f1160f..2d0b042e5e3a90fab3d9f9d2841b3bfac9ea6047 100644 (file)
@@ -240,7 +240,7 @@ int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type,
 
 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 */
 
index af527b4fd03b5f7a2fd441b71c225ad1f1df8495..909a04845c1770bef7d6d1be62cba1594d75f4da 100644 (file)
@@ -27,6 +27,7 @@
 #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
@@ -60,53 +61,42 @@ static int match_tracker_key(struct cds_lfht_node *node, const void *key)
 
        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)
 {
@@ -130,7 +120,7 @@ static void destroy_list_node_rcu(struct rcu_head *head)
        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);
 }
 
@@ -161,14 +151,15 @@ static void lttng_tracker_list_reset(struct lttng_tracker_list *tracker_list)
 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);
@@ -178,28 +169,26 @@ int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list,
         */
        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;
@@ -217,10 +206,10 @@ int lttng_tracker_list_remove(struct lttng_tracker_list *tracker_list,
                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". */
@@ -380,14 +369,26 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type,
                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:
@@ -396,11 +397,11 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type,
                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;
                }
@@ -412,14 +413,15 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type,
 
 /*
  * 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:
@@ -435,14 +437,10 @@ ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_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++;
                }
@@ -456,7 +454,13 @@ ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list,
                        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;
@@ -469,21 +473,19 @@ end:
        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;
        }
@@ -493,7 +495,7 @@ int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list,
                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);
index 1df4a0ce75c94fa5dd8e81031fb330be808618d8..812b3b1277e3265865d9042fb8a7e1a6f0803144 100644 (file)
@@ -18,7 +18,7 @@
  * 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>
@@ -31,7 +31,7 @@ enum lttng_tracker_list_state {
 
 /* 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;
@@ -57,9 +57,9 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type,
                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 */
index 226eb4c871da31102c9a2c096c49442e7ad2dd38..49470ab86b91d00fc8032f5062b8b89429599ad0 100644 (file)
@@ -26,6 +26,7 @@
 #include <common/mi-lttng.h>
 #include <common/time.h>
 #include <lttng/constant.h>
+#include <lttng/tracker.h>
 
 #include "../command.h"
 
@@ -1538,14 +1539,14 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type)
 {
        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) {
@@ -1561,23 +1562,49 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type)
                }
 
                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 */
@@ -1600,10 +1627,7 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type)
                }
        }
 end:
-       for (i = 0; i < nr_ids; i++) {
-               free(ids[i].string);
-       }
-       free(ids);
+       lttng_tracker_ids_destroy(ids, nr_ids);
        return ret;
 }
 
index 25b4461f696a7e96beab3265da9f437eb1fda9d5..c54b6407802ed7cd0e342c057f9d3c460c05a351 100644 (file)
@@ -56,7 +56,7 @@ struct opt_type {
 
 struct id_list {
        size_t nr;
-       struct lttng_tracker_id *array;
+       struct lttng_tracker_id **array;
 };
 
 static char *opt_session_name;
@@ -100,7 +100,7 @@ static struct poptOption long_options[] = {
 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) {
@@ -128,15 +128,16 @@ static void free_id_list(struct id_list *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;
@@ -157,14 +158,28 @@ static int parse_id_string(
                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;
        }
 
@@ -230,20 +245,30 @@ static int parse_id_string(
        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;
                        }
@@ -254,11 +279,12 @@ static int parse_id_string(
        }
 
 assign:
+       /* SUCCESS */
        *_id_list = id_list;
-       goto end;       /* SUCCESS */
+       goto end;
 
-       /* ERROR */
 error:
+       /* ERROR */
        free_id_list(id_list);
 end:
        free(id_string);
@@ -365,7 +391,7 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
                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;
@@ -387,22 +413,51 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
        }
 
        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;
@@ -425,7 +480,7 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
                                break;
                        }
                        if (msg) {
-                               switch (item->type) {
+                               switch (type) {
                                case LTTNG_ID_ALL:
                                        WARN("All %ss %s in session %s",
                                                        tracker_str, msg,
@@ -433,14 +488,13 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
                                        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:
@@ -449,19 +503,18 @@ static enum cmd_error_code track_untrack_id(enum cmd_type cmd_type,
                                }
                        }
                } 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:
index 95935b76e6283b2ae9a9cdf1195c60f757848a67..e7ceefe47cf8d5a1b9e0ad659103e507557cd44e 100644 (file)
@@ -62,6 +62,7 @@ libcommon_la_SOURCES = \
        userspace-probe.c \
        utils.c utils.h \
        uuid.c uuid.h \
+       tracker.c \
        waiter.c waiter.h
 
 if HAVE_ELF_H
index e625f316a96e735ff77485b1830926c38b663f9d..695142a298256a743f9fb1efddb9153a4a242e94 100644 (file)
@@ -2745,6 +2745,7 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node,
        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);
@@ -2774,11 +2775,21 @@ static int process_id_tracker_node(xmlNodePtr 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;
                }
@@ -2796,7 +2807,7 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node,
                                                                        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) {
@@ -2811,10 +2822,23 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node,
                                        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;
                                }
@@ -2822,17 +2846,31 @@ static int process_id_tracker_node(xmlNodePtr id_tracker_node,
                        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;
index f884f9385de317c72b68422e626a281878f6e1e9..7b0d9cf0266b981db43b3344f9c67ac9d3280f32 100644 (file)
@@ -21,6 +21,7 @@
 #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"
 
@@ -1666,6 +1667,9 @@ int mi_lttng_id_target(struct mi_writer *writer,
 {
        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);
@@ -1673,7 +1677,7 @@ int mi_lttng_id_target(struct mi_writer *writer,
                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) {
@@ -1702,8 +1706,15 @@ int mi_lttng_id_target(struct mi_writer *writer,
                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;
                }
@@ -1721,8 +1732,15 @@ int mi_lttng_id_target(struct mi_writer *writer,
                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;
                }
diff --git a/src/common/tracker.c b/src/common/tracker.c
new file mode 100644 (file)
index 0000000..f8a4fba
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * 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;
+}
index 085005c3940bd4d1c039996b83857f454a29cbf0..406de885c713a4f4ab6a4d022c117f2a43946980 100644 (file)
@@ -46,6 +46,7 @@
 #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"
@@ -1606,98 +1607,6 @@ int lttng_disable_channel(struct lttng_handle *handle, const char *name)
        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.
@@ -2923,14 +2832,14 @@ end:
  *
  * 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;
@@ -2939,7 +2848,7 @@ int lttng_list_tracker_ids(struct lttng_handle *handle,
        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;
@@ -2978,29 +2887,40 @@ int lttng_list_tracker_ids(struct lttng_handle *handle,
        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;
@@ -3008,12 +2928,8 @@ int lttng_list_tracker_ids(struct lttng_handle *handle,
        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;
@@ -3032,16 +2948,17 @@ error:
 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;
        }
@@ -3053,20 +2970,18 @@ int lttng_list_tracker_pids(struct lttng_handle *handle,
                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);
@@ -3208,6 +3123,131 @@ end:
        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.
  */
This page took 0.058091 seconds and 4 git commands to generate.