X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Ftracker.c;h=302971767742a41f792f907484e2e91bc10e9c7f;hp=af527b4fd03b5f7a2fd441b71c225ad1f1df8495;hb=b7e1aba3b4ca20d7efd006f2c0485eb3408ea80e;hpb=a8c3ad3e850d45026f22ecdc7ea963b7e923bd08 diff --git a/src/bin/lttng-sessiond/tracker.c b/src/bin/lttng-sessiond/tracker.c index af527b4fd..302971767 100644 --- a/src/bin/lttng-sessiond/tracker.c +++ b/src/bin/lttng-sessiond/tracker.c @@ -1,18 +1,8 @@ /* - * Copyright (C) 2018 - Mathieu Desnoyers + * Copyright (C) 2018 Mathieu Desnoyers * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2 only, - * as published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _LGPL_SOURCE @@ -27,6 +17,7 @@ #include #include #include +#include #define FALLBACK_USER_BUFLEN 16384 #define FALLBACK_GROUP_BUFLEN 16384 @@ -60,53 +51,42 @@ static int match_tracker_key(struct cds_lfht_node *node, const void *key) tracker_node = caa_container_of( node, struct lttng_tracker_list_node, ht_node); - if (tracker_node->id.type != tracker_key->type) { - return 0; - } - switch (tracker_node->id.type) { - case LTTNG_ID_ALL: - return 1; - case LTTNG_ID_VALUE: - if (tracker_node->id.value != tracker_key->value) { - return 0; - } - break; - case LTTNG_ID_STRING: - if (strcmp(tracker_node->id.string, tracker_key->string) != 0) { - return 0; - } - break; - default: - return 0; - } - return 1; + + return lttng_tracker_id_is_equal(tracker_node->id, tracker_key); } static unsigned long hash_tracker_key( const struct lttng_tracker_id *tracker_key) { unsigned long key_hash = 0; + int value; + const char *string; + enum lttng_tracker_id_type type; + + /* We do not care for invalid state during hash computation */ + type = lttng_tracker_id_get_type(tracker_key); + (void) lttng_tracker_id_get_value(tracker_key, &value); + (void) lttng_tracker_id_get_string(tracker_key, &string); - switch (tracker_key->type) { + switch (type) { case LTTNG_ID_ALL: break; case LTTNG_ID_VALUE: key_hash ^= hash_key_ulong( - (void *) (unsigned long) tracker_key->value, - lttng_ht_seed); + (void *) (unsigned long) value, lttng_ht_seed); break; case LTTNG_ID_STRING: - key_hash ^= hash_key_str(tracker_key->string, lttng_ht_seed); + key_hash ^= hash_key_str(string, lttng_ht_seed); break; case LTTNG_ID_UNKNOWN: break; } - key_hash ^= hash_key_ulong((void *) (unsigned long) tracker_key->type, - lttng_ht_seed); + key_hash ^= hash_key_ulong( + (void *) (unsigned long) type, lttng_ht_seed); return key_hash; } -static struct lttng_tracker_id *lttng_tracker_list_lookup( +static struct lttng_tracker_id **lttng_tracker_list_lookup( const struct lttng_tracker_list *tracker_list, const struct lttng_tracker_id *key) { @@ -130,7 +110,7 @@ static void destroy_list_node_rcu(struct rcu_head *head) struct lttng_tracker_list_node *n = caa_container_of( head, struct lttng_tracker_list_node, rcu_head); - free(n->id.string); + lttng_tracker_id_destroy(n->id); free(n); } @@ -161,14 +141,15 @@ static void lttng_tracker_list_reset(struct lttng_tracker_list *tracker_list) int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list, const struct lttng_tracker_id *_id) { - struct lttng_tracker_id *id; - struct lttng_tracker_list_node *n; + struct lttng_tracker_id **id; + struct lttng_tracker_list_node *n = NULL; int ret; - if (_id->type == LTTNG_ID_ALL) { + if (lttng_tracker_id_get_type(_id) == LTTNG_ID_ALL) { /* Track all, so remove each individual item. */ lttng_tracker_list_reset(tracker_list); - return LTTNG_OK; + ret = LTTNG_OK; + goto error; } rcu_read_lock(); id = lttng_tracker_list_lookup(tracker_list, _id); @@ -178,28 +159,26 @@ int lttng_tracker_list_add(struct lttng_tracker_list *tracker_list, */ rcu_read_unlock(); if (id) { - return LTTNG_ERR_ID_TRACKED; + ret = LTTNG_ERR_ID_TRACKED; + goto error; } n = zmalloc(sizeof(*n)); if (!n) { - return LTTNG_ERR_NOMEM; + ret = LTTNG_ERR_NOMEM; + goto error; } - n->id = *_id; - if (_id->type == LTTNG_ID_STRING) { - n->id.string = strdup(_id->string); - if (!n->id.string) { - ret = LTTNG_ERR_NOMEM; - goto error; - } - } else { - n->id.string = NULL; + + n->id = lttng_tracker_id_duplicate(_id); + if (!n->id) { + ret = LTTNG_ERR_NOMEM; + goto error; } cds_list_add_tail(&n->list_node, &tracker_list->list_head); tracker_list->state = LTTNG_TRACK_LIST; rcu_read_lock(); - cds_lfht_add(tracker_list->ht, hash_tracker_key(&n->id), &n->ht_node); + cds_lfht_add(tracker_list->ht, hash_tracker_key(n->id), &n->ht_node); rcu_read_unlock(); return LTTNG_OK; @@ -217,10 +196,10 @@ int lttng_tracker_list_remove(struct lttng_tracker_list *tracker_list, const struct lttng_tracker_id *_id) { enum lttng_error_code ret = LTTNG_OK; - struct lttng_tracker_id *id; + struct lttng_tracker_id **id; struct lttng_tracker_list_node *n; - if (_id->type == LTTNG_ID_ALL) { + if (lttng_tracker_id_get_type(_id) == LTTNG_ID_ALL) { /* Untrack all. */ lttng_tracker_list_reset(tracker_list); /* Set state to "track none". */ @@ -246,11 +225,14 @@ end: void lttng_tracker_list_destroy(struct lttng_tracker_list *tracker_list) { + int ret; + if (!tracker_list) { return; } lttng_tracker_list_reset(tracker_list); - cds_lfht_destroy(tracker_list->ht, NULL); + ret = cds_lfht_destroy(tracker_list->ht, NULL); + assert(!ret); free(tracker_list); } @@ -380,14 +362,26 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, const struct lttng_tracker_id *id, int *result) { - switch (id->type) { + enum lttng_tracker_id_status status; + int value; + const char *string; + + switch (lttng_tracker_id_get_type(id)) { case LTTNG_ID_ALL: *result = -1; return LTTNG_OK; case LTTNG_ID_VALUE: + status = lttng_tracker_id_get_value(id, &value); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + return LTTNG_ERR_INVALID; + } *result = id->value; return LTTNG_OK; case LTTNG_ID_STRING: + status = lttng_tracker_id_get_string(id, &string); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + return LTTNG_ERR_INVALID; + } switch (tracker_type) { case LTTNG_TRACKER_PID: case LTTNG_TRACKER_VPID: @@ -396,11 +390,11 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, case LTTNG_TRACKER_UID: case LTTNG_TRACKER_VUID: DBG("Lookup of tracker UID/VUID by name."); - return lttng_lookup_user(id->string, result); + return lttng_lookup_user(string, result); case LTTNG_TRACKER_GID: case LTTNG_TRACKER_VGID: DBG("Lookup of tracker GID/VGID by name."); - return lttng_lookup_group(id->string, result); + return lttng_lookup_group(string, result); default: return LTTNG_ERR_INVALID; } @@ -412,14 +406,17 @@ int lttng_tracker_id_lookup_string(enum lttng_tracker_type tracker_type, /* * Protected by session mutex held by caller. - * On success, _ids and the strings it contains must be freed 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) { case LTTNG_TRACK_LIST: @@ -427,7 +424,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; @@ -435,67 +432,91 @@ 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].type = n->id.type; - ids[i].value = n->id.value; - if (ids[i].type == LTTNG_ID_STRING) { - ids[i].string = strdup(n->id.string); - if (!ids[i].string) { - retval = -LTTNG_ERR_NOMEM; - goto error; - } + 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->type = LTTNG_TRACK_ALL; - *_ids = ids; - retval = 1; + + 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; + } 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: - for (i = 0; i < count; i++) { - free(ids[i].string); - } - 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; + unsigned int i, count; + const struct lttng_tracker_id *id; + enum lttng_tracker_id_status status; + + assert(tracker_list); + assert(ids); lttng_tracker_list_reset(tracker_list); - if (count == 1 && _ids[0].type == LTTNG_ID_ALL) { - /* Track all. */ - return LTTNG_OK; + + status = lttng_tracker_ids_get_count(ids, &count); + if (status != LTTNG_TRACKER_ID_STATUS_OK) { + return LTTNG_ERR_INVALID; } + 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;