/*
* Add context on a kernel channel.
+ *
+ * Assumes the ownership of ctx.
*/
int kernel_add_channel_context(struct ltt_kernel_channel *chan,
struct ltt_kernel_context *ctx)
end:
cds_list_add_tail(&ctx->list, &chan->ctx_list);
- return 0;
-
+ ctx->in_list = true;
+ ctx = NULL;
error:
+ if (ctx) {
+ trace_kernel_destroy_context(ctx);
+ }
return ret;
}
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,
+ struct lttng_tracker_id *id)
{
- int ret;
+ int ret, value;
+ struct lttng_tracker_list *tracker_list;
- 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;
+ }
+
+ /* Add to list. */
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return LTTNG_ERR_INVALID;
+ }
+ ret = lttng_tracker_list_add(tracker_list, id);
+ if (ret != LTTNG_OK) {
+ return ret;
+ }
+
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ break;
+ default:
+ return LTTNG_ERR_INVALID;
}
switch (-ret) {
case EINVAL:
case ENOMEM:
return LTTNG_ERR_NOMEM;
case EEXIST:
- return LTTNG_ERR_PID_TRACKED;
+ return LTTNG_ERR_ID_TRACKED;
default:
return LTTNG_ERR_UNK;
}
}
-int kernel_untrack_pid(struct ltt_kernel_session *session, int pid)
+int kernel_untrack_id(enum lttng_tracker_type tracker_type,
+ struct ltt_kernel_session *session,
+ struct lttng_tracker_id *id)
{
- int ret;
+ int ret, value;
+ struct lttng_tracker_list *tracker_list;
+
+ ret = lttng_tracker_id_lookup_string(tracker_type,
+ id, &value);
+ if (ret != LTTNG_OK) {
+ return ret;
+ }
- DBG("Kernel untrack PID %d for session id %" PRIu64 ".",
- pid, session->id);
- ret = kernctl_untrack_pid(session->fd, pid);
- if (!ret) {
- return LTTNG_OK;
+ /* Remove from list. */
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return LTTNG_ERR_INVALID;
+ }
+ ret = lttng_tracker_list_remove(tracker_list, id);
+ if (ret != LTTNG_OK) {
+ return ret;
+ }
+
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ 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) {
+ return LTTNG_OK;
+ }
+ break;
+ default:
+ return LTTNG_ERR_INVALID;
}
+
switch (-ret) {
case EINVAL:
return LTTNG_ERR_INVALID;
case ENOMEM:
return LTTNG_ERR_NOMEM;
case ENOENT:
- return LTTNG_ERR_PID_NOT_TRACKED;
+ return LTTNG_ERR_ID_NOT_TRACKED;
default:
return LTTNG_ERR_UNK;
}
}
-ssize_t kernel_list_tracker_pids(struct ltt_kernel_session *session,
- int **_pids)
+/*
+ * 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)
{
- int fd, ret;
- int pid;
- ssize_t nbmem, count = 0;
- FILE *fp;
- int *pids;
+ struct lttng_tracker_list *tracker_list;
- fd = kernctl_list_tracker_pids(session->fd);
- if (fd < 0) {
- PERROR("kernel tracker pids list");
- goto error;
+ tracker_list = get_id_tracker_list(session, tracker_type);
+ if (!tracker_list) {
+ return -LTTNG_ERR_INVALID;
}
-
- fp = fdopen(fd, "r");
- if (fp == NULL) {
- PERROR("kernel tracker pids list fdopen");
- goto error_fp;
- }
-
- nbmem = KERNEL_TRACKER_PIDS_INIT_LIST_SIZE;
- pids = zmalloc(sizeof(*pids) * nbmem);
- if (pids == NULL) {
- PERROR("alloc list pids");
- count = -ENOMEM;
- 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;
- }
- pids[count++] = pid;
- }
-
- *_pids = pids;
- DBG("Kernel list tracker pids done (%zd pids)", count);
-end:
- ret = fclose(fp); /* closes both fp and fd */
- if (ret) {
- PERROR("fclose");
- }
- return count;
-
-error_fp:
- ret = close(fd);
- if (ret) {
- PERROR("close");
- }
-error:
- return -1;
+ return lttng_tracker_id_get_list(tracker_list, _ids);
}
/*
* Open stream of channel, register it to the kernel tracer and add it
* to the stream list of the channel.
*
+ * Note: given that the streams may appear in random order wrt CPU
+ * number (e.g. cpu hotplug), the index value of the stream number in
+ * the stream name is not necessarily linked to the CPU number.
+ *
* Return the number of created stream. Else, a negative value.
*/
int kernel_open_channel_stream(struct ltt_kernel_channel *channel)
{
- int ret, count = 0;
+ int ret;
struct ltt_kernel_stream *lks;
assert(channel);
while ((ret = kernctl_create_stream(channel->fd)) >= 0) {
- lks = trace_kernel_create_stream(channel->channel->name, count);
+ lks = trace_kernel_create_stream(channel->channel->name,
+ channel->stream_count);
if (lks == NULL) {
ret = close(ret);
if (ret) {
lks->tracefile_size = channel->channel->attr.tracefile_size;
lks->tracefile_count = channel->channel->attr.tracefile_count;
- /* Add stream to channe stream list */
+ /* Add stream to channel stream list */
cds_list_add(&lks->list, &channel->stream_list.head);
channel->stream_count++;
- /* Increment counter which represent CPU number. */
- count++;
-
DBG("Kernel stream %s created (fd: %d, state: %d)", lks->name, lks->fd,
lks->state);
}
/* For each channel, ask the consumer to snapshot it. */
cds_list_for_each_entry(chan, &ksess->channel_list.head, list) {
- pthread_mutex_lock(socket->lock);
ret = consumer_snapshot_channel(socket, chan->fd, output, 0,
ksess->uid, ksess->gid,
DEFAULT_KERNEL_TRACE_DIR, wait,
nb_packets_per_stream);
- pthread_mutex_unlock(socket->lock);
if (ret < 0) {
ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
(void) kernel_consumer_destroy_metadata(socket,
}
/* Snapshot metadata, */
- pthread_mutex_lock(socket->lock);
ret = consumer_snapshot_channel(socket, ksess->metadata->fd, output,
1, ksess->uid, ksess->gid,
DEFAULT_KERNEL_TRACE_DIR, wait, 0);
- pthread_mutex_unlock(socket->lock);
if (ret < 0) {
ret = LTTNG_ERR_KERN_CONSUMER_FAIL;
goto error_consumer;