From: Jonathan Rajotte Date: Wed, 20 Nov 2019 03:48:00 +0000 (-0500) Subject: Refactoring: introduce lttng_tracker_ids data structure X-Git-Tag: v2.12.0-rc1~94 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=a7a533cd65d544e8beebabcca5fe906e27af4707 Refactoring: introduce lttng_tracker_ids data structure This data structure is opaque to allow for back-end implementation change in the future. For now, only the following functions concerning lttng_tracker_ids are public: lttng_list_tracker_ids lttng_tracker_ids_get_count lttng_tracker_ids_get_at_index lttng_tracker_ids_destroy Signed-off-by: Jonathan Rajotte Change-Id: Iae1c10d0b578b402ab91378dd49f69f605b316b2 Signed-off-by: Jérémie Galarneau --- diff --git a/include/lttng/tracker-internal.h b/include/lttng/tracker-internal.h index a84d419d6..0debf7523 100644 --- a/include/lttng/tracker-internal.h +++ b/include/lttng/tracker-internal.h @@ -29,12 +29,46 @@ struct lttng_tracker_id { char *string; }; +struct lttng_tracker_ids { + struct lttng_tracker_id *id_array; + unsigned int count; +}; + LTTNG_HIDDEN bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left, const struct lttng_tracker_id *right); +/* + * A copy acts like memcpy. It does not allocate new memory. + */ +LTTNG_HIDDEN +int lttng_tracker_id_copy(struct lttng_tracker_id *dest, + const struct lttng_tracker_id *src); + +/* + * Duplicate an lttng_tracker_id. + * The returned object must be freed via lttng_tracker_id_destroy. + */ +LTTNG_HIDDEN +struct lttng_tracker_id *lttng_tracker_id_duplicate( + const struct lttng_tracker_id *src); + +/* + * Allocate a new list of lttng_tracker_id. + * The returned object must be freed via lttng_tracker_ids_destroy. + */ +LTTNG_HIDDEN +struct lttng_tracker_ids *lttng_tracker_ids_create(unsigned int base_count); + +/* + * Return the non-const pointer of an element at index "index" of a + * lttng_tracker_ids. + * + * The ownership of the lttng_tracker_id element is NOT transfered. + * The returned object can NOT be freed via lttng_tracker_id_destroy. + */ LTTNG_HIDDEN -struct lttng_tracker_id *lttng_tracker_id_copy( - const struct lttng_tracker_id *orig); +struct lttng_tracker_id *lttng_tracker_ids_get_pointer_of_index( + const struct lttng_tracker_ids *list, unsigned int index); #endif /* LTTNG_TRACKER_INTERNAL_H */ diff --git a/include/lttng/tracker.h b/include/lttng/tracker.h index 2d952a6e3..a66a2cfce 100644 --- a/include/lttng/tracker.h +++ b/include/lttng/tracker.h @@ -51,6 +51,7 @@ enum lttng_tracker_id_status { struct lttng_handle; struct lttng_tracker_id; +struct lttng_tracker_ids; /* * Create a tracker id for the passed tracker type. @@ -132,12 +133,6 @@ extern enum lttng_tracker_id_status lttng_tracker_id_get_value( extern enum lttng_tracker_id_status lttng_tracker_id_get_string( const struct lttng_tracker_id *id, const char **value); -/* - * Destroys (frees) an array of tracker id. - */ -extern void lttng_tracker_ids_destroy( - struct lttng_tracker_id **ids, size_t nr_ids); - /* * Add ID to session tracker. * @@ -165,17 +160,16 @@ extern int lttng_untrack_id(struct lttng_handle *handle, * 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 must be freed using lttng_tracker_id_destroy on each - * constituent of the returned array or using lttng_tracker_ids_destroy. - * nr_ids is set to the number of entries contained by the ids array. + * ids is set to an allocated lttng_tracker_ids representing IDs + * currently tracked. + * On success, caller is responsible for freeing ids + * using lttng_tracker_ids_destroy. * * 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); + struct lttng_tracker_ids **ids); /* * Backward compatibility. @@ -215,6 +209,28 @@ extern int lttng_list_tracker_pids(struct lttng_handle *handle, int32_t **pids, size_t *nr_pids); +/* + * Get a tracker id from the list at a given index. + * + * Note that the list maintains the ownership of the returned tracker id. + * It must not be destroyed by the user, nor should it be held beyond the + * lifetime of the tracker id list. + * + * Returns a tracker id, or NULL on error. + */ +extern const struct lttng_tracker_id *lttng_tracker_ids_get_at_index( + const struct lttng_tracker_ids *ids, unsigned int index); + +/* + * Get the number of tracker id in a tracker id list. + */ +extern int lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids); + +/* + * Destroy a tracker id list. + */ +extern void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids); + #ifdef __cplusplus } #endif diff --git a/src/bin/lttng-sessiond/client.c b/src/bin/lttng-sessiond/client.c index 2c7bd4787..8eff1650e 100644 --- a/src/bin/lttng-sessiond/client.c +++ b/src/bin/lttng-sessiond/client.c @@ -1568,29 +1568,34 @@ error_add_context: case LTTNG_LIST_TRACKER_IDS: { struct lttcomm_tracker_command_header cmd_header; - struct lttng_tracker_id **ids = NULL; - ssize_t nr_ids, i; + struct lttng_tracker_ids *ids = NULL; + size_t nr_ids, i; struct lttng_dynamic_buffer buf; - nr_ids = cmd_list_tracker_ids( + ret = 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_ids; + if (ret != LTTNG_OK) { goto error; } + nr_ids = lttng_tracker_ids_get_count(ids); lttng_dynamic_buffer_init(&buf); for (i = 0; i < nr_ids; i++) { - struct lttng_tracker_id *id = ids[i]; + const struct lttng_tracker_id *id; struct lttcomm_tracker_id_header id_hdr; size_t var_data_len = 0; enum lttng_tracker_id_status status; const char *string; int value; + id = lttng_tracker_ids_get_at_index(ids, i); + if (!id) { + ret = LTTNG_ERR_INVALID; + goto error_list_tracker; + } + memset(&id_hdr, 0, sizeof(id_hdr)); id_hdr.type = lttng_tracker_id_get_type(id); switch (id_hdr.type) { @@ -1637,8 +1642,7 @@ error_add_context: ret = setup_lttng_msg(cmd_ctx, buf.data, buf.size, &cmd_header, sizeof(cmd_header)); error_list_tracker: - lttng_tracker_ids_destroy(ids, nr_ids); - free(ids); + lttng_tracker_ids_destroy(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 b668b56d4..4ce2d43fa 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -2581,13 +2581,12 @@ ssize_t cmd_list_syscalls(struct lttng_event **events) * * Called with session lock held. */ -ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, +int cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_session *session, enum lttng_domain_type domain, - struct lttng_tracker_id ***ids) + struct lttng_tracker_ids **ids) { - int ret; - ssize_t nr_pids = 0; + int ret = LTTNG_OK; switch (domain) { case LTTNG_DOMAIN_KERNEL: @@ -2595,9 +2594,9 @@ ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_kernel_session *ksess; ksess = session->kernel_session; - nr_pids = kernel_list_tracker_ids(tracker_type, ksess, ids); - if (nr_pids < 0) { - ret = LTTNG_ERR_KERN_LIST_FAIL; + ret = kernel_list_tracker_ids(tracker_type, ksess, ids); + if (ret != LTTNG_OK) { + ret = -LTTNG_ERR_KERN_LIST_FAIL; goto error; } break; @@ -2607,9 +2606,9 @@ ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_ust_session *usess; usess = session->ust_session; - nr_pids = trace_ust_list_tracker_ids(tracker_type, usess, ids); - if (nr_pids < 0) { - ret = LTTNG_ERR_UST_LIST_FAIL; + ret = trace_ust_list_tracker_ids(tracker_type, usess, ids); + if (ret != LTTNG_OK) { + ret = -LTTNG_ERR_UST_LIST_FAIL; goto error; } break; @@ -2618,15 +2617,13 @@ ssize_t cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, case LTTNG_DOMAIN_JUL: case LTTNG_DOMAIN_PYTHON: default: - ret = LTTNG_ERR_UND; + ret = -LTTNG_ERR_UND; goto error; } - return nr_pids; - error: /* Return negative value to differentiate return code */ - return -ret; + return ret; } /* diff --git a/src/bin/lttng-sessiond/cmd.h b/src/bin/lttng-sessiond/cmd.h index ee4bf65e7..42145002f 100644 --- a/src/bin/lttng-sessiond/cmd.h +++ b/src/bin/lttng-sessiond/cmd.h @@ -114,10 +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_ids(enum lttng_tracker_type tracker_type, +int cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_session *session, enum lttng_domain_type domain, - struct lttng_tracker_id ***ids); + struct lttng_tracker_ids **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 c5fd30b7e..8ec20e71b 100644 --- a/src/bin/lttng-sessiond/kernel.c +++ b/src/bin/lttng-sessiond/kernel.c @@ -707,8 +707,7 @@ int kernel_track_id(enum lttng_tracker_type tracker_type, { int ret, value; struct lttng_tracker_list *tracker_list; - struct lttng_tracker_id **saved_ids; - ssize_t saved_ids_count; + struct lttng_tracker_ids *saved_ids; ret = lttng_tracker_id_lookup_string(tracker_type, id, &value); if (ret != LTTNG_OK) { @@ -721,8 +720,8 @@ int kernel_track_id(enum lttng_tracker_type tracker_type, } /* Save list for restore on error. */ - saved_ids_count = lttng_tracker_id_get_list(tracker_list, &saved_ids); - if (saved_ids_count < 0) { + ret = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (ret != LTTNG_OK) { return LTTNG_ERR_INVALID; } @@ -808,13 +807,11 @@ int kernel_track_id(enum lttng_tracker_type tracker_type, break; } - if (lttng_tracker_id_set_list(tracker_list, saved_ids, - saved_ids_count) != LTTNG_OK) { + if (lttng_tracker_id_set_list(tracker_list, saved_ids) != LTTNG_OK) { ERR("Error on tracker add error handling.\n"); } end: - lttng_tracker_ids_destroy(saved_ids, saved_ids_count); - free(saved_ids); + lttng_tracker_ids_destroy(saved_ids); return ret; } @@ -824,8 +821,7 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type, { int ret, value; struct lttng_tracker_list *tracker_list; - struct lttng_tracker_id **saved_ids; - ssize_t saved_ids_count; + struct lttng_tracker_ids *saved_ids; ret = lttng_tracker_id_lookup_string(tracker_type, id, &value); if (ret != LTTNG_OK) { @@ -837,8 +833,8 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type, 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) { + ret = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (ret != LTTNG_OK) { return LTTNG_ERR_INVALID; } /* Remove from list. */ @@ -926,30 +922,38 @@ int kernel_untrack_id(enum lttng_tracker_type tracker_type, break; } - if (lttng_tracker_id_set_list(tracker_list, saved_ids, - saved_ids_count) != LTTNG_OK) { + if (lttng_tracker_id_set_list(tracker_list, saved_ids) != LTTNG_OK) { ERR("Error on tracker remove error handling.\n"); } end: - lttng_tracker_ids_destroy(saved_ids, saved_ids_count); - free(saved_ids); + lttng_tracker_ids_destroy(saved_ids); return ret; } /* * Called with session lock held. */ -ssize_t kernel_list_tracker_ids(enum lttng_tracker_type tracker_type, +int kernel_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_kernel_session *session, - struct lttng_tracker_id ***_ids) + struct lttng_tracker_ids **_ids) { + int ret = 0; struct lttng_tracker_list *tracker_list; tracker_list = get_id_tracker_list(session, tracker_type); if (!tracker_list) { - return -LTTNG_ERR_INVALID; + ret = -LTTNG_ERR_INVALID; + goto end; } - return lttng_tracker_id_get_list(tracker_list, _ids); + + ret = lttng_tracker_id_get_list(tracker_list, _ids); + if (ret != LTTNG_OK) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + +end: + return ret; } /* diff --git a/src/bin/lttng-sessiond/kernel.h b/src/bin/lttng-sessiond/kernel.h index 64d95d235..e28f0d2e0 100644 --- a/src/bin/lttng-sessiond/kernel.h +++ b/src/bin/lttng-sessiond/kernel.h @@ -72,9 +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_ids(enum lttng_tracker_type tracker_type, +int kernel_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_kernel_session *session, - struct lttng_tracker_id ***_ids); + struct lttng_tracker_ids **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 83019842d..b95ee2df0 100644 --- a/src/bin/lttng-sessiond/save.c +++ b/src/bin/lttng-sessiond/save.c @@ -1836,10 +1836,10 @@ static int save_id_tracker(struct config_writer *writer, enum lttng_tracker_type tracker_type) { int ret = LTTNG_OK; - ssize_t nr_ids = 0, i; - struct lttng_tracker_id **ids = NULL; + size_t nr_ids = 0, i; + struct lttng_tracker_ids *ids = NULL; const char *element_id_tracker, *element_target_id, *element_id; - struct lttng_tracker_id *id; + const struct lttng_tracker_id *id; enum lttng_tracker_id_status status; int value; const char *string; @@ -1883,9 +1883,9 @@ static int save_id_tracker(struct config_writer *writer, switch (domain) { case LTTNG_DOMAIN_KERNEL: { - nr_ids = kernel_list_tracker_ids( + ret = kernel_list_tracker_ids( tracker_type, sess->kernel_session, &ids); - if (nr_ids < 0) { + if (ret != LTTNG_OK) { ret = LTTNG_ERR_KERN_LIST_FAIL; goto end; } @@ -1893,9 +1893,9 @@ static int save_id_tracker(struct config_writer *writer, } case LTTNG_DOMAIN_UST: { - nr_ids = trace_ust_list_tracker_ids( + ret = trace_ust_list_tracker_ids( tracker_type, sess->ust_session, &ids); - if (nr_ids < 0) { + if (ret != LTTNG_OK) { ret = LTTNG_ERR_UST_LIST_FAIL; goto end; } @@ -1909,10 +1909,15 @@ static int save_id_tracker(struct config_writer *writer, goto end; } - if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) { - /* Tracking all, nothing to output. */ - ret = LTTNG_OK; - goto end; + nr_ids = lttng_tracker_ids_get_count(ids); + + if (nr_ids == 1) { + id = lttng_tracker_ids_get_at_index(ids, 0); + if (id && lttng_tracker_id_get_type(id) == LTTNG_ID_ALL) { + /* Tracking all, nothing to output. */ + ret = LTTNG_OK; + goto end; + } } ret = config_writer_open_element(writer, element_id_tracker); @@ -1944,7 +1949,11 @@ static int save_id_tracker(struct config_writer *writer, } else { /* Tracking list. */ for (i = 0; i < nr_ids; i++) { - id = ids[i]; + id = lttng_tracker_ids_get_at_index(ids, i); + if (!id) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } switch (lttng_tracker_id_get_type(id)) { case LTTNG_ID_VALUE: ret = config_writer_open_element( @@ -2008,8 +2017,7 @@ static int save_id_tracker(struct config_writer *writer, ret = LTTNG_OK; end: - lttng_tracker_ids_destroy(ids, nr_ids); - free(ids); + lttng_tracker_ids_destroy(ids); return ret; } diff --git a/src/bin/lttng-sessiond/trace-ust.c b/src/bin/lttng-sessiond/trace-ust.c index 4a7e26105..a5192ffbe 100644 --- a/src/bin/lttng-sessiond/trace-ust.c +++ b/src/bin/lttng-sessiond/trace-ust.c @@ -918,8 +918,7 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type, 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; + struct lttng_tracker_ids *saved_ids; if (tracker_type == LTTNG_TRACKER_PID) { DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain."); @@ -935,8 +934,8 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type, 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) { + retval = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (retval != LTTNG_OK) { return LTTNG_ERR_INVALID; } /* Add to list. */ @@ -997,13 +996,11 @@ int trace_ust_track_id(enum lttng_tracker_type tracker_type, goto end; end_restore: - if (lttng_tracker_id_set_list(tracker_list, saved_ids, - saved_ids_count) != LTTNG_OK) { + if (lttng_tracker_id_set_list(tracker_list, saved_ids) != LTTNG_OK) { ERR("Error on tracker add error handling.\n"); } end: - lttng_tracker_ids_destroy(saved_ids, saved_ids_count); - free(saved_ids); + lttng_tracker_ids_destroy(saved_ids); return retval; } @@ -1019,8 +1016,7 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type, 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; + struct lttng_tracker_ids *saved_ids; if (tracker_type == LTTNG_TRACKER_PID) { DBG("Backward compatible behavior: translate PID tracker to VPID tracker for UST domain."); @@ -1037,8 +1033,8 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type, 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) { + retval = lttng_tracker_id_get_list(tracker_list, &saved_ids); + if (retval != LTTNG_OK) { return LTTNG_ERR_INVALID; } /* Remove from list. */ @@ -1100,23 +1096,22 @@ int trace_ust_untrack_id(enum lttng_tracker_type tracker_type, goto end; end_restore: - if (lttng_tracker_id_set_list(tracker_list, saved_ids, - saved_ids_count) != LTTNG_OK) { + if (lttng_tracker_id_set_list(tracker_list, saved_ids) != LTTNG_OK) { ERR("Error on tracker remove error handling.\n"); } end: - lttng_tracker_ids_destroy(saved_ids, saved_ids_count); - free(saved_ids); + lttng_tracker_ids_destroy(saved_ids); return retval; } /* * Called with session lock held. */ -ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, +int trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_ust_session *session, - struct lttng_tracker_id ***_ids) + struct lttng_tracker_ids **_ids) { + int ret = LTTNG_OK; struct lttng_tracker_list *tracker_list; if (tracker_type == LTTNG_TRACKER_PID) { @@ -1126,9 +1121,17 @@ ssize_t trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, tracker_list = get_id_tracker_list(session, tracker_type); if (!tracker_list) { - return -LTTNG_ERR_INVALID; + ret = -LTTNG_ERR_INVALID; + goto end; } - return lttng_tracker_id_get_list(tracker_list, _ids); + + ret = lttng_tracker_id_get_list(tracker_list, _ids); + if (ret != LTTNG_OK) { + ret = -LTTNG_ERR_INVALID; + goto end; + } +end: + return ret; } /* diff --git a/src/bin/lttng-sessiond/trace-ust.h b/src/bin/lttng-sessiond/trace-ust.h index 2d0b042e5..11486ddd0 100644 --- a/src/bin/lttng-sessiond/trace-ust.h +++ b/src/bin/lttng-sessiond/trace-ust.h @@ -238,9 +238,9 @@ 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_ids(enum lttng_tracker_type tracker_type, +int trace_ust_list_tracker_ids(enum lttng_tracker_type tracker_type, struct ltt_ust_session *session, - struct lttng_tracker_id ***_ids); + struct lttng_tracker_ids **_ids); #else /* HAVE_LIBLTTNG_UST_CTL */ @@ -352,10 +352,10 @@ static inline int trace_ust_id_tracker_lookup( { return 0; } -static inline ssize_t trace_ust_list_tracker_ids( +static inline int trace_ust_list_tracker_ids( enum lttng_tracker_type tracker_type, struct ltt_ust_session *session, - struct lttng_tracker_id **_ids) + struct lttng_tracker_ids **_ids) { return -1; } diff --git a/src/bin/lttng-sessiond/tracker.c b/src/bin/lttng-sessiond/tracker.c index 909a04845..48dc176c1 100644 --- a/src/bin/lttng-sessiond/tracker.c +++ b/src/bin/lttng-sessiond/tracker.c @@ -178,7 +178,7 @@ int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list, goto error; } - n->id = lttng_tracker_id_copy(_id); + n->id = lttng_tracker_id_duplicate(_id); if (!n->id) { ret = LTTNG_ERR_NOMEM; goto error; @@ -415,12 +415,14 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, * Protected by session mutex held by caller. * On success, _ids and the ids it contains must be freed by the caller. */ -ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id ***_ids) +int lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, + struct lttng_tracker_ids **_ids) { + int retval = LTTNG_OK, ret; struct lttng_tracker_list_node *n; - ssize_t count = 0, i = 0, retval = 0; - struct lttng_tracker_id **ids; + ssize_t count = 0, i = 0; + struct lttng_tracker_ids *ids = NULL; + struct lttng_tracker_id *id; enum lttng_tracker_id_status status; switch (tracker_list->state) { @@ -429,7 +431,7 @@ ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, n, &tracker_list->list_head, list_node) { count++; } - ids = zmalloc(sizeof(*ids) * count); + ids = lttng_tracker_ids_create(count); if (ids == NULL) { PERROR("Failed to allocate tracked ID list"); retval = -LTTNG_ERR_NOMEM; @@ -437,67 +439,86 @@ ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, } cds_list_for_each_entry ( n, &tracker_list->list_head, list_node) { - ids[i] = lttng_tracker_id_copy(n->id); - if (!ids[i]) { + id = lttng_tracker_ids_get_pointer_of_index(ids, i); + if (!id) { + retval = -LTTNG_ERR_INVALID; + goto error; + } + + ret = lttng_tracker_id_copy(id, n->id); + if (ret) { retval = -LTTNG_ERR_NOMEM; goto error; } i++; } - *_ids = ids; - retval = count; break; case LTTNG_TRACK_ALL: - ids = zmalloc(sizeof(*ids)); + + ids = lttng_tracker_ids_create(1); if (ids == NULL) { PERROR("Failed to allocate tracked ID list"); retval = -LTTNG_ERR_NOMEM; goto end; } - ids[0] = lttng_tracker_id_create(); - status = lttng_tracker_id_set_all(ids[0]); + + id = lttng_tracker_ids_get_pointer_of_index(ids, 0); + status = lttng_tracker_id_set_all(id); if (status != LTTNG_TRACKER_ID_STATUS_OK) { ERR("Invalid tracker id for track all"); retval = -LTTNG_ERR_INVALID; goto error; } - *_ids = ids; - retval = 1; break; case LTTNG_TRACK_NONE: - /* No ids track, so we return 0 element. */ - *_ids = NULL; + /* No ids track, so we return 0 element collection. */ + ids = lttng_tracker_ids_create(0); + if (ids == NULL) { + PERROR("alloc list ids"); + retval = -LTTNG_ERR_NOMEM; + goto end; + } break; } + *_ids = ids; + end: return retval; error: - lttng_tracker_ids_destroy(ids, count); - free(ids); + lttng_tracker_ids_destroy(ids); return retval; } int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id **_ids, - size_t count) + const struct lttng_tracker_ids *ids) { - size_t i; + size_t i, count; + const struct lttng_tracker_id *id; + + assert(tracker_list); + assert(ids); lttng_tracker_list_reset(tracker_list); - if (count == 1 && lttng_tracker_id_get_type(_ids[0])) { - /* Track all. */ - return LTTNG_OK; - } + count = lttng_tracker_ids_get_count(ids); + if (count == 0) { /* Set state to "track none". */ tracker_list->state = LTTNG_TRACK_NONE; return LTTNG_OK; } + + if (count == 1) { + id = lttng_tracker_ids_get_at_index(ids, 0); + if (lttng_tracker_id_get_type(id) == LTTNG_ID_ALL) { + /* Track all. */ + return LTTNG_OK; + } + } + for (i = 0; i < count; i++) { - struct lttng_tracker_id *id = _ids[i]; int ret; - + id = lttng_tracker_ids_get_at_index(ids, i); ret = lttng_tracker_list_add(tracker_list, id); if (ret != LTTNG_OK) { return ret; diff --git a/src/bin/lttng-sessiond/tracker.h b/src/bin/lttng-sessiond/tracker.h index 812b3b127..7497abd0c 100644 --- a/src/bin/lttng-sessiond/tracker.h +++ b/src/bin/lttng-sessiond/tracker.h @@ -56,10 +56,9 @@ int lttng_tracker_list_remove(struct lttng_tracker_list *tracker_list, int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, const struct lttng_tracker_id *id, int *result); -ssize_t lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id ***_ids); +int lttng_tracker_id_get_list(const struct lttng_tracker_list *tracker_list, + struct lttng_tracker_ids **_ids); int lttng_tracker_id_set_list(struct lttng_tracker_list *tracker_list, - struct lttng_tracker_id **_ids, - size_t count); + const struct lttng_tracker_ids *_ids); #endif /* _LTT_TRACKER_H */ diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c index 49470ab86..229648e07 100644 --- a/src/bin/lttng/commands/list.c +++ b/src/bin/lttng/commands/list.c @@ -1539,16 +1539,23 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) { int ret = 0; int enabled = 1; - struct lttng_tracker_id **ids = NULL; + struct lttng_tracker_ids *ids = NULL; size_t nr_ids, i; + const struct lttng_tracker_id *id; - ret = lttng_list_tracker_ids(handle, tracker_type, &ids, &nr_ids); + ret = lttng_list_tracker_ids(handle, tracker_type, &ids); if (ret) { return ret; } - if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) { - enabled = 0; + + nr_ids = lttng_tracker_ids_get_count(ids); + if (nr_ids == 1) { + id = lttng_tracker_ids_get_at_index(ids, 0); + if (id && lttng_tracker_id_get_type(id) == LTTNG_ID_ALL) { + enabled = 0; + } } + if (enabled) { _MSG("%s tracker: [", get_tracker_str(tracker_type)); @@ -1562,11 +1569,17 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) } for (i = 0; i < nr_ids; i++) { - struct lttng_tracker_id *id = ids[i]; - enum lttng_tracker_id_status status; + enum lttng_tracker_id_status status = + LTTNG_TRACKER_ID_STATUS_OK; int value; const char *value_string; + id = lttng_tracker_ids_get_at_index(ids, i); + if (!id) { + ret = CMD_ERROR; + goto end; + } + switch (lttng_tracker_id_get_type(id)) { case LTTNG_ID_ALL: break; @@ -1627,7 +1640,7 @@ static int list_tracker_ids(enum lttng_tracker_type tracker_type) } } end: - lttng_tracker_ids_destroy(ids, nr_ids); + lttng_tracker_ids_destroy(ids); return ret; } diff --git a/src/common/mi-lttng.c b/src/common/mi-lttng.c index 7b0d9cf02..bc2d3f3d0 100644 --- a/src/common/mi-lttng.c +++ b/src/common/mi-lttng.c @@ -1662,7 +1662,7 @@ int mi_lttng_targets_open(struct mi_writer *writer) LTTNG_HIDDEN int mi_lttng_id_target(struct mi_writer *writer, enum lttng_tracker_type tracker_type, - struct lttng_tracker_id *id, + const struct lttng_tracker_id *id, int is_open) { int ret; diff --git a/src/common/mi-lttng.h b/src/common/mi-lttng.h index 3ea6bc6d7..2e4592b53 100644 --- a/src/common/mi-lttng.h +++ b/src/common/mi-lttng.h @@ -694,7 +694,7 @@ int mi_lttng_targets_open(struct mi_writer *writer); */ int mi_lttng_id_target(struct mi_writer *writer, enum lttng_tracker_type tracker_type, - struct lttng_tracker_id *id, + const struct lttng_tracker_id *id, int is_open); /* diff --git a/src/common/tracker.c b/src/common/tracker.c index f8a4fba0f..7742f47bc 100644 --- a/src/common/tracker.c +++ b/src/common/tracker.c @@ -85,7 +85,7 @@ enum lttng_tracker_id_status lttng_tracker_id_set_all( return LTTNG_TRACKER_ID_STATUS_OK; } -void lttng_tracker_id_destroy(struct lttng_tracker_id *id) +static void lttng_tracker_id_reset(struct lttng_tracker_id *id) { if (id == NULL) { return; @@ -93,20 +93,22 @@ void lttng_tracker_id_destroy(struct lttng_tracker_id *id) if (id->string != NULL) { free(id->string); + id->string = NULL; } - free(id); + id->type = LTTNG_ID_UNKNOWN; + id->value = -1; } -void lttng_tracker_ids_destroy(struct lttng_tracker_id **ids, size_t nr_ids) +void lttng_tracker_id_destroy(struct lttng_tracker_id *id) { - if (ids == NULL) { + if (id == NULL) { return; } - for (int i = 0; i < nr_ids; i++) { - lttng_tracker_id_destroy(ids[i]); - } + lttng_tracker_id_reset(id); + + free(id); } enum lttng_tracker_id_type lttng_tracker_id_get_type( @@ -162,32 +164,24 @@ bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left, return 1; } -struct lttng_tracker_id *lttng_tracker_id_copy( +int lttng_tracker_id_copy(struct lttng_tracker_id *dest, const struct lttng_tracker_id *orig) { - struct lttng_tracker_id *copy = NULL; + int ret = 0; enum lttng_tracker_id_status status; - copy = lttng_tracker_id_create(); - if (copy == NULL) { - goto error; - } + assert(dest); + assert(orig); switch (orig->type) { case LTTNG_ID_ALL: - status = lttng_tracker_id_set_all(copy); + status = lttng_tracker_id_set_all(dest); break; case LTTNG_ID_VALUE: - status = lttng_tracker_id_set_value(copy, orig->value); - if (status != LTTNG_TRACKER_ID_STATUS_OK) { - goto error; - } + status = lttng_tracker_id_set_value(dest, orig->value); break; case LTTNG_ID_STRING: - status = lttng_tracker_id_set_string(copy, orig->string); - if (status != LTTNG_TRACKER_ID_STATUS_OK) { - goto error; - } + status = lttng_tracker_id_set_string(dest, orig->string); break; default: status = LTTNG_TRACKER_ID_STATUS_OK; @@ -195,6 +189,26 @@ struct lttng_tracker_id *lttng_tracker_id_copy( } if (status != LTTNG_TRACKER_ID_STATUS_OK) { + ret = -1; + goto error; + } +error: + return ret; +} + +struct lttng_tracker_id *lttng_tracker_id_duplicate( + const struct lttng_tracker_id *orig) +{ + int ret; + struct lttng_tracker_id *copy = NULL; + + copy = lttng_tracker_id_create(); + if (copy == NULL) { + goto error; + } + + ret = lttng_tracker_id_copy(copy, orig); + if (ret) { goto error; } @@ -221,3 +235,63 @@ enum lttng_tracker_id_status lttng_tracker_id_get_string( *value = id->string; return LTTNG_TRACKER_ID_STATUS_OK; } + +struct lttng_tracker_ids *lttng_tracker_ids_create(unsigned int count) +{ + struct lttng_tracker_ids *ids = NULL; + + ids = zmalloc(sizeof(*ids)); + if (!ids) { + goto error; + } + + ids->id_array = zmalloc(sizeof(struct lttng_tracker_id) * count); + if (!ids->id_array) { + goto error; + } + + ids->count = count; + + return ids; +error: + free(ids); + return NULL; +} + +LTTNG_HIDDEN +struct lttng_tracker_id *lttng_tracker_ids_get_pointer_of_index( + const struct lttng_tracker_ids *ids, unsigned int index) +{ + assert(ids); + if (index >= ids->count) { + return NULL; + } + + return &ids->id_array[index]; +} + +const struct lttng_tracker_id *lttng_tracker_ids_get_at_index( + const struct lttng_tracker_ids *ids, unsigned int index) +{ + assert(ids); + return lttng_tracker_ids_get_pointer_of_index(ids, index); +} + +int lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids) +{ + assert(ids); + return ids->count; +} + +void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids) +{ + if (!ids) { + return; + } + + for (int i = 0; i < ids->count; i++) { + lttng_tracker_id_reset(&ids->id_array[i]); + } + free(ids->id_array); + free(ids); +} diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 406de885c..88daf45aa 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -2839,8 +2839,7 @@ end: */ int lttng_list_tracker_ids(struct lttng_handle *handle, enum lttng_tracker_type tracker_type, - struct lttng_tracker_id ***_ids, - size_t *_nr_ids) + struct lttng_tracker_ids **_ids) { int ret, i; struct lttcomm_session_msg lsm; @@ -2848,7 +2847,7 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, char *cmd_payload = NULL, *p; size_t cmd_header_len; size_t nr_ids = 0; - struct lttng_tracker_id **ids = NULL; + struct lttng_tracker_ids *ids = NULL; if (handle == NULL) { return -LTTNG_ERR_INVALID; @@ -2877,7 +2876,7 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, free(cmd_header); cmd_header = NULL; - ids = zmalloc(sizeof(*ids) * nr_ids); + ids = lttng_tracker_ids_create(nr_ids); if (!ids) { ret = -LTTNG_ERR_NOMEM; goto error; @@ -2891,9 +2890,9 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, tracker_id = (struct lttcomm_tracker_id_header *) p; p += sizeof(struct lttcomm_tracker_id_header); - id = lttng_tracker_id_create(); + id = lttng_tracker_ids_get_pointer_of_index(ids, i); if (!id) { - ret = -LTTNG_ERR_NOMEM; + ret = -LTTNG_ERR_INVALID; goto error; } @@ -2918,18 +2917,13 @@ int lttng_list_tracker_ids(struct lttng_handle *handle, ret = -LTTNG_ERR_INVALID; goto error; } - - /* Assign the new object to the list */ - ids[i] = id; } free(cmd_payload); *_ids = ids; - *_nr_ids = nr_ids; return 0; error: - lttng_tracker_ids_destroy(ids, nr_ids); - free(ids); + lttng_tracker_ids_destroy(ids); free(cmd_payload); free(cmd_header); return ret; @@ -2948,20 +2942,28 @@ error: int lttng_list_tracker_pids(struct lttng_handle *handle, int *_enabled, int32_t **_pids, size_t *_nr_pids) { - struct lttng_tracker_id **ids = NULL; + struct lttng_tracker_ids *ids = NULL; size_t nr_ids = 0; int *pids = NULL; int ret = 0, i; enum lttng_tracker_id_status status; + const struct lttng_tracker_id *id; - ret = lttng_list_tracker_ids(handle, LTTNG_TRACKER_PID, &ids, &nr_ids); - if (ret < 0) + ret = lttng_list_tracker_ids(handle, LTTNG_TRACKER_PID, &ids); + if (ret < 0) { return ret; + } - if (nr_ids == 1 && lttng_tracker_id_get_type(ids[0]) == LTTNG_ID_ALL) { - *_enabled = 0; - goto end; + nr_ids = lttng_tracker_ids_get_count(ids); + + if (nr_ids == 1) { + id = lttng_tracker_ids_get_at_index(ids, 0); + if (id && lttng_tracker_id_get_type(id) == LTTNG_ID_ALL) { + *_enabled = 0; + goto end; + } } + *_enabled = 1; pids = zmalloc(nr_ids * sizeof(*pids)); @@ -2970,8 +2972,7 @@ int lttng_list_tracker_pids(struct lttng_handle *handle, goto end; } for (i = 0; i < nr_ids; i++) { - struct lttng_tracker_id *id = ids[i]; - + id = lttng_tracker_ids_get_at_index(ids, i); status = lttng_tracker_id_get_value(id, &pids[i]); if (status != LTTNG_TRACKER_ID_STATUS_OK) { ret = -LTTNG_ERR_UNK; @@ -2981,8 +2982,7 @@ int lttng_list_tracker_pids(struct lttng_handle *handle, *_pids = pids; *_nr_pids = nr_ids; end: - lttng_tracker_ids_destroy(ids, nr_ids); - free(ids); + lttng_tracker_ids_destroy(ids); if (ret < 0) { free(pids); }