extern "C" {
#endif
+#include <lttng/constant.h>
+
enum lttng_tracker_type {
LTTNG_TRACKER_PID = 0,
LTTNG_TRACKER_VPID = 1,
char *string;
};
+struct lttng_handle;
struct lttng_session_descriptor;
struct lttng_destruction_handle;
extern int lttng_set_session_shm_path(const char *session_name,
const char *shm_path);
+/*
+ * Add ID to session tracker.
+ *
+ * tracker_type is the type of tracker.
+ * id the id to track.
+ *
+ * Return 0 on success else a negative LTTng error code.
+ */
+extern int lttng_track_id(struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type,
+ const struct lttng_tracker_id *id);
+
+/*
+ * Remove ID from session tracker.
+ *
+ * tracker_type is the type of tracker.
+ * id the id to untrack.
+ *
+ * Return 0 on success else a negative LTTng error code.
+ */
+extern int lttng_untrack_id(struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type,
+ const struct lttng_tracker_id *id);
+
+/*
+ * List IDs in the tracker.
+ *
+ * tracker_type is the type of tracker.
+ * ids is set to an allocated array of IDs currently tracked. On
+ * success, ids and the strings it contains must be freed by the
+ * caller.
+ * nr_ids is set to the number of entries contained by the ids array.
+ *
+ * Returns 0 on success, else a negative LTTng error code.
+ */
+extern int lttng_list_tracker_ids(struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type,
+ struct lttng_tracker_id **ids,
+ size_t *nr_ids);
+
/*
* Add PID to session tracker.
*
manage-apps.c manage-apps.h \
manage-kernel.c manage-kernel.h \
manage-consumer.c manage-consumer.h \
- clear.c clear.h
+ clear.c clear.h \
+ tracker.c tracker.h
if HAVE_LIBLTTNG_UST_CTL
lttng_sessiond_SOURCES += trace-ust.c ust-registry.c ust-app.c \
case LTTNG_LIST_CHANNELS:
case LTTNG_LIST_EVENTS:
case LTTNG_LIST_SYSCALLS:
- case LTTNG_LIST_TRACKER_PIDS:
+ case LTTNG_LIST_TRACKER_IDS:
case LTTNG_DATA_PENDING:
case LTTNG_ROTATE_SESSION:
case LTTNG_ROTATION_GET_INFO:
kernel_poll_pipe[1]);
break;
}
- case LTTNG_TRACK_PID:
+ case LTTNG_TRACK_ID:
{
- ret = cmd_track_pid(cmd_ctx->session,
- cmd_ctx->lsm->domain.type,
- cmd_ctx->lsm->u.pid_tracker.pid);
+ struct lttng_tracker_id id;
+
+ memset(&id, 0, sizeof(id));
+ id.type = cmd_ctx->lsm->u.id_tracker.id_type;
+ switch (id.type) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ id.value = 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;
+
+ id.string = zmalloc(var_len);
+ if (!id.string) {
+ 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);
+ if (ret <= 0) {
+ DBG("Nothing received");
+ *sock_error = 1;
+ free(id.string);
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ if (strnlen(id.string, var_len) != var_len - 1) {
+ DBG("String received as tracker ID is not NULL-terminated");
+ free(id.string);
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ break;
+ }
+ default:
+ ret = LTTNG_ERR_INVALID;
+ 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);
break;
}
- case LTTNG_UNTRACK_PID:
+ case LTTNG_UNTRACK_ID:
{
- ret = cmd_untrack_pid(cmd_ctx->session,
- cmd_ctx->lsm->domain.type,
- cmd_ctx->lsm->u.pid_tracker.pid);
+ struct lttng_tracker_id id;
+
+ memset(&id, 0, sizeof(id));
+ id.type = cmd_ctx->lsm->u.id_tracker.id_type;
+ switch (id.type) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ id.value = 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;
+
+ id.string = zmalloc(var_len);
+ if (!id.string) {
+ 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);
+ if (ret <= 0) {
+ DBG("Nothing received");
+ *sock_error = 1;
+ free(id.string);
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ if (strnlen(id.string, var_len) != var_len - 1) {
+ DBG("String received as tracker ID is not NULL-terminated");
+ free(id.string);
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ break;
+ }
+ default:
+ 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);
break;
}
case LTTNG_ENABLE_EVENT:
ret = LTTNG_OK;
break;
}
- case LTTNG_LIST_TRACKER_PIDS:
+ case LTTNG_LIST_TRACKER_IDS:
{
- int32_t *pids = NULL;
- ssize_t nr_pids;
-
- nr_pids = cmd_list_tracker_pids(cmd_ctx->session,
- cmd_ctx->lsm->domain.type, &pids);
- if (nr_pids < 0) {
+ struct lttcomm_tracker_command_header cmd_header;
+ struct lttng_tracker_id *ids = NULL;
+ ssize_t nr_ids, i;
+ struct lttng_dynamic_buffer buf;
+
+ nr_ids = cmd_list_tracker_ids(
+ cmd_ctx->lsm->u.id_tracker.tracker_type,
+ cmd_ctx->session, cmd_ctx->lsm->domain.type,
+ &ids);
+ if (nr_ids < 0) {
/* Return value is a negative lttng_error_code. */
- ret = -nr_pids;
+ ret = -nr_ids;
goto error;
}
- /*
- * Setup lttng message with payload size set to the event list size in
- * bytes and then copy list into the llm payload.
- */
- ret = setup_lttng_msg_no_cmd_header(cmd_ctx, pids,
- sizeof(int32_t) * nr_pids);
- free(pids);
+ lttng_dynamic_buffer_init(&buf);
+ for (i = 0; i < nr_ids; i++) {
+ struct lttng_tracker_id *id = &ids[i];
+ struct lttcomm_tracker_id_header id_hdr;
+ size_t var_data_len = 0;
+
+ memset(&id_hdr, 0, sizeof(id_hdr));
+ id_hdr.type = id->type;
+ switch (id->type) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ id_hdr.u.value = id->value;
+ break;
+ case LTTNG_ID_STRING:
+ id_hdr.u.var_data_len = var_data_len =
+ strlen(id->string) + 1;
+ break;
+ default:
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+ ret = lttng_dynamic_buffer_append(
+ &buf, &id_hdr, sizeof(id_hdr));
+ if (ret) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ ret = lttng_dynamic_buffer_append(
+ &buf, id->string, var_data_len);
+ if (ret) {
+ ret = LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ 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));
+ free(ids);
+ lttng_dynamic_buffer_reset(&buf);
if (ret < 0) {
goto setup_error;
}
}
/*
- * Command LTTNG_TRACK_PID processed by the client thread.
+ * Command LTTNG_TRACK_ID processed by the client thread.
*
* Called with session lock held.
*/
-int cmd_track_pid(struct ltt_session *session, enum lttng_domain_type domain,
- int pid)
+int cmd_track_id(struct ltt_session *session,
+ enum lttng_tracker_type tracker_type,
+ enum lttng_domain_type domain,
+ const struct lttng_tracker_id *id)
{
int ret;
ksess = session->kernel_session;
- ret = kernel_track_pid(ksess, pid);
+ ret = kernel_track_id(tracker_type, ksess, id);
if (ret != LTTNG_OK) {
goto error;
}
usess = session->ust_session;
- ret = trace_ust_track_pid(usess, pid);
+ ret = trace_ust_track_id(tracker_type, usess, id);
if (ret != LTTNG_OK) {
goto error;
}
}
/*
- * Command LTTNG_UNTRACK_PID processed by the client thread.
+ * Command LTTNG_UNTRACK_ID processed by the client thread.
*
* Called with session lock held.
*/
-int cmd_untrack_pid(struct ltt_session *session, enum lttng_domain_type domain,
- int pid)
+int cmd_untrack_id(struct ltt_session *session,
+ enum lttng_tracker_type tracker_type,
+ enum lttng_domain_type domain,
+ const struct lttng_tracker_id *id)
{
int ret;
ksess = session->kernel_session;
- ret = kernel_untrack_pid(ksess, pid);
+ ret = kernel_untrack_id(tracker_type, ksess, id);
if (ret != LTTNG_OK) {
goto error;
}
usess = session->ust_session;
- ret = trace_ust_untrack_pid(usess, pid);
+ ret = trace_ust_untrack_id(tracker_type, usess, id);
if (ret != LTTNG_OK) {
goto error;
}
}
/*
- * Command LTTNG_LIST_TRACKER_PIDS processed by the client thread.
+ * Command LTTNG_LIST_TRACKER_IDS processed by the client thread.
*
* Called with session lock held.
*/
-ssize_t cmd_list_tracker_pids(struct ltt_session *session,
- enum lttng_domain_type domain, int32_t **pids)
+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)
{
int ret;
ssize_t nr_pids = 0;
struct ltt_kernel_session *ksess;
ksess = session->kernel_session;
- nr_pids = kernel_list_tracker_pids(ksess, pids);
+ nr_pids = kernel_list_tracker_ids(tracker_type, ksess, ids);
if (nr_pids < 0) {
ret = LTTNG_ERR_KERN_LIST_FAIL;
goto error;
struct ltt_ust_session *usess;
usess = session->ust_session;
- nr_pids = trace_ust_list_tracker_pids(usess, pids);
+ nr_pids = trace_ust_list_tracker_ids(tracker_type, usess, ids);
if (nr_pids < 0) {
ret = LTTNG_ERR_UST_LIST_FAIL;
goto error;
int cmd_enable_channel(struct ltt_session *session,
const struct lttng_domain *domain, const struct lttng_channel *attr,
int wpipe);
-int cmd_track_pid(struct ltt_session *session, enum lttng_domain_type domain,
- int pid);
-int cmd_untrack_pid(struct ltt_session *session, enum lttng_domain_type domain,
- int pid);
+int cmd_track_id(struct ltt_session *session,
+ enum lttng_tracker_type tracker_type,
+ enum lttng_domain_type domain,
+ const struct lttng_tracker_id *id);
+int cmd_untrack_id(struct ltt_session *session,
+ enum lttng_tracker_type tracker_type,
+ enum lttng_domain_type domain,
+ const struct lttng_tracker_id *id);
/* Event commands */
int cmd_disable_event(struct ltt_session *session,
ssize_t cmd_snapshot_list_outputs(struct ltt_session *session,
struct lttng_snapshot_output **outputs);
ssize_t cmd_list_syscalls(struct lttng_event **events);
-ssize_t cmd_list_tracker_pids(struct ltt_session *session,
- enum lttng_domain_type domain, int32_t **pids);
+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);
int cmd_data_pending(struct ltt_session *session);
return ret;
}
+static struct lttng_tracker_list *get_id_tracker_list(
+ struct ltt_kernel_session *session,
+ enum lttng_tracker_type tracker_type)
+{
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ return session->tracker_list_pid;
+ case LTTNG_TRACKER_VPID:
+ return session->tracker_list_vpid;
+ case LTTNG_TRACKER_UID:
+ return session->tracker_list_uid;
+ case LTTNG_TRACKER_VUID:
+ return session->tracker_list_vuid;
+ case LTTNG_TRACKER_GID:
+ return session->tracker_list_gid;
+ case LTTNG_TRACKER_VGID:
+ return session->tracker_list_vgid;
+ default:
+ return NULL;
+ }
+}
-int kernel_track_pid(struct ltt_kernel_session *session, int pid)
+int kernel_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ const struct lttng_tracker_id *id)
{
- int ret;
+ int ret, value;
+ struct lttng_tracker_list *tracker_list;
+ struct lttng_tracker_id *saved_ids;
+ ssize_t saved_ids_count, i;
- DBG("Kernel track PID %d for session id %" PRIu64 ".",
- pid, session->id);
- ret = kernctl_track_pid(session->fd, pid);
- if (!ret) {
- return LTTNG_OK;
+ ret = lttng_tracker_id_lookup_string(tracker_type, id, &value);
+ if (ret != LTTNG_OK) {
+ return ret;
}
- switch (-ret) {
- case EINVAL:
+
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
return LTTNG_ERR_INVALID;
- case ENOMEM:
- return LTTNG_ERR_NOMEM;
- case EEXIST:
- return LTTNG_ERR_PID_TRACKED;
- default:
- return LTTNG_ERR_UNK;
}
-}
-int kernel_untrack_pid(struct ltt_kernel_session *session, int pid)
-{
- int ret;
+ /* Save list for restore on error. */
+ saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids);
+ if (saved_ids_count < 0) {
+ return LTTNG_ERR_INVALID;
+ }
- DBG("Kernel untrack PID %d for session id %" PRIu64 ".",
- pid, session->id);
- ret = kernctl_untrack_pid(session->fd, pid);
- if (!ret) {
- return LTTNG_OK;
+ /* Add to list. */
+ ret = lttng_tracker_list_add(tracker_list, id);
+ if (ret != LTTNG_OK) {
+ goto end;
}
+
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ DBG("Kernel track PID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_track_pid(session->fd, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_VPID:
+ DBG("Kernel track VPID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_VPID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_UID:
+ DBG("Kernel track UID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_UID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_GID:
+ DBG("Kernel track GID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_GID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_VUID:
+ DBG("Kernel track VUID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_VUID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_VGID:
+ DBG("Kernel track VGID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_track_id(session->fd, LTTNG_TRACKER_VGID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ /* Error handling. */
switch (-ret) {
case EINVAL:
- return LTTNG_ERR_INVALID;
+ ret = LTTNG_ERR_INVALID;
+ break;
case ENOMEM:
- return LTTNG_ERR_NOMEM;
- case ENOENT:
- return LTTNG_ERR_PID_NOT_TRACKED;
+ ret = LTTNG_ERR_NOMEM;
+ break;
+ case EEXIST:
+ ret = LTTNG_ERR_ID_TRACKED;
+ break;
default:
- return LTTNG_ERR_UNK;
+ ret = LTTNG_ERR_UNK;
+ break;
}
+
+ if (lttng_tracker_id_set_list(tracker_list, saved_ids,
+ saved_ids_count) != LTTNG_OK) {
+ ERR("Error on tracker add error handling.\n");
+ }
+end:
+ for (i = 0; i < saved_ids_count; i++) {
+ free(saved_ids[i].string);
+ }
+ free(saved_ids);
+ return ret;
}
-ssize_t kernel_list_tracker_pids(struct ltt_kernel_session *session,
- int **_pids)
+int kernel_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ const struct lttng_tracker_id *id)
{
- int fd, ret;
- int pid;
- ssize_t nbmem, count = 0;
- FILE *fp;
- int *pids;
+ int ret, value;
+ struct lttng_tracker_list *tracker_list;
+ struct lttng_tracker_id *saved_ids;
+ ssize_t saved_ids_count, i;
- fd = kernctl_list_tracker_pids(session->fd);
- if (fd < 0) {
- PERROR("kernel tracker pids list");
- goto error;
+ ret = lttng_tracker_id_lookup_string(tracker_type, id, &value);
+ if (ret != LTTNG_OK) {
+ return ret;
}
- fp = fdopen(fd, "r");
- if (fp == NULL) {
- PERROR("kernel tracker pids list fdopen");
- goto error_fp;
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return LTTNG_ERR_INVALID;
}
-
- nbmem = KERNEL_TRACKER_PIDS_INIT_LIST_SIZE;
- pids = zmalloc(sizeof(*pids) * nbmem);
- if (pids == NULL) {
- PERROR("alloc list pids");
- count = -ENOMEM;
+ /* Save list for restore on error. */
+ saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids);
+ if (saved_ids_count < 0) {
+ return LTTNG_ERR_INVALID;
+ }
+ /* Remove from list. */
+ ret = lttng_tracker_list_remove(tracker_list, id);
+ if (ret != LTTNG_OK) {
goto end;
}
- while (fscanf(fp, "process { pid = %u; };\n", &pid) == 1) {
- if (count >= nbmem) {
- int *new_pids;
- size_t new_nbmem;
-
- new_nbmem = nbmem << 1;
- DBG("Reallocating pids list from %zu to %zu entries",
- nbmem, new_nbmem);
- new_pids = realloc(pids, new_nbmem * sizeof(*new_pids));
- if (new_pids == NULL) {
- PERROR("realloc list events");
- free(pids);
- count = -ENOMEM;
- goto end;
- }
- /* Zero the new memory */
- memset(new_pids + nbmem, 0,
- (new_nbmem - nbmem) * sizeof(*new_pids));
- nbmem = new_nbmem;
- pids = new_pids;
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ DBG("Kernel untrack PID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_untrack_pid(session->fd, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_VPID:
+ DBG("Kernel untrack VPID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_untrack_id(
+ session->fd, LTTNG_TRACKER_VPID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_UID:
+ DBG("Kernel untrack UID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_UID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_GID:
+ DBG("Kernel untrack GID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_untrack_id(session->fd, LTTNG_TRACKER_GID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_VUID:
+ DBG("Kernel untrack VUID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_untrack_id(
+ session->fd, LTTNG_TRACKER_VUID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
+ }
+ break;
+ case LTTNG_TRACKER_VGID:
+ DBG("Kernel untrack VGID %d for session id %" PRIu64 ".", value,
+ session->id);
+ ret = kernctl_untrack_id(
+ session->fd, LTTNG_TRACKER_VGID, value);
+ if (!ret) {
+ ret = LTTNG_OK;
+ goto end;
}
- pids[count++] = pid;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ /* Error handling. */
+ switch (-ret) {
+ case EINVAL:
+ ret = LTTNG_ERR_INVALID;
+ break;
+ case ENOMEM:
+ ret = LTTNG_ERR_NOMEM;
+ break;
+ case EEXIST:
+ ret = LTTNG_ERR_ID_TRACKED;
+ break;
+ default:
+ ret = LTTNG_ERR_UNK;
+ break;
}
- *_pids = pids;
- DBG("Kernel list tracker pids done (%zd pids)", count);
+ if (lttng_tracker_id_set_list(tracker_list, saved_ids,
+ saved_ids_count) != LTTNG_OK) {
+ ERR("Error on tracker remove error handling.\n");
+ }
end:
- ret = fclose(fp); /* closes both fp and fd */
- if (ret) {
- PERROR("fclose");
+ for (i = 0; i < saved_ids_count; i++) {
+ free(saved_ids[i].string);
}
- return count;
+ free(saved_ids);
+ return ret;
+}
-error_fp:
- ret = close(fd);
- if (ret) {
- PERROR("close");
+/*
+ * Called with session lock held.
+ */
+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_list *tracker_list;
+
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return -LTTNG_ERR_INVALID;
}
-error:
- return -1;
+ return lttng_tracker_id_get_list(tracker_list, _ids);
}
/*
* dynamic reallocation is performed.
*/
#define KERNEL_EVENT_INIT_LIST_SIZE 64
-#define KERNEL_TRACKER_PIDS_INIT_LIST_SIZE 64
+#define KERNEL_TRACKER_IDS_INIT_LIST_SIZE 64
int kernel_add_channel_context(struct ltt_kernel_channel *chan,
struct ltt_kernel_context *ctx);
int kernel_disable_event(struct ltt_kernel_event *event);
int kernel_enable_event(struct ltt_kernel_event *event);
int kernel_enable_channel(struct ltt_kernel_channel *chan);
-int kernel_track_pid(struct ltt_kernel_session *session, int pid);
-int kernel_untrack_pid(struct ltt_kernel_session *session, int pid);
+int kernel_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ const struct lttng_tracker_id *id);
+int kernel_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ const struct lttng_tracker_id *id);
int kernel_open_metadata(struct ltt_kernel_session *session);
int kernel_open_metadata_stream(struct ltt_kernel_session *session);
int kernel_open_channel_stream(struct ltt_kernel_channel *channel);
enum lttng_error_code kernel_clear_session(struct ltt_session *session);
int init_kernel_workarounds(void);
-ssize_t kernel_list_tracker_pids(struct ltt_kernel_session *session,
- int **_pids);
+ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ 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);
#include "trace-ust.h"
#include "agent.h"
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_channel_attributes(struct config_writer *writer,
struct lttng_channel_attr *attr)
attr->overwrite ? config_overwrite_mode_overwrite :
config_overwrite_mode_discard);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
ret = config_writer_write_element_unsigned_int(writer,
config_element_subbuf_size, attr->subbuf_size);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_num_subbuf,
attr->num_subbuf);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_switch_timer_interval,
attr->switch_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_read_timer_interval,
attr->read_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
attr->output == LTTNG_EVENT_SPLICE ?
config_output_type_splice : config_output_type_mmap);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
ret = config_writer_write_element_unsigned_int(writer,
config_element_tracefile_size, attr->tracefile_size);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_tracefile_count,
attr->tracefile_count);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_live_timer_interval,
attr->live_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_monitor_timer_interval,
ext->monitor_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_blocking_timeout,
ext->blocking_timeout);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
}
+ ret = LTTNG_OK;
end:
- return ret ? LTTNG_ERR_SAVE_IO_FAIL : 0;
+ return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_channel_attributes(struct config_writer *writer,
struct lttng_ust_channel_attr *attr)
attr->overwrite ? config_overwrite_mode_overwrite :
config_overwrite_mode_discard);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
ret = config_writer_write_element_unsigned_int(writer,
config_element_subbuf_size, attr->subbuf_size);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_num_subbuf,
attr->num_subbuf);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_switch_timer_interval,
attr->switch_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_read_timer_interval,
attr->read_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
attr->output == LTTNG_UST_MMAP ?
config_output_type_mmap : config_output_type_splice);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_blocking_timeout,
attr->u.s.blocking_timeout);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
config_element_monitor_timer_interval,
channel->monitor_timer_interval);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+ ret = LTTNG_OK;
end:
- return ret ? LTTNG_ERR_SAVE_IO_FAIL : 0;
+ return ret;
}
static
return loglevel_type_string;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_function_event(struct config_writer *writer,
struct ltt_kernel_event *event)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_events(struct config_writer *writer,
struct ltt_kernel_channel *kchan)
cds_list_for_each_entry(event, &kchan->events_list.head, list) {
ret = save_kernel_event(writer, event);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_event(struct config_writer *writer,
struct ltt_ust_event *event)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_events(struct config_writer *writer,
struct lttng_ht *events)
continue;
}
ret = save_ust_event(writer, event);
- if (ret) {
+ if (ret != LTTNG_OK) {
rcu_read_unlock();
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event,
struct agent_event *agent_event)
{
- int ret = 0;
+ int ret;
enum lttng_ust_loglevel_type ust_loglevel_type;
ust_event->enabled = agent_event->enabled;
ust_event->attr.instrumentation = LTTNG_UST_TRACEPOINT;
if (lttng_strncpy(ust_event->attr.name, agent_event->name,
LTTNG_SYMBOL_NAME_LEN)) {
- ret = -1;
+ ret = LTTNG_ERR_INVALID;
goto end;
}
switch (agent_event->loglevel_type) {
break;
default:
ERR("Invalid agent_event loglevel_type.");
- ret = -1;
+ ret = LTTNG_ERR_INVALID;
goto end;
}
ust_event->attr.loglevel = agent_event->loglevel_value;
ust_event->filter_expression = agent_event->filter_expression;
ust_event->exclusion = agent_event->exclusion;
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_agent_events(struct config_writer *writer,
struct agent *agent)
* structures...).
*/
ret = init_ust_event_from_agent_event(&fake_event, agent_event);
- if (ret) {
+ if (ret != LTTNG_OK) {
rcu_read_unlock();
goto end;
}
ret = save_ust_event(writer, &fake_event);
- if (ret) {
+ if (ret != LTTNG_OK) {
rcu_read_unlock();
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_context(struct config_writer *writer,
struct lttng_kernel_context *ctx)
{
- int ret = 0;
+ int ret = LTTNG_OK;
if (!ctx) {
goto end;
goto end;
}
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_contexts(struct config_writer *writer,
struct ltt_kernel_channel *kchan)
struct ltt_kernel_context *ctx;
if (cds_list_empty(&kchan->ctx_list)) {
- ret = 0;
+ ret = LTTNG_OK;
goto end;
}
cds_list_for_each_entry(ctx, &kchan->ctx_list, list) {
ret = save_kernel_context(writer, &ctx->ctx);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_context_perf_thread_counter(struct config_writer *writer,
struct ltt_ust_context *ctx)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_context_app_ctx(struct config_writer *writer,
struct ltt_ust_context *ctx)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_context_generic(struct config_writer *writer,
struct ltt_ust_context *ctx)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_context(struct config_writer *writer,
struct cds_list_head *ctx_list)
/* Save generic context. */
ret = save_ust_context_generic(writer, ctx);
}
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_channel(struct config_writer *writer,
struct ltt_kernel_channel *kchan)
}
ret = save_kernel_channel_attributes(writer, &kchan->channel->attr);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_kernel_events(writer, kchan);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_kernel_contexts(writer, kchan);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_channel(struct config_writer *writer,
struct ltt_ust_channel *ust_chan,
}
ret = save_ust_channel_attributes(writer, &ust_chan->attr);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
if (ust_chan->domain == LTTNG_DOMAIN_UST) {
ret = save_ust_events(writer, ust_chan->events);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
} else {
* them.
*/
ret = save_agent_events(writer, agent);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = save_ust_context(writer, &ust_chan->ctx_list);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_kernel_session(struct config_writer *writer,
struct ltt_session *session)
cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head,
list) {
ret = save_kernel_channel(writer, kchan);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
return str_dom;
}
-static
-int save_pid_tracker(struct config_writer *writer,
- struct ltt_session *sess, int domain)
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
+static int save_id_tracker(struct config_writer *writer,
+ struct ltt_session *sess,
+ int domain,
+ enum lttng_tracker_type tracker_type)
{
- int ret = 0;
- ssize_t nr_pids = 0, i;
- int32_t *pids = NULL;
+ int ret = LTTNG_OK;
+ ssize_t nr_ids = 0, i;
+ struct lttng_tracker_id *ids = NULL;
+ const char *element_id_tracker, *element_target_id, *element_id;
+
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ element_id_tracker = config_element_pid_tracker;
+ element_target_id = config_element_target_pid;
+ element_id = config_element_pid;
+ break;
+ case LTTNG_TRACKER_VPID:
+ element_id_tracker = config_element_vpid_tracker;
+ element_target_id = config_element_target_vpid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_UID:
+ element_id_tracker = config_element_uid_tracker;
+ element_target_id = config_element_target_uid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_VUID:
+ element_id_tracker = config_element_vuid_tracker;
+ element_target_id = config_element_target_vuid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_GID:
+ element_id_tracker = config_element_gid_tracker;
+ element_target_id = config_element_target_gid;
+ element_id = config_element_id;
+ break;
+ case LTTNG_TRACKER_VGID:
+ element_id_tracker = config_element_vgid_tracker;
+ element_target_id = config_element_target_vgid;
+ element_id = config_element_id;
+ break;
+ default:
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
switch (domain) {
case LTTNG_DOMAIN_KERNEL:
{
- nr_pids = kernel_list_tracker_pids(sess->kernel_session, &pids);
- if (nr_pids < 0) {
+ nr_ids = kernel_list_tracker_ids(
+ tracker_type, sess->kernel_session, &ids);
+ if (nr_ids < 0) {
ret = LTTNG_ERR_KERN_LIST_FAIL;
goto end;
}
}
case LTTNG_DOMAIN_UST:
{
- nr_pids = trace_ust_list_tracker_pids(sess->ust_session, &pids);
- if (nr_pids < 0) {
+ nr_ids = trace_ust_list_tracker_ids(
+ tracker_type, sess->ust_session, &ids);
+ if (nr_ids < 0) {
ret = LTTNG_ERR_UST_LIST_FAIL;
goto end;
}
goto end;
}
- /* Only create a pid_tracker if enabled or untrack all */
- if (nr_pids != 1 || (nr_pids == 1 && pids[0] != -1)) {
- ret = config_writer_open_element(writer,
- config_element_pid_tracker);
+ if (nr_ids == 1 && ids[0].type == LTTNG_ID_ALL) {
+ /* Tracking all, nothing to output. */
+ ret = LTTNG_OK;
+ goto end;
+ }
+
+ ret = config_writer_open_element(writer, element_id_tracker);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ ret = config_writer_open_element(writer, config_element_targets);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+
+ if (nr_ids == 0) {
+ /* Tracking none: empty list. */
+ ret = config_writer_open_element(writer, element_target_id);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
- ret = config_writer_open_element(writer,
- config_element_targets);
+ /* /$element_target_id */
+ ret = config_writer_close_element(writer);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
-
- for (i = 0; i < nr_pids; i++) {
- ret = config_writer_open_element(writer,
- config_element_target_pid);
- if (ret) {
+ } else {
+ /* Tracking list. */
+ for (i = 0; i < nr_ids; i++) {
+ switch (ids[i].type) {
+ case LTTNG_ID_VALUE:
+ ret = config_writer_open_element(
+ writer, element_target_id);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ ret = config_writer_write_element_unsigned_int(
+ writer, element_id,
+ ids[i].value);
+ break;
+ case LTTNG_ID_STRING:
+ ret = config_writer_open_element(
+ writer, element_target_id);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
+ ret = config_writer_write_element_string(writer,
+ config_element_name,
+ ids[i].string);
+ break;
+ default:
+ /* Unexpected. */
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
-
- ret = config_writer_write_element_unsigned_int(writer,
- config_element_pid, pids[i]);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
- /* /pid_target */
+ /* /$element_target_id */
ret = config_writer_close_element(writer);
if (ret) {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
}
+ }
- /* /targets */
- ret = config_writer_close_element(writer);
- if (ret) {
- ret = LTTNG_ERR_SAVE_IO_FAIL;
- goto end;
- }
+ /* /targets */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
+ }
- /* /pid_tracker */
- ret = config_writer_close_element(writer);
- if (ret) {
- ret = LTTNG_ERR_SAVE_IO_FAIL;
- goto end;
- }
+ /* /$element_id_tracker */
+ ret = config_writer_close_element(writer);
+ if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
+ goto end;
}
+
+ ret = LTTNG_OK;
end:
- free(pids);
+ free(ids);
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
+static int save_id_trackers(struct config_writer *writer,
+ struct ltt_session *sess,
+ int domain)
+{
+ int ret;
+
+ switch (domain) {
+ case LTTNG_DOMAIN_KERNEL:
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_PID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VPID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_UID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VUID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_GID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VGID);
+ if (ret != LTTNG_OK)
+ return ret;
+ break;
+ case LTTNG_DOMAIN_UST:
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VPID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VUID);
+ if (ret != LTTNG_OK)
+ return ret;
+ ret = save_id_tracker(writer, sess, domain, LTTNG_TRACKER_VGID);
+ if (ret != LTTNG_OK)
+ return ret;
+ break;
+ default:
+ return LTTNG_ERR_INVALID;
+ }
+ return LTTNG_OK;
+}
+
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_ust_domain(struct config_writer *writer,
struct ltt_session *session, enum lttng_domain_type domain)
ust_chan = caa_container_of(node, struct ltt_ust_channel, node);
if (domain == ust_chan->domain) {
ret = save_ust_channel(writer, ust_chan, session->ust_session);
- if (ret) {
+ if (ret != LTTNG_OK) {
rcu_read_unlock();
goto end;
}
goto end;
}
- ret = save_pid_tracker(writer, session, LTTNG_DOMAIN_UST);
- if (ret) {
+ ret = save_id_trackers(writer, session, LTTNG_DOMAIN_UST);
+ if (ret != LTTNG_OK) {
goto end;
}
/* /trackers */
ret = config_writer_close_element(writer);
if (ret) {
+ ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
}
goto end;
}
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_domains(struct config_writer *writer, struct ltt_session *session)
{
- int ret = 0;
+ int ret = LTTNG_OK;
assert(writer);
assert(session);
goto end;
}
-
if (session->kernel_session) {
ret = config_writer_open_element(writer,
config_element_domain);
}
ret = save_kernel_session(writer, session);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
goto end;
}
- ret = save_pid_tracker(writer, session, LTTNG_DOMAIN_KERNEL);
- if (ret) {
+ ret = save_id_trackers(writer, session, LTTNG_DOMAIN_KERNEL);
+ if (ret != LTTNG_OK) {
goto end;
}
if (session->ust_session) {
ret = save_ust_domain(writer, session, LTTNG_DOMAIN_UST);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_ust_domain(writer, session, LTTNG_DOMAIN_JUL);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_ust_domain(writer, session, LTTNG_DOMAIN_LOG4J);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = save_ust_domain(writer, session, LTTNG_DOMAIN_PYTHON);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_consumer_output(struct config_writer *writer,
struct consumer_output *output)
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end_net_output;
}
-
+ ret = LTTNG_OK;
end_net_output:
free(uri);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
} else {
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_snapshot_outputs(struct config_writer *writer,
struct snapshot *snapshot)
}
ret = save_consumer_output(writer, output->consumer);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end_unlock;
}
goto end;
}
+ ret = LTTNG_OK;
end:
return ret;
end_unlock:
return ret;
}
+/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
static
int save_session_output(struct config_writer *writer,
struct ltt_session *session)
if ((session->snapshot_mode && session->snapshot.nb_output == 0) ||
(!session->snapshot_mode && !session->consumer)) {
/* Session is in no output mode */
- ret = 0;
+ ret = LTTNG_OK;
goto end;
}
if (session->snapshot_mode) {
ret = save_snapshot_outputs(writer, &session->snapshot);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
} else {
if (session->consumer) {
ret = save_consumer_output(writer, session->consumer);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+ ret = LTTNG_OK;
end:
return ret;
}
/*
* Save the given session.
*
- * Return 0 on success else a LTTNG_ERR* code.
+ * Return LTTNG_OK on success else a LTTNG_ERR* code.
*/
static
int save_session(struct ltt_session *session,
goto end;
}
- if(session->shm_path[0] != '\0') {
+ if (session->shm_path[0] != '\0') {
ret = config_writer_write_element_string(writer,
config_element_shared_memory_path,
session->shm_path);
}
ret = save_domains(writer, session);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
}
ret = save_session_output(writer, session);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
ret = LTTNG_ERR_SAVE_IO_FAIL;
goto end;
}
+
+ ret = LTTNG_OK;
end:
if (writer && config_writer_destroy(writer)) {
/* Preserve the original error code */
- ret = ret ? ret : LTTNG_ERR_SAVE_IO_FAIL;
+ ret = ret != LTTNG_OK ? ret : LTTNG_ERR_SAVE_IO_FAIL;
}
- if (ret) {
+ if (ret != LTTNG_OK) {
/* Delete file in case of error */
if ((fd >= 0) && unlink(config_file_path)) {
PERROR("Unlinking XML session configuration.");
}
if (fd >= 0) {
- ret = close(fd);
- if (ret) {
+ int closeret;
+
+ closeret = close(fd);
+ if (closeret) {
PERROR("Closing XML session configuration");
}
}
ret = save_session(session, attr, creds);
session_unlock(session);
session_put(session);
- if (ret) {
+ if (ret != LTTNG_OK) {
goto end;
}
} else {
session_unlock(session);
session_put(session);
/* Don't abort if we don't have the required permissions. */
- if (ret && ret != LTTNG_ERR_EPERM) {
+ if (ret != LTTNG_OK && ret != LTTNG_ERR_EPERM) {
goto end;
}
}
lks->metadata = NULL;
CDS_INIT_LIST_HEAD(&lks->channel_list.head);
+ lks->tracker_list_pid = lttng_tracker_list_create();
+ if (!lks->tracker_list_pid) {
+ goto error;
+ }
+ lks->tracker_list_vpid = lttng_tracker_list_create();
+ if (!lks->tracker_list_vpid) {
+ goto error;
+ }
+ lks->tracker_list_uid = lttng_tracker_list_create();
+ if (!lks->tracker_list_uid) {
+ goto error;
+ }
+ lks->tracker_list_vuid = lttng_tracker_list_create();
+ if (!lks->tracker_list_vuid) {
+ goto error;
+ }
+ lks->tracker_list_gid = lttng_tracker_list_create();
+ if (!lks->tracker_list_gid) {
+ goto error;
+ }
+ lks->tracker_list_vgid = lttng_tracker_list_create();
+ if (!lks->tracker_list_vgid) {
+ goto error;
+ }
lks->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
if (lks->consumer == NULL) {
goto error;
return lks;
error:
+ lttng_tracker_list_destroy(lks->tracker_list_pid);
+ lttng_tracker_list_destroy(lks->tracker_list_vpid);
+ lttng_tracker_list_destroy(lks->tracker_list_uid);
+ lttng_tracker_list_destroy(lks->tracker_list_vuid);
+ lttng_tracker_list_destroy(lks->tracker_list_gid);
+ lttng_tracker_list_destroy(lks->tracker_list_vgid);
free(lks);
alloc_error:
/* Wipe consumer output object */
consumer_output_put(session->consumer);
+ lttng_tracker_list_destroy(session->tracker_list_pid);
+ lttng_tracker_list_destroy(session->tracker_list_vpid);
+ lttng_tracker_list_destroy(session->tracker_list_uid);
+ lttng_tracker_list_destroy(session->tracker_list_vuid);
+ lttng_tracker_list_destroy(session->tracker_list_gid);
+ lttng_tracker_list_destroy(session->tracker_list_vgid);
+
free(session);
}
#include <common/defaults.h>
#include "consumer.h"
+#include "tracker.h"
/* Kernel event list */
struct ltt_kernel_event_list {
unsigned int has_non_default_channel;
/* Current trace chunk of the ltt_session. */
struct lttng_trace_chunk *current_trace_chunk;
+ /* Tracker lists */
+ struct lttng_tracker_list *tracker_list_pid;
+ struct lttng_tracker_list *tracker_list_vpid;
+ struct lttng_tracker_list *tracker_list_uid;
+ struct lttng_tracker_list *tracker_list_vuid;
+ struct lttng_tracker_list *tracker_list_gid;
+ struct lttng_tracker_list *tracker_list_vgid;
};
/*
lus = zmalloc(sizeof(struct ltt_ust_session));
if (lus == NULL) {
PERROR("create ust session zmalloc");
- goto error;
+ goto error_alloc;
}
/* Init data structure */
/* Alloc agent hash table. */
lus->agents = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
+ lus->tracker_list_vpid = lttng_tracker_list_create();
+ if (!lus->tracker_list_vpid) {
+ goto error;
+ }
+ lus->tracker_list_vuid = lttng_tracker_list_create();
+ if (!lus->tracker_list_vuid) {
+ goto error;
+ }
+ lus->tracker_list_vgid = lttng_tracker_list_create();
+ if (!lus->tracker_list_vgid) {
+ goto error;
+ }
lus->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
if (lus->consumer == NULL) {
- goto error_consumer;
+ goto error;
}
DBG2("UST trace session create successful");
return lus;
-error_consumer:
+error:
+ lttng_tracker_list_destroy(lus->tracker_list_vpid);
+ lttng_tracker_list_destroy(lus->tracker_list_vuid);
+ lttng_tracker_list_destroy(lus->tracker_list_vgid);
ht_cleanup_push(lus->domain_global.channels);
ht_cleanup_push(lus->agents);
free(lus);
-error:
+error_alloc:
return NULL;
}
return NULL;
}
-static
-void destroy_pid_tracker_node_rcu(struct rcu_head *head)
+static void destroy_id_tracker_node_rcu(struct rcu_head *head)
{
- struct ust_pid_tracker_node *tracker_node =
- caa_container_of(head, struct ust_pid_tracker_node, node.head);
+ struct ust_id_tracker_node *tracker_node = caa_container_of(
+ head, struct ust_id_tracker_node, node.head);
free(tracker_node);
}
-static
-void destroy_pid_tracker_node(struct ust_pid_tracker_node *tracker_node)
+static void destroy_id_tracker_node(struct ust_id_tracker_node *tracker_node)
{
-
- call_rcu(&tracker_node->node.head, destroy_pid_tracker_node_rcu);
+ call_rcu(&tracker_node->node.head, destroy_id_tracker_node_rcu);
}
-static
-int init_pid_tracker(struct ust_pid_tracker *pid_tracker)
+static int init_id_tracker(struct ust_id_tracker *id_tracker)
{
- int ret = 0;
+ int ret = LTTNG_OK;
- pid_tracker->ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
- if (!pid_tracker->ht) {
- ret = -1;
+ id_tracker->ht = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
+ if (!id_tracker->ht) {
+ ret = LTTNG_ERR_NOMEM;
goto end;
}
}
/*
- * Teardown pid tracker content, but don't free pid_tracker object.
+ * Teardown id tracker content, but don't free id_tracker object.
*/
-static
-void fini_pid_tracker(struct ust_pid_tracker *pid_tracker)
+static void fini_id_tracker(struct ust_id_tracker *id_tracker)
{
- struct ust_pid_tracker_node *tracker_node;
+ struct ust_id_tracker_node *tracker_node;
struct lttng_ht_iter iter;
- if (!pid_tracker->ht) {
+ if (!id_tracker->ht) {
return;
}
rcu_read_lock();
- cds_lfht_for_each_entry(pid_tracker->ht->ht,
- &iter.iter, tracker_node, node.node) {
- int ret = lttng_ht_del(pid_tracker->ht, &iter);
+ cds_lfht_for_each_entry (id_tracker->ht->ht, &iter.iter, tracker_node,
+ node.node) {
+ int ret = lttng_ht_del(id_tracker->ht, &iter);
assert(!ret);
- destroy_pid_tracker_node(tracker_node);
+ destroy_id_tracker_node(tracker_node);
}
rcu_read_unlock();
- ht_cleanup_push(pid_tracker->ht);
- pid_tracker->ht = NULL;
+ ht_cleanup_push(id_tracker->ht);
+ id_tracker->ht = NULL;
}
-static
-struct ust_pid_tracker_node *pid_tracker_lookup(
- struct ust_pid_tracker *pid_tracker, int pid,
+static struct ust_id_tracker_node *id_tracker_lookup(
+ struct ust_id_tracker *id_tracker,
+ int id,
struct lttng_ht_iter *iter)
{
- unsigned long _pid = (unsigned long) pid;
+ unsigned long _id = (unsigned long) id;
struct lttng_ht_node_ulong *node;
- lttng_ht_lookup(pid_tracker->ht, (void *) _pid, iter);
+ lttng_ht_lookup(id_tracker->ht, (void *) _id, iter);
node = lttng_ht_iter_get_node_ulong(iter);
if (node) {
- return caa_container_of(node, struct ust_pid_tracker_node,
- node);
+ return caa_container_of(node, struct ust_id_tracker_node, node);
} else {
return NULL;
}
}
-static
-int pid_tracker_add_pid(struct ust_pid_tracker *pid_tracker, int pid)
+static int id_tracker_add_id(struct ust_id_tracker *id_tracker, int id)
{
int retval = LTTNG_OK;
- struct ust_pid_tracker_node *tracker_node;
+ struct ust_id_tracker_node *tracker_node;
struct lttng_ht_iter iter;
- if (pid < 0) {
+ if (id < 0) {
retval = LTTNG_ERR_INVALID;
goto end;
}
- tracker_node = pid_tracker_lookup(pid_tracker, pid, &iter);
+ tracker_node = id_tracker_lookup(id_tracker, id, &iter);
if (tracker_node) {
/* Already exists. */
- retval = LTTNG_ERR_PID_TRACKED;
+ retval = LTTNG_ERR_ID_TRACKED;
goto end;
}
tracker_node = zmalloc(sizeof(*tracker_node));
retval = LTTNG_ERR_NOMEM;
goto end;
}
- lttng_ht_node_init_ulong(&tracker_node->node, (unsigned long) pid);
- lttng_ht_add_unique_ulong(pid_tracker->ht, &tracker_node->node);
+ lttng_ht_node_init_ulong(&tracker_node->node, (unsigned long) id);
+ lttng_ht_add_unique_ulong(id_tracker->ht, &tracker_node->node);
end:
return retval;
}
-static
-int pid_tracker_del_pid(struct ust_pid_tracker *pid_tracker, int pid)
+static int id_tracker_del_id(struct ust_id_tracker *id_tracker, int id)
{
int retval = LTTNG_OK, ret;
- struct ust_pid_tracker_node *tracker_node;
+ struct ust_id_tracker_node *tracker_node;
struct lttng_ht_iter iter;
- if (pid < 0) {
+ if (id < 0) {
retval = LTTNG_ERR_INVALID;
goto end;
}
- tracker_node = pid_tracker_lookup(pid_tracker, pid, &iter);
+ tracker_node = id_tracker_lookup(id_tracker, id, &iter);
if (!tracker_node) {
/* Not found */
- retval = LTTNG_ERR_PID_NOT_TRACKED;
+ retval = LTTNG_ERR_ID_NOT_TRACKED;
goto end;
}
- ret = lttng_ht_del(pid_tracker->ht, &iter);
+ ret = lttng_ht_del(id_tracker->ht, &iter);
assert(!ret);
- destroy_pid_tracker_node(tracker_node);
+ destroy_id_tracker_node(tracker_node);
end:
return retval;
}
+static struct ust_id_tracker *get_id_tracker(struct ltt_ust_session *session,
+ enum lttng_tracker_type tracker_type)
+{
+ switch (tracker_type) {
+ case LTTNG_TRACKER_VPID:
+ return &session->vpid_tracker;
+ case LTTNG_TRACKER_VUID:
+ return &session->vuid_tracker;
+ case LTTNG_TRACKER_VGID:
+ return &session->vgid_tracker;
+ default:
+ return NULL;
+ }
+}
+
+static struct lttng_tracker_list *get_id_tracker_list(
+ struct ltt_ust_session *session,
+ enum lttng_tracker_type tracker_type)
+{
+ switch (tracker_type) {
+ case LTTNG_TRACKER_VPID:
+ return session->tracker_list_vpid;
+ case LTTNG_TRACKER_VUID:
+ return session->tracker_list_vuid;
+ case LTTNG_TRACKER_VGID:
+ return session->tracker_list_vgid;
+ default:
+ return NULL;
+ }
+}
+
/*
* The session lock is held when calling this function.
*/
-int trace_ust_pid_tracker_lookup(struct ltt_ust_session *session, int pid)
+int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ int id)
{
struct lttng_ht_iter iter;
+ struct ust_id_tracker *id_tracker;
- if (!session->pid_tracker.ht) {
+ id_tracker = get_id_tracker(session, tracker_type);
+ if (!id_tracker) {
+ abort();
+ }
+ if (!id_tracker->ht) {
return 1;
}
- if (pid_tracker_lookup(&session->pid_tracker, pid, &iter)) {
+ if (id_tracker_lookup(id_tracker, id, &iter)) {
return 1;
}
return 0;
/*
* Called with the session lock held.
*/
-int trace_ust_track_pid(struct ltt_ust_session *session, int pid)
+int trace_ust_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ const struct lttng_tracker_id *id)
{
int retval = LTTNG_OK;
bool should_update_apps = false;
+ 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;
+
+ if (tracker_type == LTTNG_TRACKER_PID) {
+ DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
+ tracker_type = LTTNG_TRACKER_VPID;
+ }
- if (pid == -1) {
- /* Track all pids: destroy tracker if exists. */
- if (session->pid_tracker.ht) {
- fini_pid_tracker(&session->pid_tracker);
+ retval = lttng_tracker_id_lookup_string(tracker_type, id, &value);
+ if (retval != LTTNG_OK) {
+ return retval;
+ }
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return LTTNG_ERR_INVALID;
+ }
+ /* Save list for restore on error. */
+ saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids);
+ if (saved_ids_count < 0) {
+ return LTTNG_ERR_INVALID;
+ }
+ /* Add to list. */
+ retval = lttng_tracker_list_add(tracker_list, id);
+ if (retval != LTTNG_OK) {
+ goto end;
+ }
+
+ id_tracker = get_id_tracker(session, tracker_type);
+ if (!id_tracker) {
+ abort();
+ }
+ if (value == -1) {
+ /* Track all ids: destroy tracker if exists. */
+ if (id_tracker->ht) {
+ fini_id_tracker(id_tracker);
/* Ensure all apps have session. */
should_update_apps = true;
}
} else {
- int ret;
-
- if (!session->pid_tracker.ht) {
+ if (!id_tracker->ht) {
/* Create tracker. */
- if (init_pid_tracker(&session->pid_tracker)) {
- ERR("Error initializing PID tracker");
- retval = LTTNG_ERR_NOMEM;
- goto end;
+ retval = init_id_tracker(id_tracker);
+ if (retval != LTTNG_OK) {
+ ERR("Error initializing ID tracker");
+ goto end_restore;
}
- ret = pid_tracker_add_pid(&session->pid_tracker, pid);
- if (ret != LTTNG_OK) {
- retval = ret;
- fini_pid_tracker(&session->pid_tracker);
- goto end;
+ retval = id_tracker_add_id(id_tracker, value);
+ if (retval != LTTNG_OK) {
+ fini_id_tracker(id_tracker);
+ goto end_restore;
}
/* Remove all apps from session except pid. */
should_update_apps = true;
} else {
struct ust_app *app;
- ret = pid_tracker_add_pid(&session->pid_tracker, pid);
- if (ret != LTTNG_OK) {
- retval = ret;
- goto end;
+ retval = id_tracker_add_id(id_tracker, value);
+ if (retval != LTTNG_OK) {
+ goto end_restore;
}
/* Add session to application */
- app = ust_app_find_by_pid(pid);
- if (app) {
+ switch (tracker_type) {
+ case LTTNG_TRACKER_VPID:
+ app = ust_app_find_by_pid(value);
+ if (app) {
+ should_update_apps = true;
+ }
+ break;
+ default:
should_update_apps = true;
}
}
if (should_update_apps && session->active) {
ust_app_global_update_all(session);
}
+ goto end;
+
+end_restore:
+ if (lttng_tracker_id_set_list(tracker_list, saved_ids,
+ saved_ids_count) != LTTNG_OK) {
+ ERR("Error on tracker add error handling.\n");
+ }
end:
+ for (i = 0; i < saved_ids_count; i++) {
+ free(saved_ids[i].string);
+ }
+ free(saved_ids);
return retval;
}
/*
* Called with the session lock held.
*/
-int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid)
+int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ const struct lttng_tracker_id *id)
{
int retval = LTTNG_OK;
bool should_update_apps = false;
+ 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;
+
+ if (tracker_type == LTTNG_TRACKER_PID) {
+ DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
+ tracker_type = LTTNG_TRACKER_VPID;
+ }
+
+ retval = lttng_tracker_id_lookup_string(tracker_type, id, &value);
+ if (retval != LTTNG_OK) {
+ return retval;
+ }
+
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return LTTNG_ERR_INVALID;
+ }
+ /* Save list for restore on error. */
+ saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids);
+ if (saved_ids_count < 0) {
+ return LTTNG_ERR_INVALID;
+ }
+ /* Remove from list. */
+ retval = lttng_tracker_list_remove(tracker_list, id);
+ if (retval != LTTNG_OK) {
+ goto end;
+ }
- if (pid == -1) {
+ id_tracker = get_id_tracker(session, tracker_type);
+ if (!id_tracker) {
+ abort();
+ }
+
+ if (value == -1) {
/* Create empty tracker, replace old tracker. */
- struct ust_pid_tracker tmp_tracker;
+ struct ust_id_tracker tmp_tracker;
- tmp_tracker = session->pid_tracker;
- if (init_pid_tracker(&session->pid_tracker)) {
- ERR("Error initializing PID tracker");
- retval = LTTNG_ERR_NOMEM;
+ tmp_tracker = *id_tracker;
+ retval = init_id_tracker(id_tracker);
+ if (retval != LTTNG_OK) {
+ ERR("Error initializing ID tracker");
/* Rollback operation. */
- session->pid_tracker = tmp_tracker;
- goto end;
+ *id_tracker = tmp_tracker;
+ goto end_restore;
}
- fini_pid_tracker(&tmp_tracker);
+ fini_id_tracker(&tmp_tracker);
/* Remove session from all applications */
should_update_apps = true;
} else {
- int ret;
struct ust_app *app;
- if (!session->pid_tracker.ht) {
- /* No PID being tracked. */
- retval = LTTNG_ERR_PID_NOT_TRACKED;
- goto end;
+ if (!id_tracker->ht) {
+ /* No ID being tracked. */
+ retval = LTTNG_ERR_ID_NOT_TRACKED;
+ goto end_restore;
}
- /* Remove PID from tracker */
- ret = pid_tracker_del_pid(&session->pid_tracker, pid);
- if (ret != LTTNG_OK) {
- retval = ret;
- goto end;
+ /* Remove ID from tracker */
+ retval = id_tracker_del_id(id_tracker, value);
+ if (retval != LTTNG_OK) {
+ goto end_restore;
}
- /* Remove session from application. */
- app = ust_app_find_by_pid(pid);
- if (app) {
+ switch (tracker_type) {
+ case LTTNG_TRACKER_VPID:
+ /* Remove session from application. */
+ app = ust_app_find_by_pid(value);
+ if (app) {
+ should_update_apps = true;
+ }
+ break;
+ default:
+ /* Keep only apps matching ID. */
should_update_apps = true;
}
}
if (should_update_apps && session->active) {
ust_app_global_update_all(session);
}
+ goto end;
+
+end_restore:
+ if (lttng_tracker_id_set_list(tracker_list, saved_ids,
+ saved_ids_count) != LTTNG_OK) {
+ ERR("Error on tracker remove error handling.\n");
+ }
end:
+ for (i = 0; i < saved_ids_count; i++) {
+ free(saved_ids[i].string);
+ }
+ free(saved_ids);
return retval;
}
/*
* Called with session lock held.
*/
-ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session,
- int32_t **_pids)
+ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ struct lttng_tracker_id **_ids)
{
- struct ust_pid_tracker_node *tracker_node;
- struct lttng_ht_iter iter;
- unsigned long count, i = 0;
- long approx[2];
- int32_t *pids;
- int ret = 0;
+ struct lttng_tracker_list *tracker_list;
- if (!session->pid_tracker.ht) {
- /* Tracker disabled. Set first entry to -1. */
- pids = zmalloc(sizeof(*pids));
- if (!pids) {
- ret = -1;
- goto end;
- }
- pids[0] = -1;
- *_pids = pids;
- return 1;
+ if (tracker_type == LTTNG_TRACKER_PID) {
+ DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain.");
+ tracker_type = LTTNG_TRACKER_VPID;
}
- rcu_read_lock();
- cds_lfht_count_nodes(session->pid_tracker.ht->ht,
- &approx[0], &count, &approx[1]);
- pids = zmalloc(sizeof(*pids) * count);
- if (!pids) {
- ret = -1;
- goto end;
- }
- cds_lfht_for_each_entry(session->pid_tracker.ht->ht,
- &iter.iter, tracker_node, node.node) {
- pids[i++] = tracker_node->node.key;
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return -LTTNG_ERR_INVALID;
}
- *_pids = pids;
- ret = count;
-end:
- rcu_read_unlock();
- return ret;
+ return lttng_tracker_id_get_list(tracker_list, _ids);
}
/*
buffer_reg_uid_destroy(reg, session->consumer);
}
- fini_pid_tracker(&session->pid_tracker);
+ lttng_tracker_list_destroy(session->tracker_list_vpid);
+ lttng_tracker_list_destroy(session->tracker_list_vuid);
+ lttng_tracker_list_destroy(session->tracker_list_vgid);
+
+ fini_id_tracker(&session->vpid_tracker);
+ fini_id_tracker(&session->vuid_tracker);
+ fini_id_tracker(&session->vgid_tracker);
lttng_trace_chunk_put(session->current_trace_chunk);
}
struct cds_list_head registry_buffer_uid_list;
};
-struct ust_pid_tracker_node {
+struct ust_id_tracker_node {
struct lttng_ht_node_ulong node;
};
-struct ust_pid_tracker {
+struct ust_id_tracker {
struct lttng_ht *ht;
};
char root_shm_path[PATH_MAX];
char shm_path[PATH_MAX];
- struct ust_pid_tracker pid_tracker;
-
/* Current trace chunk of the ltt_session. */
struct lttng_trace_chunk *current_trace_chunk;
+
+ /* Trackers used for actual lookup on app registration. */
+ struct ust_id_tracker vpid_tracker;
+ struct ust_id_tracker vuid_tracker;
+ struct ust_id_tracker vgid_tracker;
+
+ /* Tracker list of keys requested by users. */
+ struct lttng_tracker_list *tracker_list_vpid;
+ struct lttng_tracker_list *tracker_list_vuid;
+ struct lttng_tracker_list *tracker_list_vgid;
};
/*
void trace_ust_destroy_context(struct ltt_ust_context *ctx);
void trace_ust_free_session(struct ltt_ust_session *session);
-int trace_ust_track_pid(struct ltt_ust_session *session, int pid);
-int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid);
+int trace_ust_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ const struct lttng_tracker_id *id);
+int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ const struct lttng_tracker_id *id);
-int trace_ust_pid_tracker_lookup(struct ltt_ust_session *session, int pid);
+int trace_ust_id_tracker_lookup(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ int id);
-ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session,
- int32_t **_pids);
+ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ struct lttng_tracker_id **_ids);
#else /* HAVE_LIBLTTNG_UST_CTL */
{
return NULL;
}
-static inline
-int trace_ust_track_pid(struct ltt_ust_session *session, int pid)
+static inline int trace_ust_track_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ const struct lttng_tracker_id *id);
{
return 0;
}
-static inline
-int trace_ust_untrack_pid(struct ltt_ust_session *session, int pid)
+static inline int trace_ust_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ const struct lttng_tracker_id *id)
{
return 0;
}
-static inline
-int trace_ust_pid_tracker_lookup(struct ltt_ust_session *session, int pid)
+static inline int trace_ust_id_tracker_lookup(
+ enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ int pid)
{
return 0;
}
-static inline
-ssize_t trace_ust_list_tracker_pids(struct ltt_ust_session *session,
- int32_t **_pids)
+static inline ssize_t trace_ust_list_tracker_ids(
+ enum lttng_tracker_type tracker_type,
+ struct ltt_ust_session *session,
+ struct lttng_tracker_id **_ids)
{
return -1;
}
cds_lfht_for_each_entry(ust_app_ht->ht, &iter, app, pid_n.node) {
struct ust_app_session *ua_sess;
int session_was_created = 0;
-
- if (!app->compatible ||
- !trace_ust_pid_tracker_lookup(usess, app->pid)) {
+ bool present_in_tracker =
+ trace_ust_id_tracker_lookup(LTTNG_TRACKER_VPID,
+ usess, app->pid) &&
+ trace_ust_id_tracker_lookup(LTTNG_TRACKER_VUID,
+ usess, app->uid) &&
+ trace_ust_id_tracker_lookup(LTTNG_TRACKER_VGID,
+ usess, app->gid);
+
+ if (!app->compatible || !(present_in_tracker)) {
+ /*
+ * This is probably an error this MUST BE TESTED
+ * Introduced by
+ * 88e3c2f5610b9ac89b0923d448fee34140fc46fb On app not
+ * in tracker we should skip it. not sure what to do on
+ * app !compatible
+ */
goto error_rcu_unlock;
}
if (!app->compatible) {
return;
}
- if (trace_ust_pid_tracker_lookup(usess, app->pid)) {
+ if (trace_ust_id_tracker_lookup(LTTNG_TRACKER_VPID, usess, app->pid) &&
+ trace_ust_id_tracker_lookup(
+ LTTNG_TRACKER_VUID, usess, app->uid) &&
+ trace_ust_id_tracker_lookup(
+ LTTNG_TRACKER_VGID, usess, app->gid)) {
/*
* Synchronize the application's internal tracing configuration
* and start tracing.
#ifndef CONFIG_SESSION_INTERNAL_H
#define CONFIG_SESSION_INTERNAL_H
+extern const char * const config_element_all;
extern const char * const config_element_channel;
extern const char * const config_element_channels;
extern const char * const config_element_domain;
extern const char * const config_element_data_uri;
extern const char * const config_element_max_size;
extern const char * const config_element_pid;
+extern const char * const config_element_id;
extern const char * const config_element_pids;
+extern const char * const config_element_name;
extern const char * const config_element_shared_memory_path;
extern const char * const config_element_pid_tracker;
+extern const char * const config_element_vpid_tracker;
+extern const char * const config_element_uid_tracker;
+extern const char * const config_element_vuid_tracker;
+extern const char * const config_element_gid_tracker;
+extern const char * const config_element_vgid_tracker;
extern const char * const config_element_trackers;
extern const char * const config_element_targets;
+extern const char * const config_element_target_type;
extern const char * const config_element_target_pid;
+extern const char * const config_element_target_vpid;
+extern const char * const config_element_target_uid;
+extern const char * const config_element_target_vuid;
+extern const char * const config_element_target_gid;
+extern const char * const config_element_target_vgid;
+extern const char * const config_element_tracker_type;
extern const char * const config_element_rotation_timer_interval;
extern const char * const config_element_rotation_size;
extern const char * const config_element_rotation_schedule;
xmlSchemaValidCtxtPtr schema_validation_ctx;
};
+const char * const config_element_all = "all";
const char * const config_str_yes = "yes";
const char * const config_str_true = "true";
const char * const config_str_on = "on";
const char * const config_element_data_uri = "data_uri";
const char * const config_element_max_size = "max_size";
const char * const config_element_pid = "pid";
+const char * const config_element_id = "id";
const char * const config_element_pids = "pids";
const char * const config_element_shared_memory_path = "shared_memory_path";
const char * const config_element_pid_tracker = "pid_tracker";
+const char * const config_element_vpid_tracker = "vpid_tracker";
+const char * const config_element_uid_tracker = "uid_tracker";
+const char * const config_element_vuid_tracker = "vuid_tracker";
+const char * const config_element_gid_tracker = "gid_tracker";
+const char * const config_element_vgid_tracker = "vgid_tracker";
const char * const config_element_trackers = "trackers";
const char * const config_element_targets = "targets";
+const char * const config_element_target_type = "target_type";
const char * const config_element_target_pid = "pid_target";
+const char * const config_element_target_vpid = "vpid_target";
+const char * const config_element_target_uid = "uid_target";
+const char * const config_element_target_vuid = "vuid_target";
+const char * const config_element_target_gid = "gid_target";
+const char * const config_element_target_vgid = "vgid_target";
+const char * const config_element_tracker_type = "tracker_type";
LTTNG_HIDDEN const char * const config_element_rotation_schedules = "rotation_schedules";
LTTNG_HIDDEN const char * const config_element_rotation_schedule_periodic = "periodic";
return ret;
}
-static
-int process_pid_tracker_node(xmlNodePtr pid_tracker_node,
- struct lttng_handle *handle)
+static int get_tracker_elements(enum lttng_tracker_type tracker_type,
+ const char **element_id_tracker,
+ const char **element_target_id,
+ const char **element_id,
+ const char **element_id_alias,
+ const char **element_name)
+{
+ int ret = 0;
+
+ switch (tracker_type) {
+ case LTTNG_TRACKER_PID:
+ *element_id_tracker = config_element_pid_tracker;
+ *element_target_id = config_element_target_pid;
+ *element_id = config_element_id;
+ *element_id_alias = config_element_pid;
+ *element_name = NULL;
+ break;
+ case LTTNG_TRACKER_VPID:
+ *element_id_tracker = config_element_vpid_tracker;
+ *element_target_id = config_element_target_vpid;
+ *element_id = config_element_id;
+ *element_id_alias = NULL;
+ *element_name = NULL;
+ break;
+ case LTTNG_TRACKER_UID:
+ *element_id_tracker = config_element_uid_tracker;
+ *element_target_id = config_element_target_uid;
+ *element_id = config_element_id;
+ *element_id_alias = NULL;
+ *element_name = config_element_name;
+ break;
+ case LTTNG_TRACKER_VUID:
+ *element_id_tracker = config_element_vuid_tracker;
+ *element_target_id = config_element_target_vuid;
+ *element_id = config_element_id;
+ *element_id_alias = NULL;
+ *element_name = config_element_name;
+ break;
+ case LTTNG_TRACKER_GID:
+ *element_id_tracker = config_element_gid_tracker;
+ *element_target_id = config_element_target_gid;
+ *element_id = config_element_id;
+ *element_id_alias = NULL;
+ *element_name = config_element_name;
+ break;
+ case LTTNG_TRACKER_VGID:
+ *element_id_tracker = config_element_vgid_tracker;
+ *element_target_id = config_element_target_vgid;
+ *element_id = config_element_id;
+ *element_id_alias = NULL;
+ *element_name = config_element_name;
+ break;
+ default:
+ ret = LTTNG_ERR_INVALID;
+ }
+ return ret;
+}
+
+static int process_id_tracker_node(xmlNodePtr id_tracker_node,
+ struct lttng_handle *handle,
+ enum lttng_tracker_type tracker_type)
{
int ret = 0, child;
xmlNodePtr targets_node = NULL;
xmlNodePtr node;
+ const char *element_id_tracker;
+ const char *element_target_id;
+ const char *element_id;
+ const char *element_id_alias;
+ const char *element_name;
assert(handle);
- assert(pid_tracker_node);
+ assert(id_tracker_node);
+
+ ret = get_tracker_elements(tracker_type, &element_id_tracker,
+ &element_target_id, &element_id, &element_id_alias,
+ &element_name);
+ if (ret) {
+ return ret;
+ }
+
/* get the targets node */
- for (node = xmlFirstElementChild(pid_tracker_node); node;
- node = xmlNextElementSibling(node)) {
+ for (node = xmlFirstElementChild(id_tracker_node); node;
+ node = xmlNextElementSibling(node)) {
if (!strcmp((const char *) node->name,
config_element_targets)) {
targets_node = node;
goto end;
}
- /* Go through all pid_target node */
+ /* Go through all id target node */
child = xmlChildElementCount(targets_node);
if (child == 0) {
+ struct lttng_tracker_id tracker_id;
+
+ tracker_id.type = LTTNG_ID_ALL;
/* The session is explicitly set to target nothing. */
- ret = lttng_untrack_pid(handle, -1);
+ ret = lttng_untrack_id(handle, tracker_type, &tracker_id);
if (ret) {
goto end;
}
}
for (node = xmlFirstElementChild(targets_node); node;
node = xmlNextElementSibling(node)) {
- xmlNodePtr pid_target_node = node;
+ xmlNodePtr id_target_node = node;
- /* get pid node and track it */
- for (node = xmlFirstElementChild(pid_target_node); node;
- node = xmlNextElementSibling(node)) {
- if (!strcmp((const char *) node->name,
- config_element_pid)) {
- int64_t pid;
+ /* get id node and track it */
+ for (node = xmlFirstElementChild(id_target_node); node;
+ node = xmlNextElementSibling(node)) {
+ if (!strcmp((const char *) node->name, element_id) ||
+ (element_id_alias &&
+ !strcmp((const char *) node->name,
+ element_id_alias))) {
+ int64_t id;
xmlChar *content = NULL;
+ struct lttng_tracker_id tracker_id;
content = xmlNodeGetContent(node);
if (!content) {
goto end;
}
- ret = parse_int(content, &pid);
+ ret = parse_int(content, &id);
free(content);
if (ret) {
ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
goto end;
}
- ret = lttng_track_pid(handle, (int) pid);
+ tracker_id.type = LTTNG_ID_VALUE;
+ tracker_id.value = (int) id;
+ ret = lttng_track_id(handle, tracker_type,
+ &tracker_id);
+ if (ret) {
+ goto end;
+ }
+ }
+ if (element_name && !strcmp((const char *) node->name,
+ element_name)) {
+ xmlChar *content = NULL;
+ struct lttng_tracker_id tracker_id;
+
+ content = xmlNodeGetContent(node);
+ if (!content) {
+ ret = LTTNG_ERR_LOAD_INVALID_CONFIG;
+ goto end;
+ }
+ tracker_id.type = LTTNG_ID_STRING;
+ tracker_id.string = (char *) content;
+ ret = lttng_track_id(handle, tracker_type,
+ &tracker_id);
+ free(content);
if (ret) {
goto end;
}
}
}
- node = pid_target_node;
+ node = id_target_node;
}
end:
xmlNodePtr channels_node = NULL;
xmlNodePtr trackers_node = NULL;
xmlNodePtr pid_tracker_node = NULL;
+ xmlNodePtr vpid_tracker_node = NULL;
+ xmlNodePtr uid_tracker_node = NULL;
+ xmlNodePtr vuid_tracker_node = NULL;
+ xmlNodePtr gid_tracker_node = NULL;
+ xmlNodePtr vgid_tracker_node = NULL;
xmlNodePtr node;
assert(session_name);
for (node = xmlFirstElementChild(trackers_node); node;
node = xmlNextElementSibling(node)) {
- if (!strcmp((const char *)node->name,config_element_pid_tracker)) {
+ if (!strcmp((const char *) node->name,
+ config_element_pid_tracker)) {
pid_tracker_node = node;
- ret = process_pid_tracker_node(pid_tracker_node, handle);
+ ret = process_id_tracker_node(pid_tracker_node, handle,
+ LTTNG_TRACKER_PID);
+ if (ret) {
+ goto end;
+ }
+ }
+ if (!strcmp((const char *) node->name,
+ config_element_vpid_tracker)) {
+ vpid_tracker_node = node;
+ ret = process_id_tracker_node(vpid_tracker_node, handle,
+ LTTNG_TRACKER_VPID);
+ if (ret) {
+ goto end;
+ }
+ }
+ if (!strcmp((const char *) node->name,
+ config_element_uid_tracker)) {
+ uid_tracker_node = node;
+ ret = process_id_tracker_node(uid_tracker_node, handle,
+ LTTNG_TRACKER_UID);
+ if (ret) {
+ goto end;
+ }
+ }
+ if (!strcmp((const char *) node->name,
+ config_element_vuid_tracker)) {
+ vuid_tracker_node = node;
+ ret = process_id_tracker_node(vuid_tracker_node, handle,
+ LTTNG_TRACKER_VUID);
+ if (ret) {
+ goto end;
+ }
+ }
+ if (!strcmp((const char *) node->name,
+ config_element_gid_tracker)) {
+ gid_tracker_node = node;
+ ret = process_id_tracker_node(gid_tracker_node, handle,
+ LTTNG_TRACKER_GID);
+ if (ret) {
+ goto end;
+ }
+ }
+ if (!strcmp((const char *) node->name,
+ config_element_vgid_tracker)) {
+ vgid_tracker_node = node;
+ ret = process_id_tracker_node(vgid_tracker_node, handle,
+ LTTNG_TRACKER_VGID);
if (ret) {
goto end;
}
}
- }
-
- if (!pid_tracker_node) {
- lttng_track_pid(handle, -1);
}
end:
sessions_node = xmlDocGetRootElement(doc);
if (!sessions_node) {
+ ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
goto end;
}
if (!ret) {
ret = session_found ? 0 : -LTTNG_ERR_LOAD_SESSION_NOENT;
}
+ if (ret == -LTTNG_ERR_NO_SESSION) {
+ ret = -LTTNG_ERR_LOAD_SESSION_NOENT;
+ }
return ret;
}
ret = load_session_from_file(file_path.data, session_name,
validation_ctx, overwrite, overrides);
- if (session_name && !ret) {
+ if (session_name &&
+ (!ret || ret != -LTTNG_ERR_LOAD_SESSION_NOENT)) {
session_found = 1;
break;
}
+ if (ret && ret != -LTTNG_ERR_LOAD_SESSION_NOENT) {
+ goto end;
+ }
/*
* Reset the buffer's size to the location of the
* path's trailing '/'.
goto end;
}
}
-
} else {
ret = load_session_from_file(path, session_name,
validation_ctx, overwrite, overrides);
if (ret) {
goto end;
- } else {
- session_found = 1;
}
+ session_found = 1;
}
+ ret = 0;
end:
if (directory) {
if (closedir(directory)) {
PERROR("closedir");
}
}
- if (session_found && !ret) {
- ret = 0;
+ if (!ret && !session_found) {
+ ret = -LTTNG_ERR_LOAD_SESSION_NOENT;
}
lttng_dynamic_buffer_reset(&file_path);
return ret;
DEFAULT_SESSION_CONFIG_AUTOLOAD, home_path);
if (ret < 0) {
PERROR("snprintf session autoload home config path");
+ ret = -LTTNG_ERR_INVALID;
goto end;
}
DEFAULT_SESSION_HOME_CONFIGPATH, home_path);
if (ret < 0) {
PERROR("snprintf session home config path");
+ ret = -LTTNG_ERR_INVALID;
goto end;
}
path_ptr = path;
if (!ret) {
session_loaded = true;
}
+ } else {
+ ret = 0;
}
} else {
ret = access(path, F_OK);
</xs:complexType>
<xs:complexType name="pid_target_type">
- <xs:all>
+ <xs:choice minOccurs="0">
<xs:element name="pid" type="xs:integer" />
- </xs:all>
+ <xs:element name="id" type="xs:integer" />
+ </xs:choice>
</xs:complexType>
<!-- Maps to a list of pid_targets-->
-<xs:complexType name="targets_type">
+<xs:complexType name="pid_targets_type">
<xs:sequence>
- <xs:choice>
- <xs:element name="pid_target" type="pid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ <xs:choice minOccurs="0" maxOccurs="unbounded" >
+ <xs:element name="pid_target" type="pid_target_type" />
</xs:choice>
</xs:sequence>
</xs:complexType>
<!-- Maps to a pid_tracker-->
<xs:complexType name="pid_tracker_type">
<xs:all>
- <xs:element name="targets" type="targets_type" />
+ <xs:element name="targets" type="pid_targets_type" />
+ </xs:all>
+</xs:complexType>
+
+<xs:complexType name="vpid_target_type">
+ <xs:all>
+ <xs:element name="id" type="xs:integer" />
+ </xs:all>
+</xs:complexType>
+
+<!-- Maps to a list of vpid_targets-->
+<xs:complexType name="vpid_targets_type">
+ <xs:sequence>
+ <xs:element name="vpid_target" type="vpid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+</xs:complexType>
+
+<!-- Maps to a pid_tracker-->
+<xs:complexType name="vpid_tracker_type">
+ <xs:all>
+ <xs:element name="targets" type="vpid_targets_type" />
+ </xs:all>
+</xs:complexType>
+
+<xs:complexType name="uid_target_type">
+ <xs:choice>
+ <xs:element name="id" type="xs:integer" />
+ <xs:element name="name" type="xs:string" />
+ </xs:choice>
+</xs:complexType>
+
+<!-- Maps to a list of uid_targets-->
+<xs:complexType name="uid_targets_type">
+ <xs:sequence>
+ <xs:element name="uid_target" type="uid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+</xs:complexType>
+
+<!-- Maps to a uid_tracker-->
+<xs:complexType name="uid_tracker_type">
+ <xs:all>
+ <xs:element name="targets" type="uid_targets_type" />
+ </xs:all>
+</xs:complexType>
+
+<xs:complexType name="vuid_target_type">
+ <xs:choice>
+ <xs:element name="id" type="xs:integer" />
+ <xs:element name="name" type="xs:string" />
+ </xs:choice>
+</xs:complexType>
+
+<!-- Maps to a list of vuid_targets-->
+<xs:complexType name="vuid_targets_type">
+ <xs:sequence>
+ <xs:element name="vuid_target" type="vuid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+</xs:complexType>
+
+<!-- Maps to a uid_tracker-->
+<xs:complexType name="vuid_tracker_type">
+ <xs:all>
+ <xs:element name="targets" type="vuid_targets_type" />
+ </xs:all>
+</xs:complexType>
+
+<xs:complexType name="gid_target_type">
+ <xs:choice>
+ <xs:element name="id" type="xs:integer" />
+ <xs:element name="name" type="xs:string" />
+ </xs:choice>
+</xs:complexType>
+
+<!-- Maps to a list of gid_targets-->
+<xs:complexType name="gid_targets_type">
+ <xs:sequence>
+ <xs:element name="gid_target" type="gid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+</xs:complexType>
+
+<!-- Maps to a gid_tracker-->
+<xs:complexType name="gid_tracker_type">
+ <xs:all>
+ <xs:element name="targets" type="gid_targets_type" />
+ </xs:all>
+</xs:complexType>
+
+<xs:complexType name="vgid_target_type">
+ <xs:choice>
+ <xs:element name="id" type="xs:integer" />
+ <xs:element name="name" type="xs:string" />
+ </xs:choice>
+</xs:complexType>
+
+<!-- Maps to a list of vgid_targets-->
+<xs:complexType name="vgid_targets_type">
+ <xs:sequence>
+ <xs:element name="vgid_target" type="vgid_target_type" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+</xs:complexType>
+
+<!-- Maps to a gid_tracker-->
+<xs:complexType name="vgid_tracker_type">
+ <xs:all>
+ <xs:element name="targets" type="vgid_targets_type" />
</xs:all>
</xs:complexType>
<!-- Maps to a list of trackers-->
<xs:complexType name="trackers_type">
- <xs:sequence minOccurs="0" maxOccurs="unbounded">
- <xs:element name="pid_tracker" type="pid_tracker_type" maxOccurs="1" />
+ <xs:sequence>
+ <xs:choice minOccurs="0" maxOccurs="unbounded" >
+ <xs:element name="pid_tracker" type="pid_tracker_type" maxOccurs="1" />
+ <xs:element name="vpid_tracker" type="vpid_tracker_type" maxOccurs="1" />
+ <xs:element name="uid_tracker" type="uid_tracker_type" maxOccurs="1" />
+ <xs:element name="vuid_tracker" type="vuid_tracker_type" maxOccurs="1" />
+ <xs:element name="gid_tracker" type="gid_tracker_type" maxOccurs="1" />
+ <xs:element name="vgid_tracker" type="vgid_tracker_type" maxOccurs="1" />
+ </xs:choice>
</xs:sequence>
</xs:complexType>
/* 29 */
/* 30 */
LTTNG_SAVE_SESSION = 31,
- LTTNG_TRACK_PID = 32,
- LTTNG_UNTRACK_PID = 33,
- LTTNG_LIST_TRACKER_PIDS = 34,
+ LTTNG_TRACK_ID = 32,
+ LTTNG_UNTRACK_ID = 33,
+ LTTNG_LIST_TRACKER_IDS = 34,
LTTNG_SET_SESSION_SHM_PATH = 40,
LTTNG_REGENERATE_METADATA = 41,
LTTNG_REGENERATE_STATEDUMP = 42,
char shm_path[PATH_MAX];
} LTTNG_PACKED set_shm_path;
struct {
- uint32_t pid;
- } LTTNG_PACKED pid_tracker;
+ uint32_t tracker_type; /* enum lttng_tracker_type */
+ uint32_t id_type; /* enum lttng_tracker_id_type */
+ union {
+ int32_t value;
+ uint32_t var_len;
+ } u;
+ /*
+ * for LTTNG_ID_STRING, followed by a variable length
+ * zero-terminated string of length "var_len", which
+ * includes the final \0.
+ */
+ } LTTNG_PACKED id_tracker;
+ struct {
+ uint32_t tracker_type; /* enum lttng_tracker_type */
+ } LTTNG_PACKED id_tracker_list;
struct {
uint32_t length;
} LTTNG_PACKED trigger;
int32_t rotation_state;
};
+/*
+ * tracker command header.
+ */
+struct lttcomm_tracker_command_header {
+ uint32_t nb_tracker_id;
+} LTTNG_PACKED;
+
+struct lttcomm_tracker_id_header {
+ uint32_t type; /* enum lttng_tracker_id_type */
+ union {
+ int32_t value;
+ uint32_t var_data_len;
+ } u;
+} LTTNG_PACKED;
+
/*
* Data structure for the response from sessiond to the lttng client.
*/
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,
+ 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) {
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;
+ }
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(&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,
+ const 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,
+ const 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;
- COPY_DOMAIN_PACKED(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);
}
/*
/* 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 end;
}
free(cmd_header);
}
/*
- * List PIDs in the tracker.
+ * List IDs 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.
+ * 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_pids(struct lttng_handle *handle,
- int *_enabled, int32_t **_pids, size_t *_nr_pids)
+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;
- int enabled = 1;
+ int ret, i;
struct lttcomm_session_msg lsm;
- size_t nr_pids;
- int32_t *pids = NULL;
+ 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_PIDS;
+ 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));
COPY_DOMAIN_PACKED(lsm.domain, handle->domain);
- ret = lttng_ctl_ask_sessiond(&lsm, (void **) &pids);
+ ret = lttng_ctl_ask_sessiond_fds_varlen(&lsm, NULL, 0, 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.
+ *
+ * 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.
+ */
+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;
}
- nr_pids = ret / sizeof(int32_t);
- if (nr_pids > 0 && !pids) {
- return -LTTNG_ERR_UNK;
+ *_enabled = 1;
+
+ pids = zmalloc(nr_ids * sizeof(*pids));
+ if (!pids) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto end;
}
- if (nr_pids == 1 && pids[0] == -1) {
- free(pids);
- pids = NULL;
- enabled = 0;
- nr_pids = 0;
+ 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;
}
- *_enabled = enabled;
*_pids = pids;
- *_nr_pids = nr_pids;
- return 0;
+ *_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;
}
/*
$(top_builddir)/src/bin/lttng-sessiond/notify-apps.$(OBJEXT) \
$(top_builddir)/src/bin/lttng-sessiond/ust-metadata.$(OBJEXT) \
$(top_builddir)/src/bin/lttng-sessiond/agent-thread.$(OBJEXT) \
- $(top_builddir)/src/bin/lttng-sessiond/ust-field-utils.$(OBJEXT)
+ $(top_builddir)/src/bin/lttng-sessiond/ust-field-utils.$(OBJEXT) \
+ $(top_builddir)/src/bin/lttng-sessiond/tracker.$(OBJEXT)
endif
RELAYD_OBJS = $(top_builddir)/src/bin/lttng-relayd/backward-compatibility-group-by.$(OBJEXT)
$(top_builddir)/src/bin/lttng-sessiond/consumer.$(OBJEXT) \
$(top_builddir)/src/bin/lttng-sessiond/globals.$(OBJEXT) \
$(top_builddir)/src/bin/lttng-sessiond/utils.$(OBJEXT) \
+ $(top_builddir)/src/bin/lttng-sessiond/tracker.$(OBJEXT) \
$(top_builddir)/src/common/health/libhealth.la \
$(top_builddir)/src/bin/lttng-sessiond/notification-thread-commands.$(OBJEXT) \
$(LIBLTTNG_CTL)