From: Jonathan Rajotte Date: Thu, 7 Nov 2019 21:18:10 +0000 (-0500) Subject: trackers: support tracking feature X-Git-Tag: v2.12.0-rc1~104 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=55c9e7cac24318259d4f2549c97f7577b7b52db4;p=lttng-tools.git trackers: support tracking feature Signed-off-by: Jonathan Rajotte Change-Id: I1629562f4c94947f5dd54a0cee6c0f8f7beb19fe Signed-off-by: Jérémie Galarneau --- diff --git a/include/lttng/session.h b/include/lttng/session.h index 824323bdf..06d4f8b9d 100644 --- a/include/lttng/session.h +++ b/include/lttng/session.h @@ -23,6 +23,8 @@ extern "C" { #endif +#include + enum lttng_tracker_type { LTTNG_TRACKER_PID = 0, LTTNG_TRACKER_VPID = 1, @@ -45,6 +47,7 @@ struct lttng_tracker_id { char *string; }; +struct lttng_handle; struct lttng_session_descriptor; struct lttng_destruction_handle; @@ -236,6 +239,46 @@ extern enum lttng_error_code lttng_session_get_creation_time( extern int lttng_set_session_shm_path(const char *session_name, const char *shm_path); +/* + * Add ID to session tracker. + * + * tracker_type is the type of tracker. + * id the id to track. + * + * Return 0 on success else a negative LTTng error code. + */ +extern int lttng_track_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + const struct lttng_tracker_id *id); + +/* + * Remove ID from session tracker. + * + * tracker_type is the type of tracker. + * id the id to untrack. + * + * Return 0 on success else a negative LTTng error code. + */ +extern int lttng_untrack_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + const struct lttng_tracker_id *id); + +/* + * List IDs in the tracker. + * + * tracker_type is the type of tracker. + * ids is set to an allocated array of IDs currently tracked. On + * success, ids and the strings it contains must be freed by the + * caller. + * nr_ids is set to the number of entries contained by the ids array. + * + * Returns 0 on success, else a negative LTTng error code. + */ +extern int lttng_list_tracker_ids(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + struct lttng_tracker_id **ids, + size_t *nr_ids); + /* * Add PID to session tracker. * diff --git a/src/bin/lttng-sessiond/Makefile.am b/src/bin/lttng-sessiond/Makefile.am index 481a3e3b3..34dd9965e 100644 --- a/src/bin/lttng-sessiond/Makefile.am +++ b/src/bin/lttng-sessiond/Makefile.am @@ -51,7 +51,8 @@ lttng_sessiond_SOURCES = utils.c utils.h \ 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 \ diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index 30ec11119..ae027d5e0 100644 --- a/src/bin/lttng-sessiond/client.c +++ b/src/bin/lttng-sessiond/client.c @@ -789,7 +789,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx, int *sock, 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: @@ -1205,18 +1205,100 @@ error_add_context: 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: @@ -1442,27 +1524,65 @@ error_add_context: 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; } diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 53850f74a..f152c1c2e 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -1442,12 +1442,14 @@ 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; @@ -1460,7 +1462,7 @@ int cmd_track_pid(struct ltt_session *session, enum lttng_domain_type domain, ksess = session->kernel_session; - ret = kernel_track_pid(ksess, pid); + ret = kernel_track_id(tracker_type, ksess, id); if (ret != LTTNG_OK) { goto error; } @@ -1474,7 +1476,7 @@ int cmd_track_pid(struct ltt_session *session, enum lttng_domain_type domain, 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; } @@ -1493,12 +1495,14 @@ 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; @@ -1511,7 +1515,7 @@ int cmd_untrack_pid(struct ltt_session *session, enum lttng_domain_type domain, ksess = session->kernel_session; - ret = kernel_untrack_pid(ksess, pid); + ret = kernel_untrack_id(tracker_type, ksess, id); if (ret != LTTNG_OK) { goto error; } @@ -1525,7 +1529,7 @@ int cmd_untrack_pid(struct ltt_session *session, enum lttng_domain_type domain, 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; } @@ -2573,12 +2577,14 @@ ssize_t cmd_list_syscalls(struct lttng_event **events) } /* - * 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; @@ -2589,7 +2595,7 @@ ssize_t cmd_list_tracker_pids(struct ltt_session *session, 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; @@ -2601,7 +2607,7 @@ ssize_t cmd_list_tracker_pids(struct ltt_session *session, 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; diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index 2f9d9cdf7..9329f42cf 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -57,10 +57,14 @@ int cmd_disable_channel(struct ltt_session *session, 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, @@ -110,8 +114,10 @@ ssize_t cmd_list_tracepoints(enum lttng_domain_type domain, 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); diff --git a/src/bin/lttng-sessiond/kernel.c b/src/bin/lttng-sessiond/kernel.c index 2626e98b2..113937536 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -679,120 +679,281 @@ error: 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); } /* diff --git a/src/bin/lttng-sessiond/kernel.h b/src/bin/lttng-sessiond/kernel.h index 16a70124d..cf91cab1b 100644 --- a/src/bin/lttng-sessiond/kernel.h +++ b/src/bin/lttng-sessiond/kernel.h @@ -30,7 +30,7 @@ * 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); @@ -43,8 +43,12 @@ int kernel_disable_channel(struct ltt_kernel_channel *chan); 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); @@ -68,8 +72,9 @@ enum lttng_error_code kernel_rotate_session(struct ltt_session *session); 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); diff --git a/src/bin/lttng-sessiond/save.c b/src/bin/lttng-sessiond/save.c index 865775c8d..59715d0b9 100644 --- a/src/bin/lttng-sessiond/save.c +++ b/src/bin/lttng-sessiond/save.c @@ -36,6 +36,7 @@ #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) @@ -47,12 +48,14 @@ int save_kernel_channel_attributes(struct config_writer *writer, 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; } @@ -60,6 +63,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_num_subbuf, attr->num_subbuf); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -67,6 +71,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_switch_timer_interval, attr->switch_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -74,6 +79,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_read_timer_interval, attr->read_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -82,12 +88,14 @@ int save_kernel_channel_attributes(struct config_writer *writer, 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; } @@ -95,6 +103,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_tracefile_count, attr->tracefile_count); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -102,6 +111,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_live_timer_interval, attr->live_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -113,6 +123,7 @@ int save_kernel_channel_attributes(struct config_writer *writer, config_element_monitor_timer_interval, ext->monitor_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -120,14 +131,17 @@ int save_kernel_channel_attributes(struct config_writer *writer, 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) @@ -140,12 +154,14 @@ int save_ust_channel_attributes(struct config_writer *writer, 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; } @@ -153,6 +169,7 @@ int save_ust_channel_attributes(struct config_writer *writer, config_element_num_subbuf, attr->num_subbuf); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -160,6 +177,7 @@ int save_ust_channel_attributes(struct config_writer *writer, config_element_switch_timer_interval, attr->switch_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -167,6 +185,7 @@ int save_ust_channel_attributes(struct config_writer *writer, config_element_read_timer_interval, attr->read_timer_interval); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -175,6 +194,7 @@ int save_ust_channel_attributes(struct config_writer *writer, attr->output == LTTNG_UST_MMAP ? config_output_type_mmap : config_output_type_splice); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -182,6 +202,7 @@ int save_ust_channel_attributes(struct config_writer *writer, config_element_blocking_timeout, attr->u.s.blocking_timeout); if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } @@ -194,11 +215,13 @@ int save_ust_channel_attributes(struct config_writer *writer, 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 @@ -481,6 +504,7 @@ const char *get_loglevel_type_string( 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) @@ -962,10 +986,13 @@ int save_kernel_event(struct config_writer *writer, 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) @@ -981,7 +1008,7 @@ int save_kernel_events(struct config_writer *writer, 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; } } @@ -992,10 +1019,13 @@ int save_kernel_events(struct config_writer *writer, 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) @@ -1106,10 +1136,13 @@ int save_ust_event(struct config_writer *writer, 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) @@ -1134,7 +1167,7 @@ int save_ust_events(struct config_writer *writer, continue; } ret = save_ust_event(writer, event); - if (ret) { + if (ret != LTTNG_OK) { rcu_read_unlock(); goto end; } @@ -1147,22 +1180,25 @@ int save_ust_events(struct config_writer *writer, 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) { @@ -1177,7 +1213,7 @@ int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event, break; default: ERR("Invalid agent_event loglevel_type."); - ret = -1; + ret = LTTNG_ERR_INVALID; goto end; } @@ -1185,10 +1221,13 @@ int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event, 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) @@ -1219,12 +1258,12 @@ int save_agent_events(struct config_writer *writer, * 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; } @@ -1237,15 +1276,18 @@ int save_agent_events(struct config_writer *writer, 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; @@ -1317,10 +1359,12 @@ int save_kernel_context(struct config_writer *writer, 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) @@ -1329,7 +1373,7 @@ int save_kernel_contexts(struct config_writer *writer, struct ltt_kernel_context *ctx; if (cds_list_empty(&kchan->ctx_list)) { - ret = 0; + ret = LTTNG_OK; goto end; } @@ -1341,7 +1385,7 @@ int save_kernel_contexts(struct config_writer *writer, 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; } } @@ -1352,10 +1396,13 @@ int save_kernel_contexts(struct config_writer *writer, 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) @@ -1399,10 +1446,13 @@ int save_ust_context_perf_thread_counter(struct config_writer *writer, 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) @@ -1441,10 +1491,13 @@ int save_ust_context_app_ctx(struct config_writer *writer, 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) @@ -1470,10 +1523,13 @@ int save_ust_context_generic(struct config_writer *writer, 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) @@ -1509,7 +1565,7 @@ int save_ust_context(struct config_writer *writer, /* Save generic context. */ ret = save_ust_context_generic(writer, ctx); } - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -1527,10 +1583,13 @@ int save_ust_context(struct config_writer *writer, 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) @@ -1561,17 +1620,17 @@ int save_kernel_channel(struct config_writer *writer, } 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; } @@ -1581,10 +1640,13 @@ int save_kernel_channel(struct config_writer *writer, 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, @@ -1617,7 +1679,7 @@ int save_ust_channel(struct config_writer *writer, } ret = save_ust_channel_attributes(writer, &ust_chan->attr); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -1645,7 +1707,7 @@ int save_ust_channel(struct config_writer *writer, if (ust_chan->domain == LTTNG_DOMAIN_UST) { ret = save_ust_events(writer, ust_chan->events); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } else { @@ -1665,13 +1727,13 @@ int save_ust_channel(struct config_writer *writer, * 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; } @@ -1681,10 +1743,13 @@ int save_ust_channel(struct config_writer *writer, 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) @@ -1719,7 +1784,7 @@ int save_kernel_session(struct config_writer *writer, 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; } } @@ -1730,6 +1795,8 @@ int save_kernel_session(struct config_writer *writer, ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } + + ret = LTTNG_OK; end: return ret; } @@ -1762,19 +1829,59 @@ const char *get_config_domain_str(enum lttng_domain_type domain) 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; } @@ -1782,8 +1889,9 @@ int save_pid_tracker(struct config_writer *writer, } 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; } @@ -1797,64 +1905,149 @@ int save_pid_tracker(struct config_writer *writer, 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) @@ -1916,7 +2109,7 @@ int save_ust_domain(struct config_writer *writer, 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; } @@ -1939,14 +2132,15 @@ int save_ust_domain(struct config_writer *writer, 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; } } @@ -1958,14 +2152,16 @@ int save_ust_domain(struct config_writer *writer, 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); @@ -1980,7 +2176,6 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) goto end; } - if (session->kernel_session) { ret = config_writer_open_element(writer, config_element_domain); @@ -1990,7 +2185,7 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) } ret = save_kernel_session(writer, session); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -2001,8 +2196,8 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) 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; } @@ -2022,22 +2217,22 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) 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; } } @@ -2048,10 +2243,13 @@ int save_domains(struct config_writer *writer, struct ltt_session *session) 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) @@ -2132,10 +2330,10 @@ int save_consumer_output(struct config_writer *writer, 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 { @@ -2172,10 +2370,13 @@ end_net_output: 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) @@ -2218,7 +2419,7 @@ int save_snapshot_outputs(struct config_writer *writer, } ret = save_consumer_output(writer, output->consumer); - if (ret) { + if (ret != LTTNG_OK) { goto end_unlock; } @@ -2238,6 +2439,7 @@ int save_snapshot_outputs(struct config_writer *writer, goto end; } + ret = LTTNG_OK; end: return ret; end_unlock: @@ -2245,6 +2447,7 @@ 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) @@ -2257,7 +2460,7 @@ int save_session_output(struct config_writer *writer, 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; } @@ -2269,13 +2472,13 @@ int save_session_output(struct config_writer *writer, 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; } } @@ -2287,6 +2490,7 @@ int save_session_output(struct config_writer *writer, ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } + ret = LTTNG_OK; end: return ret; } @@ -2374,7 +2578,7 @@ end: /* * 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, @@ -2508,7 +2712,7 @@ 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); @@ -2519,7 +2723,7 @@ int save_session(struct ltt_session *session, } ret = save_domains(writer, session); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -2571,7 +2775,7 @@ int save_session(struct ltt_session *session, } ret = save_session_output(writer, session); - if (ret) { + if (ret != LTTNG_OK) { goto end; } @@ -2588,12 +2792,14 @@ int save_session(struct ltt_session *session, 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."); @@ -2601,8 +2807,10 @@ end: } if (fd >= 0) { - ret = close(fd); - if (ret) { + int closeret; + + closeret = close(fd); + if (closeret) { PERROR("Closing XML session configuration"); } } @@ -2631,7 +2839,7 @@ int cmd_save_sessions(struct lttng_save_session_attr *attr, ret = save_session(session, attr, creds); session_unlock(session); session_put(session); - if (ret) { + if (ret != LTTNG_OK) { goto end; } } else { @@ -2646,7 +2854,7 @@ int cmd_save_sessions(struct lttng_save_session_attr *attr, 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; } } diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index e0491c95b..22c602cee 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -164,6 +164,30 @@ struct ltt_kernel_session *trace_kernel_create_session(void) 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; @@ -172,6 +196,12 @@ struct ltt_kernel_session *trace_kernel_create_session(void) 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: @@ -718,5 +748,12 @@ void trace_kernel_free_session(struct ltt_kernel_session *session) /* 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); } diff --git a/src/bin/lttng-sessiond/trace-kernel.h b/src/bin/lttng-sessiond/trace-kernel.h index e439c31cd..e0a310553 100644 --- a/src/bin/lttng-sessiond/trace-kernel.h +++ b/src/bin/lttng-sessiond/trace-kernel.h @@ -26,6 +26,7 @@ #include #include "consumer.h" +#include "tracker.h" /* Kernel event list */ struct ltt_kernel_event_list { @@ -122,6 +123,13 @@ struct ltt_kernel_session { 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; }; /* diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index a6c0c04ad..f64f51c28 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -281,7 +281,7 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id) lus = zmalloc(sizeof(struct ltt_ust_session)); if (lus == NULL) { PERROR("create ust session zmalloc"); - goto error; + goto error_alloc; } /* Init data structure */ @@ -313,20 +313,35 @@ struct ltt_ust_session *trace_ust_create_session(uint64_t session_id) /* 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; } @@ -719,29 +734,25 @@ error: 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; } @@ -750,63 +761,60 @@ 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)); @@ -814,48 +822,85 @@ int pid_tracker_add_pid(struct ust_pid_tracker *pid_tracker, int pid) 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; @@ -864,47 +909,84 @@ int trace_ust_pid_tracker_lookup(struct ltt_ust_session *session, int pid) /* * 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; } } @@ -912,104 +994,145 @@ int trace_ust_track_pid(struct ltt_ust_session *session, int pid) 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); } /* @@ -1241,7 +1364,13 @@ void trace_ust_destroy_session(struct ltt_ust_session *session) 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); } diff --git a/src/bin/lttng-sessiond/trace-ust.h b/src/bin/lttng-sessiond/trace-ust.h index 7d923d527..1f6f534fe 100644 --- a/src/bin/lttng-sessiond/trace-ust.h +++ b/src/bin/lttng-sessiond/trace-ust.h @@ -91,11 +91,11 @@ struct ltt_ust_domain_global { 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; }; @@ -138,10 +138,18 @@ struct ltt_ust_session { 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; }; /* @@ -219,13 +227,20 @@ void trace_ust_destroy_event(struct ltt_ust_event *event); 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 */ @@ -318,24 +333,29 @@ struct agent *trace_ust_find_agent(struct ltt_ust_session *session, { 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; } diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 910642f86..d0980220d 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -4183,9 +4183,22 @@ int ust_app_create_channel_glb(struct ltt_ust_session *usess, 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; } @@ -5184,7 +5197,11 @@ void ust_app_global_update(struct ltt_ust_session *usess, struct ust_app *app) 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. diff --git a/src/common/config/config-session-abi.h b/src/common/config/config-session-abi.h index 12dfe600c..24ccee10c 100644 --- a/src/common/config/config-session-abi.h +++ b/src/common/config/config-session-abi.h @@ -18,6 +18,7 @@ #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; @@ -84,12 +85,26 @@ extern const char * const config_element_control_uri; 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; diff --git a/src/common/config/session-config.c b/src/common/config/session-config.c index c2ae5e120..e625f316a 100644 --- a/src/common/config/session-config.c +++ b/src/common/config/session-config.c @@ -61,6 +61,7 @@ struct session_config_validation_ctx { 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"; @@ -141,12 +142,25 @@ const char * const config_element_control_uri = "control_uri"; 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"; @@ -2661,19 +2675,90 @@ end: 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; @@ -2686,26 +2771,32 @@ int process_pid_tracker_node(xmlNodePtr pid_tracker_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) { @@ -2713,20 +2804,42 @@ int process_pid_tracker_node(xmlNodePtr pid_tracker_node, 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: @@ -2743,6 +2856,11 @@ int process_domain_node(xmlNodePtr domain_node, const char *session_name) 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); @@ -2855,17 +2973,60 @@ int process_domain_node(xmlNodePtr domain_node, const char *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: @@ -3377,6 +3538,7 @@ int load_session_from_file(const char *path, const char *session_name, sessions_node = xmlDocGetRootElement(doc); if (!sessions_node) { + ret = -LTTNG_ERR_LOAD_INVALID_CONFIG; goto end; } @@ -3396,6 +3558,9 @@ 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; } @@ -3520,10 +3685,14 @@ int load_session_from_path(const char *path, const char *session_name, 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 '/'. @@ -3535,25 +3704,24 @@ int load_session_from_path(const char *path, const char *session_name, 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; @@ -3626,6 +3794,7 @@ int config_load_session(const char *path, const char *session_name, DEFAULT_SESSION_CONFIG_AUTOLOAD, home_path); if (ret < 0) { PERROR("snprintf session autoload home config path"); + ret = -LTTNG_ERR_INVALID; goto end; } @@ -3643,6 +3812,7 @@ int config_load_session(const char *path, const char *session_name, DEFAULT_SESSION_HOME_CONFIGPATH, home_path); if (ret < 0) { PERROR("snprintf session home config path"); + ret = -LTTNG_ERR_INVALID; goto end; } path_ptr = path; @@ -3683,6 +3853,8 @@ int config_load_session(const char *path, const char *session_name, if (!ret) { session_loaded = true; } + } else { + ret = 0; } } else { ret = access(path, F_OK); diff --git a/src/common/config/session.xsd b/src/common/config/session.xsd index 7781a5bda..044b37701 100644 --- a/src/common/config/session.xsd +++ b/src/common/config/session.xsd @@ -270,16 +270,17 @@ by its signed 32-bit representation when converted to msec. - + - + + - + - - + + @@ -287,14 +288,125 @@ by its signed 32-bit representation when converted to msec. - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + diff --git a/src/common/sessiond-comm/sessiond-comm.h b/src/common/sessiond-comm/sessiond-comm.h index 8b1757438..034ba3697 100644 --- a/src/common/sessiond-comm/sessiond-comm.h +++ b/src/common/sessiond-comm/sessiond-comm.h @@ -95,9 +95,9 @@ enum lttcomm_sessiond_command { /* 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, @@ -354,8 +354,21 @@ struct lttcomm_session_msg { 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; @@ -459,6 +472,21 @@ struct lttcomm_session_destroy_command_header { 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. */ diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 7e01045fa..085005c39 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -1606,13 +1606,14 @@ int lttng_disable_channel(struct lttng_handle *handle, const char *name) return lttng_ctl_ask_sessiond(&lsm, NULL); } -/* - * Add PID to session tracker. - * Return 0 on success else a negative LTTng error code. - */ -int lttng_track_pid(struct lttng_handle *handle, int pid) +static int lttng_track_untrack_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + 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) { @@ -1621,41 +1622,80 @@ int lttng_track_pid(struct lttng_handle *handle, int pid) memset(&lsm, 0, sizeof(lsm)); - lsm.cmd_type = LTTNG_TRACK_PID; - lsm.u.pid_tracker.pid = pid; + lsm.cmd_type = cmd; + lsm.u.id_tracker.tracker_type = tracker_type; + lsm.u.id_tracker.id_type = id->type; + switch (id->type) { + case LTTNG_ID_ALL: + break; + case LTTNG_ID_VALUE: + lsm.u.id_tracker.u.value = id->value; + break; + case LTTNG_ID_STRING: + var_data = id->string; + var_data_len = strlen(var_data) + 1; /* Includes \0. */ + lsm.u.id_tracker.u.var_len = var_data_len; + break; + default: + return -LTTNG_ERR_INVALID; + } 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); } /* @@ -2283,7 +2323,7 @@ int lttng_list_events(struct lttng_handle *handle, /* Set number of events and free command header */ nb_events = cmd_header->nb_events; if (nb_events > INT_MAX) { - ret = -EOVERFLOW; + ret = -LTTNG_ERR_OVERFLOW; goto end; } free(cmd_header); @@ -2879,52 +2919,159 @@ end: } /* - * 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; } /* diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index b13481f4b..adc68406d 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -93,7 +93,8 @@ SESSIOND_OBJS += $(top_builddir)/src/bin/lttng-sessiond/trace-ust.$(OBJEXT) \ $(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) @@ -139,6 +140,7 @@ KERN_DATA_TRACE=$(top_builddir)/src/bin/lttng-sessiond/trace-kernel.$(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)