X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fkernel.c;h=a72fe7f5c977ac76cd351555ec170b5781977191;hb=de04bbc88637bb336255f6cc7c7e4f4ea179f40d;hp=aa51649783f64c0e324c0090c42033cdbbb41f7a;hpb=3a6922c6ab7b4d9455f517ac0bf86dfcede0ef3d;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index aa5164978..a72fe7f5c 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -36,6 +36,8 @@ /* * 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) @@ -66,9 +68,12 @@ int kernel_add_channel_context(struct ltt_kernel_channel *chan, 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; } @@ -379,120 +384,274 @@ error: return ret; } - -int kernel_track_pid(struct ltt_kernel_session *session, int pid) +static +struct lttng_tracker_list *get_id_tracker_list(struct ltt_kernel_session *session, + enum lttng_tracker_type tracker_type) { - int ret; - - DBG("Kernel track PID %d for session id %" PRIu64 ".", - pid, session->id); - ret = kernctl_track_pid(session->fd, pid); - if (!ret) { - return LTTNG_OK; - } - switch (-ret) { - case EINVAL: - return LTTNG_ERR_INVALID; - case ENOMEM: - return LTTNG_ERR_NOMEM; - case EEXIST: - return LTTNG_ERR_PID_TRACKED; + 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 LTTNG_ERR_UNK; + return NULL; } } -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, + 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; + + 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; + 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. */ + 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, + struct lttng_tracker_id *id) { - int fd, ret; - int pid; - ssize_t nbmem, count = 0; - FILE *fp; - int *pids; - - fd = kernctl_list_tracker_pids(session->fd); - if (fd < 0) { - PERROR("kernel tracker pids list"); - goto error; + int ret, value; + struct lttng_tracker_list *tracker_list; + struct lttng_tracker_id *saved_ids; + ssize_t saved_ids_count, i; + + 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; } - pids[count++] = pid; + 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; + } + break; + default: + ret = -EINVAL; + break; } - *_pids = pids; - DBG("Kernel list tracker pids done (%zd pids)", count); + /* 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; + } + + 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); } /* @@ -644,17 +803,22 @@ error: * 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) { @@ -673,13 +837,10 @@ int kernel_open_channel_stream(struct ltt_kernel_channel *channel) 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); } @@ -1021,12 +1182,10 @@ int kernel_snapshot_record(struct ltt_kernel_session *ksess, /* 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, @@ -1036,11 +1195,9 @@ int kernel_snapshot_record(struct ltt_kernel_session *ksess, } /* 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;