#include <common/hashtable/hashtable.h>
#include <common/hashtable/utils.h>
#include <lttng/lttng-error.h>
+#include <lttng/tracker-internal.h>
#define FALLBACK_USER_BUFLEN 16384
#define FALLBACK_GROUP_BUFLEN 16384
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)
{
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);
}
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);
*/
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;
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". */
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:
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;
}
/*
* 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:
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;
}
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;
+ size_t i, count;
+ const struct lttng_tracker_id *id;
+
+ 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;
- }
+ 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;