Backport: trackers: update liblttng-ctl
[deliverable/lttng-tools.git] / src / lib / lttng-ctl / lttng-ctl.c
index 02b3fed4cd3a76a7ff5d828fbabed8723ca38750..e0f21b55d2a84bf968b6ca15ba3dd31968545c87 100644 (file)
@@ -519,10 +519,6 @@ struct lttng_handle *lttng_create_handle(const char *session_name,
 {
        struct lttng_handle *handle = NULL;
 
-       if (domain == NULL) {
-               goto end;
-       }
-
        handle = zmalloc(sizeof(struct lttng_handle));
        if (handle == NULL) {
                PERROR("malloc handle");
@@ -533,8 +529,10 @@ struct lttng_handle *lttng_create_handle(const char *session_name,
        lttng_ctl_copy_string(handle->session_name, session_name,
                        sizeof(handle->session_name));
 
-       /* Copy lttng domain */
-       lttng_ctl_copy_lttng_domain(&handle->domain, domain);
+       /* Copy lttng domain or leave initialized to 0. */
+       if (domain) {
+               lttng_ctl_copy_lttng_domain(&handle->domain, domain);
+       }
 
 end:
        return handle;
@@ -736,9 +734,16 @@ int lttng_add_context(struct lttng_handle *handle,
                memcpy(buf + provider_len, ctx_name, ctx_len);
        }
        memcpy(&lsm.u.context.ctx, ctx, sizeof(struct lttng_event_context));
-       /* Don't leak application addresses to the sessiond. */
-       lsm.u.context.ctx.u.app_ctx.provider_name = NULL;
-       lsm.u.context.ctx.u.app_ctx.ctx_name = NULL;
+
+       if (ctx->ctx == LTTNG_EVENT_CONTEXT_APP_CONTEXT) {
+               /*
+                * Don't leak application addresses to the sessiond.
+                * This is only necessary when ctx is for an app ctx otherwise
+                * the values inside the union (type & config) are overwritten.
+                */
+               lsm.u.context.ctx.u.app_ctx.provider_name = NULL;
+               lsm.u.context.ctx.u.app_ctx.ctx_name = NULL;
+       }
 
        ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, buf, len, NULL);
 end:
@@ -1368,13 +1373,15 @@ int lttng_disable_channel(struct lttng_handle *handle, const char *name)
        return lttng_ctl_ask_sessiond(&lsm, NULL);
 }
 
-/*
- * 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)
+static
+int lttng_track_untrack_id(struct lttng_handle *handle,
+               enum lttng_tracker_type tracker_type,
+               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) {
@@ -1383,41 +1390,82 @@ int lttng_track_pid(struct lttng_handle *handle, int pid)
 
        memset(&lsm, 0, sizeof(lsm));
 
-       lsm.cmd_type = LTTNG_TRACK_PID;
-       lsm.u.pid_tracker.pid = pid;
+       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;
+       }
 
        lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
 
        lttng_ctl_copy_string(lsm.session.name, handle->session_name,
                        sizeof(lsm.session.name));
 
-       return lttng_ctl_ask_sessiond(&lsm, NULL);
+       return lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm,
+                       var_data, var_data_len, NULL);
 }
 
+
 /*
- * Remove PID from session tracker.
+ * Add ID to session tracker.
  * Return 0 on success else a negative LTTng error code.
  */
-int lttng_untrack_pid(struct lttng_handle *handle, int pid)
+int lttng_track_id(struct lttng_handle *handle,
+               enum lttng_tracker_type tracker_type,
+               struct lttng_tracker_id *id)
 {
-       struct lttcomm_session_msg lsm;
-
-       /* NULL arguments are forbidden. No default values. */
-       if (handle == NULL) {
-               return -LTTNG_ERR_INVALID;
-       }
+       return lttng_track_untrack_id(handle, tracker_type,
+                       id, LTTNG_TRACK_ID);
+}
 
-       memset(&lsm, 0, sizeof(lsm));
+/*
+ * 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,
+               struct lttng_tracker_id *id)
+{
+       return lttng_track_untrack_id(handle, tracker_type,
+                       id, LTTNG_UNTRACK_ID);
+}
 
-       lsm.cmd_type = LTTNG_UNTRACK_PID;
-       lsm.u.pid_tracker.pid = pid;
+/*
+ * 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;
 
-       lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
+       id.type = LTTNG_TRACKER_PID;
+       id.value = pid;
+       return lttng_track_id(handle, LTTNG_TRACKER_PID, &id);
+}
 
-       lttng_ctl_copy_string(lsm.session.name, handle->session_name,
-                       sizeof(lsm.session.name));
+/*
+ * 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;
 
-       return lttng_ctl_ask_sessiond(&lsm, NULL);
+       id.type = LTTNG_TRACKER_PID;
+       id.value = pid;
+       return lttng_untrack_id(handle, LTTNG_TRACKER_PID, &id);
 }
 
 /*
@@ -1554,6 +1602,7 @@ int lttng_create_session(const char *name, const char *url)
  * Destroy session using name.
  * Returns size of returned session payload data or a negative error code.
  */
+static
 int _lttng_destroy_session(const char *session_name)
 {
        struct lttcomm_session_msg lsm;
@@ -1694,10 +1743,15 @@ int lttng_list_channels(struct lttng_handle *handle,
                struct lttng_channel **channels)
 {
        int ret;
+       size_t channel_count, i;
+       const size_t channel_size = sizeof(struct lttng_channel) +
+                       sizeof(struct lttcomm_channel_extended);
        struct lttcomm_session_msg lsm;
+       void *extended_at;
 
        if (handle == NULL) {
-               return -LTTNG_ERR_INVALID;
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
        }
 
        memset(&lsm, 0, sizeof(lsm));
@@ -1709,10 +1763,30 @@ int lttng_list_channels(struct lttng_handle *handle,
 
        ret = lttng_ctl_ask_sessiond(&lsm, (void**) channels);
        if (ret < 0) {
-               return ret;
+               goto end;
+       }
+
+       if (ret % channel_size) {
+               ret = -LTTNG_ERR_UNK;
+               free(*channels);
+               *channels = NULL;
+               goto end;
        }
+       channel_count = (size_t) ret / channel_size;
 
-       return ret / sizeof(struct lttng_channel);
+       /* Set extended info pointers */
+       extended_at = ((void *) *channels) +
+                       channel_count * sizeof(struct lttng_channel);
+       for (i = 0; i < channel_count; i++) {
+               struct lttng_channel *chan = &(*channels)[i];
+
+               chan->attr.extended.ptr = extended_at;
+               extended_at += sizeof(struct lttcomm_channel_extended);
+       }
+
+       ret = (int) channel_count;
+end:
+       return ret;
 }
 
 /*
@@ -1753,7 +1827,7 @@ int lttng_list_events(struct lttng_handle *handle,
        /* Set number of events and free command header */
        nb_events = cmd_header->nb_events;
        if (nb_events > INT_MAX) {
-               ret = -EOVERFLOW;
+               ret = -LTTNG_ERR_OVERFLOW;
                goto error;
        }
        ret = (int) nb_events;
@@ -1784,13 +1858,13 @@ error:
        return ret;
 }
 
-int lttng_event_get_filter_string(struct lttng_event *event,
-       const char **filter_string)
+int lttng_event_get_filter_expression(struct lttng_event *event,
+       const char **filter_expression)
 {
        int ret = 0;
        struct lttcomm_event_extended_header *ext_header;
 
-       if (!event || !filter_string) {
+       if (!event || !filter_expression) {
                ret = -LTTNG_ERR_INVALID;
                goto end;
        }
@@ -1802,17 +1876,78 @@ int lttng_event_get_filter_string(struct lttng_event *event,
                 * This can happen since the lttng_event structure is
                 * used for other tasks where this pointer is never set.
                 */
-               *filter_string = NULL;
+               *filter_expression = NULL;
                goto end;
        }
 
        if (ext_header->filter_len) {
-               *filter_string = ((const char *) (ext_header)) +
-                       sizeof(*ext_header);
+               *filter_expression = ((const char *) (ext_header)) +
+                               sizeof(*ext_header);
        } else {
-               *filter_string = NULL;
+               *filter_expression = NULL;
+       }
+
+end:
+       return ret;
+}
+
+int lttng_event_get_exclusion_name_count(struct lttng_event *event)
+{
+       int ret;
+       struct lttcomm_event_extended_header *ext_header;
+
+       if (!event) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ext_header = event->extended.ptr;
+       if (!ext_header) {
+               /*
+                * This can happen since the lttng_event structure is
+                * used for other tasks where this pointer is never set.
+                */
+               ret = 0;
+               goto end;
        }
 
+       if (ext_header->nb_exclusions > INT_MAX) {
+               ret = -LTTNG_ERR_OVERFLOW;
+               goto end;
+       }
+       ret = (int) ext_header->nb_exclusions;
+end:
+       return ret;
+}
+
+int lttng_event_get_exclusion_name(struct lttng_event *event,
+               size_t index, const char **exclusion_name)
+{
+       int ret = 0;
+       struct lttcomm_event_extended_header *ext_header;
+       void *at;
+
+       if (!event || !exclusion_name) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       ext_header = event->extended.ptr;
+       if (!ext_header) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       if (index >= ext_header->nb_exclusions) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       at = (void *) ext_header + sizeof(*ext_header);
+       at += ext_header->filter_len;
+       at += index * LTTNG_SYMBOL_NAME_LEN;
+       *exclusion_name = at;
+
 end:
        return ret;
 }
@@ -1835,26 +1970,13 @@ int lttng_set_tracing_group(const char *name)
        return 0;
 }
 
-/*
- * Returns size of returned session payload data or a negative error code.
- */
 int lttng_calibrate(struct lttng_handle *handle,
                struct lttng_calibrate *calibrate)
 {
-       struct lttcomm_session_msg lsm;
-
-       /* Safety check. NULL pointer are forbidden */
-       if (handle == NULL || calibrate == NULL) {
-               return -LTTNG_ERR_INVALID;
-       }
-
-       memset(&lsm, 0, sizeof(lsm));
-       lsm.cmd_type = LTTNG_CALIBRATE;
-       lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
-
-       memcpy(&lsm.u.calibrate, calibrate, sizeof(lsm.u.calibrate));
-
-       return lttng_ctl_ask_sessiond(&lsm, NULL);
+       /*
+        * This command was removed in LTTng 2.9.
+        */
+       return -LTTNG_ERR_UND;
 }
 
 /*
@@ -1913,6 +2035,58 @@ void lttng_channel_set_default_attr(struct lttng_domain *domain,
        }
 }
 
+int lttng_channel_get_discarded_event_count(struct lttng_channel *channel,
+               uint64_t *discarded_events)
+{
+       int ret = 0;
+       struct lttcomm_channel_extended *chan_ext;
+
+       if (!channel || !discarded_events) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       chan_ext = channel->attr.extended.ptr;
+       if (!chan_ext) {
+               /*
+                * This can happen since the lttng_channel structure is
+                * used for other tasks where this pointer is never set.
+                */
+               *discarded_events = 0;
+               goto end;
+       }
+
+       *discarded_events = chan_ext->discarded_events;
+end:
+       return ret;
+}
+
+int lttng_channel_get_lost_packet_count(struct lttng_channel *channel,
+               uint64_t *lost_packets)
+{
+       int ret = 0;
+       struct lttcomm_channel_extended *chan_ext;
+
+       if (!channel || !lost_packets) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
+       }
+
+       chan_ext = channel->attr.extended.ptr;
+       if (!chan_ext) {
+               /*
+                * This can happen since the lttng_channel structure is
+                * used for other tasks where this pointer is never set.
+                */
+               *lost_packets = 0;
+               goto end;
+       }
+
+       *lost_packets = chan_ext->lost_packets;
+end:
+       return ret;
+}
+
 /*
  * Check if session daemon is alive.
  *
@@ -2190,6 +2364,105 @@ end:
        return ret;
 }
 
+/*
+ * 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 all 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.
+ */
+int lttng_list_tracker_ids(struct lttng_handle *handle,
+               enum lttng_tracker_type tracker_type,
+               struct lttng_tracker_id **_ids, size_t *_nr_ids)
+{
+       int ret, i;
+       struct lttcomm_session_msg lsm;
+       struct lttcomm_tracker_command_header *cmd_header = NULL;
+       char *cmd_payload = NULL, *p;
+       size_t cmd_header_len;
+       size_t nr_ids = 0;
+       struct lttng_tracker_id *ids = NULL;
+
+       if (handle == NULL) {
+               return -LTTNG_ERR_INVALID;
+       }
+
+       memset(&lsm, 0, sizeof(lsm));
+       lsm.cmd_type = LTTNG_LIST_TRACKER_IDS;
+       lsm.u.id_tracker_list.tracker_type = tracker_type;
+       lttng_ctl_copy_string(lsm.session.name, handle->session_name,
+                       sizeof(lsm.session.name));
+       lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
+
+       ret = lttng_ctl_ask_sessiond_varlen(&lsm, NULL, 0, (void **) &cmd_payload,
+               (void **) &cmd_header, &cmd_header_len);
+       if (ret < 0) {
+               goto error;
+       }
+
+       /* Set number of tracker_id and free command header */
+       nr_ids = cmd_header->nb_tracker_id;
+       if (nr_ids > INT_MAX) {
+               ret = -LTTNG_ERR_OVERFLOW;
+               goto error;
+       }
+       free(cmd_header);
+       cmd_header = NULL;
+
+       ids = zmalloc(sizeof(*ids) * nr_ids);
+       if (!ids) {
+               ret = -LTTNG_ERR_NOMEM;
+               goto error;
+       }
+
+       p = cmd_payload;
+       for (i = 0; i < nr_ids; i++) {
+               struct lttcomm_tracker_id_header *tracker_id;
+               struct lttng_tracker_id *id;
+
+               tracker_id = (struct lttcomm_tracker_id_header *) p;
+               p += sizeof(struct lttcomm_tracker_id_header);
+               id = &ids[i];
+
+               id->type = tracker_id->type;
+               switch (tracker_id->type) {
+               case LTTNG_ID_ALL:
+                       break;
+               case LTTNG_ID_VALUE:
+                       id->value = tracker_id->u.value;
+                       break;
+               case LTTNG_ID_STRING:
+                       id->string = strdup(p);
+                       if (!id->string) {
+                               ret = -LTTNG_ERR_NOMEM;
+                               goto error;
+                       }
+                       p += tracker_id->u.var_data_len;
+                       break;
+               default:
+                       goto error;
+               }
+       }
+       free(cmd_payload);
+       *_ids = ids;
+       *_nr_ids = nr_ids;
+       return 0;
+
+error:
+       if (ids) {
+               for (i = 0; i < nr_ids; i++) {
+                       free(ids[i].string);
+               }
+               free(ids);
+       }
+       free(cmd_payload);
+       free(cmd_header);
+       return ret;
+}
+
 /*
  * List PIDs in the tracker.
  *
@@ -2202,44 +2475,122 @@ end:
  */
 int lttng_list_tracker_pids(struct lttng_handle *handle,
                int *_enabled, int32_t **_pids, size_t *_nr_pids)
