From ee9c58e03e9f02c2966b43df2d71716dc02a54ed Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 4 Jul 2018 16:17:26 -0400 Subject: [PATCH] Backport: trackers: update liblttng-ctl Signed-off-by: Mathieu Desnoyers --- include/lttng/session.h | 69 ++++++++++ src/lib/lttng-ctl/lttng-ctl.c | 244 +++++++++++++++++++++++++++------- 2 files changed, 267 insertions(+), 46 deletions(-) diff --git a/include/lttng/session.h b/include/lttng/session.h index 599892d13..4a7f0c8c5 100644 --- a/include/lttng/session.h +++ b/include/lttng/session.h @@ -22,6 +22,33 @@ extern "C" { #endif +#include + +enum lttng_tracker_type { + LTTNG_TRACKER_PID = 0, + LTTNG_TRACKER_VPID, + LTTNG_TRACKER_UID, + LTTNG_TRACKER_GID, + LTTNG_TRACKER_VUID, + LTTNG_TRACKER_VGID, +}; + +enum lttng_tracker_id_type { + LTTNG_ID_UNKNOWN = -1, + + LTTNG_ID_ALL, + LTTNG_ID_VALUE, + LTTNG_ID_STRING, +}; + +struct lttng_tracker_id { + enum lttng_tracker_id_type type; + int value; + char *string; +}; + +struct lttng_handle; + /* * Basic session information. * @@ -129,6 +156,48 @@ extern int lttng_list_sessions(struct lttng_session **sessions); 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. + * An id argument >= 0 adds the ID to the session tracker. + * An id argument of -1 means "track all IDs". + * + * 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, + struct lttng_tracker_id *id); + +/* + * Remove ID from session tracker. + * + * tracker_type is the type of tracker. + * An id argument >= 0 removes the ID from the session tracker. + * An id argument of -1 means "untrack all IDs". + * + * 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, + 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/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index f0b211c7b..e0f21b55d 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -1373,13 +1373,15 @@ int lttng_disable_channel(struct lttng_handle *handle, const char *name) return lttng_ctl_ask_sessiond(&lsm, NULL); } -/* - * Add PID to session tracker. - * Return 0 on success else a negative LTTng error code. - */ -int lttng_track_pid(struct lttng_handle *handle, int pid) +static +int lttng_track_untrack_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + struct lttng_tracker_id *id, + enum lttcomm_sessiond_command cmd) { struct lttcomm_session_msg lsm; + char *var_data = NULL; + size_t var_data_len = 0; /* NULL arguments are forbidden. No default values. */ if (handle == NULL) { @@ -1388,41 +1390,82 @@ int lttng_track_pid(struct lttng_handle *handle, int pid) memset(&lsm, 0, sizeof(lsm)); - lsm.cmd_type = LTTNG_TRACK_PID; - lsm.u.pid_tracker.pid = pid; + lsm.cmd_type = cmd; + lsm.u.id_tracker.tracker_type = tracker_type; + lsm.u.id_tracker.id_type = id->type; + switch (id->type) { + case LTTNG_ID_ALL: + break; + case LTTNG_ID_VALUE: + lsm.u.id_tracker.u.value = id->value; + break; + case LTTNG_ID_STRING: + var_data = id->string; + var_data_len = strlen(var_data) + 1; /* Includes \0. */ + lsm.u.id_tracker.u.var_len = var_data_len; + break; + default: + return -LTTNG_ERR_INVALID; + } lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain); lttng_ctl_copy_string(lsm.session.name, handle->session_name, sizeof(lsm.session.name)); - return lttng_ctl_ask_sessiond(&lsm, NULL); + return lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, + var_data, var_data_len, NULL); } + /* - * Remove PID from session tracker. + * Add ID to session tracker. * Return 0 on success else a negative LTTng error code. */ -int lttng_untrack_pid(struct lttng_handle *handle, int pid) +int lttng_track_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + struct lttng_tracker_id *id) { - struct lttcomm_session_msg lsm; - - /* NULL arguments are forbidden. No default values. */ - if (handle == NULL) { - return -LTTNG_ERR_INVALID; - } + return lttng_track_untrack_id(handle, tracker_type, + id, LTTNG_TRACK_ID); +} - memset(&lsm, 0, sizeof(lsm)); +/* + * Remove ID from session tracker. + * Return 0 on success else a negative LTTng error code. + */ +int lttng_untrack_id(struct lttng_handle *handle, + enum lttng_tracker_type tracker_type, + struct lttng_tracker_id *id) +{ + return lttng_track_untrack_id(handle, tracker_type, + id, LTTNG_UNTRACK_ID); +} - lsm.cmd_type = LTTNG_UNTRACK_PID; - lsm.u.pid_tracker.pid = pid; +/* + * Add PID to session tracker. + * Return 0 on success else a negative LTTng error code. + */ +int lttng_track_pid(struct lttng_handle *handle, int pid) +{ + struct lttng_tracker_id id; - lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain); + id.type = LTTNG_TRACKER_PID; + id.value = pid; + return lttng_track_id(handle, LTTNG_TRACKER_PID, &id); +} - lttng_ctl_copy_string(lsm.session.name, handle->session_name, - sizeof(lsm.session.name)); +/* + * Remove PID from session tracker. + * Return 0 on success else a negative LTTng error code. + */ +int lttng_untrack_pid(struct lttng_handle *handle, int pid) +{ + struct lttng_tracker_id id; - return lttng_ctl_ask_sessiond(&lsm, NULL); + id.type = LTTNG_TRACKER_PID; + id.value = pid; + return lttng_untrack_id(handle, LTTNG_TRACKER_PID, &id); } /* @@ -1784,7 +1827,7 @@ int lttng_list_events(struct lttng_handle *handle, /* Set number of events and free command header */ nb_events = cmd_header->nb_events; if (nb_events > INT_MAX) { - ret = -EOVERFLOW; + ret = -LTTNG_ERR_OVERFLOW; goto error; } ret = (int) nb_events; @@ -2322,49 +2365,158 @@ 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; + 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)); lttng_ctl_copy_lttng_domain(&lsm.domain, &handle->domain); - ret = lttng_ctl_ask_sessiond(&lsm, (void **) &pids); + ret = lttng_ctl_ask_sessiond_varlen(&lsm, NULL, 0, (void **) &cmd_payload, + (void **) &cmd_header, &cmd_header_len); if (ret < 0) { + goto error; + } + + /* Set number of tracker_id and free command header */ + nr_ids = cmd_header->nb_tracker_id; + if (nr_ids > INT_MAX) { + ret = -LTTNG_ERR_OVERFLOW; + goto error; + } + free(cmd_header); + cmd_header = NULL; + + ids = zmalloc(sizeof(*ids) * nr_ids); + if (!ids) { + ret = -LTTNG_ERR_NOMEM; + goto error; + } + + p = cmd_payload; + for (i = 0; i < nr_ids; i++) { + struct lttcomm_tracker_id_header *tracker_id; + struct lttng_tracker_id *id; + + tracker_id = (struct lttcomm_tracker_id_header *) p; + p += sizeof(struct lttcomm_tracker_id_header); + id = &ids[i]; + + id->type = tracker_id->type; + switch (tracker_id->type) { + case LTTNG_ID_ALL: + break; + case LTTNG_ID_VALUE: + id->value = tracker_id->u.value; + break; + case LTTNG_ID_STRING: + id->string = strdup(p); + if (!id->string) { + ret = -LTTNG_ERR_NOMEM; + goto error; + } + p += tracker_id->u.var_data_len; + break; + default: + goto error; + } + } + free(cmd_payload); + *_ids = ids; + *_nr_ids = nr_ids; + return 0; + +error: + if (ids) { + for (i = 0; i < nr_ids; i++) { + free(ids[i].string); + } + free(ids); + } + free(cmd_payload); + free(cmd_header); + return ret; +} + +/* + * List PIDs in the tracker. + * + * 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 == 1 && pids[0] == -1) { - free(pids); - pids = NULL; - enabled = 0; - nr_pids = 0; + *_enabled = 1; + + pids = zmalloc(nr_ids * sizeof(*pids)); + if (!pids) { + ret = -LTTNG_ERR_NOMEM; + goto end; + } + for (i = 0; i < nr_ids; i++) { + struct lttng_tracker_id *id = &ids[i]; + + if (id->type != LTTNG_ID_VALUE) { + ret = -LTTNG_ERR_UNK; + goto end; + } + pids[i] = id->value; } - *_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; } /* -- 2.34.1