+{
+       struct lttng_tracker_id *ids = NULL;
+       size_t nr_ids = 0;
+       int *pids = NULL;
+       int ret = 0, i;
+
+       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) {
+               *_enabled = 0;
+               goto end;
+       }
+       *_enabled = 1;
+
+       pids = zmalloc(nr_ids * sizeof(*pids));
+       if (!pids) {
+               ret = -LTTNG_ERR_NOMEM;
+               goto end;
+       }
+       for (i = 0; i < nr_ids; i++) {
+               struct lttng_tracker_id *id = &ids[i];
+
+               if (id->type != LTTNG_ID_VALUE) {
+                       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);
+       }
+       free(ids);
+       if (ret < 0) {
+               free(pids);
+       }
+       return ret;
+}
+
+/*
+ * Regenerate the metadata for a session.
+ * Return 0 on success, a negative error code on error.
+ */
+int lttng_regenerate_metadata(const char *session_name)
 {
        int ret;
-       int enabled = 1;
        struct lttcomm_session_msg lsm;
-       size_t nr_pids;
-       int32_t *pids;
 
-       if (handle == NULL) {
-               return -LTTNG_ERR_INVALID;
+       if (!session_name) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
        }
 
        memset(&lsm, 0, sizeof(lsm));
-       lsm.cmd_type = LTTNG_LIST_TRACKER_PIDS;
-       lttng_ctl_copy_string(lsm.session.name, handle->session_name,
+       lsm.cmd_type = LTTNG_REGENERATE_METADATA;
+
+       lttng_ctl_copy_string(lsm.session.name, session_name,
                        sizeof(lsm.session.name));
-       lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain);
 
-       ret = lttng_ctl_ask_sessiond(&lsm, (void **) &pids);
+       ret = lttng_ctl_ask_sessiond(&lsm, NULL);
        if (ret < 0) {
-               return ret;
+               goto end;
        }
-       nr_pids = ret / sizeof(int32_t);
-       if (nr_pids == 1 && pids[0] == -1) {
-               free(pids);
-               pids = NULL;
-               enabled = 0;
-               nr_pids = 0;
+
+       ret = 0;
+end:
+       return ret;
+}
+
+/*
+ * Deprecated, replaced by lttng_regenerate_metadata.
+ */
+int lttng_metadata_regenerate(const char *session_name)
+{
+       return lttng_regenerate_metadata(session_name);
+}
+
+/*
+ * Regenerate the statedump of a session.
+ * Return 0 on success, a negative error code on error.
+ */
+int lttng_regenerate_statedump(const char *session_name)
+{
+       int ret;
+       struct lttcomm_session_msg lsm;
+
+       if (!session_name) {
+               ret = -LTTNG_ERR_INVALID;
+               goto end;
        }
-       *_enabled = enabled;
-       *_pids = pids;
-       *_nr_pids = nr_pids;
-       return 0;
+
+       memset(&lsm, 0, sizeof(lsm));
+       lsm.cmd_type = LTTNG_REGENERATE_STATEDUMP;
+
+       lttng_ctl_copy_string(lsm.session.name, session_name,
+                       sizeof(lsm.session.name));
+
+       ret = lttng_ctl_ask_sessiond(&lsm, NULL);
+       if (ret < 0) {
+               goto end;
+       }
+
+       ret = 0;
+end:
+       return ret;
 }
 
 /*
  * lib constructor.
  */
-static void __attribute__((constructor)) init()
+static void __attribute__((constructor)) init(void)
 {
        /* Set default session group */
        lttng_set_tracing_group(DEFAULT_TRACING_GROUP);
@@ -2248,7 +2599,7 @@ static void __attribute__((constructor)) init()
 /*
  * lib destructor.
  */
-static void __attribute__((destructor)) lttng_ctl_exit()
+static void __attribute__((destructor)) lttng_ctl_exit(void)
 {
        free(tracing_group);
 }
This page took 0.030896 seconds and 5 git commands to generate.