X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-registry.cpp;h=838b51afe9c7f4191da3e6cee56b5f976831a498;hb=aeeb48c6a7dd4bcc092b3105439489fc393f6425;hp=baa58d73195c4fa3e1f3ab24d7cb730e41349614;hpb=3c3390532736cfb5198f863d0d2b218e21fcf76d;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-registry.cpp b/src/bin/lttng-sessiond/ust-registry.cpp index baa58d731..838b51afe 100644 --- a/src/bin/lttng-sessiond/ust-registry.cpp +++ b/src/bin/lttng-sessiond/ust-registry.cpp @@ -8,16 +8,17 @@ #define _LGPL_SOURCE #include -#include -#include +#include +#include +#include #include -#include "ust-registry.h" -#include "ust-app.h" -#include "ust-field-utils.h" -#include "utils.h" -#include "lttng-sessiond.h" -#include "notification-thread-commands.h" +#include "ust-registry.hpp" +#include "ust-app.hpp" +#include "ust-field-utils.hpp" +#include "utils.hpp" +#include "lttng-sessiond.hpp" +#include "notification-thread-commands.hpp" /* * Hash table match function for event in the registry. @@ -288,7 +289,7 @@ static struct ust_registry_event *alloc_event(int session_objd, return NULL; } - event = (ust_registry_event *) zmalloc(sizeof(*event)); + event = zmalloc(); if (!event) { PERROR("zmalloc ust registry event"); goto error; @@ -315,7 +316,7 @@ error: /* * Free event data structure. This does NOT delete it from any hash table. It's - * safe to pass a NULL pointer. This shoudl be called inside a call RCU if the + * safe to pass a NULL pointer. This should be called inside a call RCU if the * event is previously deleted from a rcu hash table. */ static void destroy_event(struct ust_registry_event *event) @@ -361,14 +362,15 @@ struct ust_registry_event *ust_registry_find_event( LTTNG_ASSERT(chan); LTTNG_ASSERT(name); LTTNG_ASSERT(sig); + ASSERT_RCU_READ_LOCKED(); /* Setup key for the match function. */ strncpy(key.name, name, sizeof(key.name)); key.name[sizeof(key.name) - 1] = '\0'; key.signature = sig; - cds_lfht_lookup(chan->ht->ht, chan->ht->hash_fct(&key, lttng_ht_seed), - chan->ht->match_fct, &key, &iter.iter); + cds_lfht_lookup(chan->events->ht, chan->events->hash_fct(&key, lttng_ht_seed), + chan->events->match_fct, &key, &iter.iter); node = lttng_ht_iter_get_node_u64(&iter); if (!node) { goto end; @@ -389,7 +391,7 @@ end: * * Should be called with session registry mutex held. */ -int ust_registry_create_event(struct ust_registry_session *session, +int ust_registry_create_event(ust_registry_session *session, uint64_t chan_key, int session_objd, int channel_objd, char *name, char *sig, size_t nr_fields, struct lttng_ust_ctl_field *fields, int loglevel_value, char *model_emf_uri, int buffer_type, @@ -445,8 +447,8 @@ int ust_registry_create_event(struct ust_registry_session *session, * This is an add unique with a custom match function for event. The node * are matched using the event name and signature. */ - nptr = cds_lfht_add_unique(chan->ht->ht, chan->ht->hash_fct(event, - lttng_ht_seed), chan->ht->match_fct, event, &event->node.node); + nptr = cds_lfht_add_unique(chan->events->ht, chan->events->hash_fct(event, + lttng_ht_seed), chan->events->match_fct, event, &event->node.node); if (nptr != &event->node.node) { if (buffer_type == LTTNG_BUFFER_PER_UID) { /* @@ -509,10 +511,11 @@ void ust_registry_destroy_event(struct ust_registry_channel *chan, LTTNG_ASSERT(chan); LTTNG_ASSERT(event); + ASSERT_RCU_READ_LOCKED(); /* Delete the node first. */ iter.iter.node = &event->node.node; - ret = lttng_ht_del(chan->ht, &iter); + ret = lttng_ht_del(chan->events, &iter); LTTNG_ASSERT(!ret); call_rcu(&event->node.head, destroy_event_rcu); @@ -542,14 +545,16 @@ static void destroy_enum_rcu(struct rcu_head *head) * Needs to be called from RCU read-side critical section. */ static struct ust_registry_enum *ust_registry_lookup_enum( - struct ust_registry_session *session, + ust_registry_session *session, const struct ust_registry_enum *reg_enum_lookup) { struct ust_registry_enum *reg_enum = NULL; struct lttng_ht_node_str *node; struct lttng_ht_iter iter; - cds_lfht_lookup(session->enums->ht, + ASSERT_RCU_READ_LOCKED(); + + cds_lfht_lookup(session->_enums->ht, ht_hash_enum((void *) reg_enum_lookup, lttng_ht_seed), ht_match_enum, reg_enum_lookup, &iter.iter); node = lttng_ht_iter_get_node_str(&iter); @@ -566,7 +571,7 @@ end: * Needs to be called from RCU read-side critical section. */ struct ust_registry_enum * - ust_registry_lookup_enum_by_id(struct ust_registry_session *session, + ust_registry_lookup_enum_by_id(ust_registry_session *session, const char *enum_name, uint64_t enum_id) { struct ust_registry_enum *reg_enum = NULL; @@ -574,11 +579,13 @@ struct ust_registry_enum * struct lttng_ht_iter iter; struct ust_registry_enum reg_enum_lookup; + ASSERT_RCU_READ_LOCKED(); + memset(®_enum_lookup, 0, sizeof(reg_enum_lookup)); strncpy(reg_enum_lookup.name, enum_name, LTTNG_UST_ABI_SYM_NAME_LEN); reg_enum_lookup.name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0'; reg_enum_lookup.id = enum_id; - cds_lfht_lookup(session->enums->ht, + cds_lfht_lookup(session->_enums->ht, ht_hash_enum((void *) ®_enum_lookup, lttng_ht_seed), ht_match_enum_id, ®_enum_lookup, &iter.iter); node = lttng_ht_iter_get_node_str(&iter); @@ -600,7 +607,7 @@ end: * * We receive ownership of entries. */ -int ust_registry_create_or_find_enum(struct ust_registry_session *session, +int ust_registry_create_or_find_enum(ust_registry_session *session, int session_objd, char *enum_name, struct lttng_ust_ctl_enum_entry *entries, size_t nr_entries, uint64_t *enum_id) @@ -624,7 +631,7 @@ int ust_registry_create_or_find_enum(struct ust_registry_session *session, } /* Check if the enumeration was already dumped */ - reg_enum = (ust_registry_enum *) zmalloc(sizeof(*reg_enum)); + reg_enum = zmalloc(); if (!reg_enum) { PERROR("zmalloc ust registry enumeration"); ret = -ENOMEM; @@ -646,14 +653,14 @@ int ust_registry_create_or_find_enum(struct ust_registry_session *session, } else { DBG("UST registry creating enum: %s, sess_objd: %u", enum_name, session_objd); - if (session->next_enum_id == -1ULL) { + if (session->_next_enum_id == -1ULL) { ret = -EOVERFLOW; destroy_enum(reg_enum); goto end; } - reg_enum->id = session->next_enum_id++; + reg_enum->id = session->_next_enum_id++; cds_lfht_node_init(®_enum->node.node); - nodep = cds_lfht_add_unique(session->enums->ht, + nodep = cds_lfht_add_unique(session->_enums->ht, ht_hash_enum(reg_enum, lttng_ht_seed), ht_match_enum_id, reg_enum, ®_enum->node.node); @@ -673,7 +680,7 @@ end: * the enumeration. * This MUST be called within a RCU read side lock section. */ -static void ust_registry_destroy_enum(struct ust_registry_session *reg_session, +void ust_registry_destroy_enum(ust_registry_session *reg_session, struct ust_registry_enum *reg_enum) { int ret; @@ -681,10 +688,11 @@ static void ust_registry_destroy_enum(struct ust_registry_session *reg_session, LTTNG_ASSERT(reg_session); LTTNG_ASSERT(reg_enum); + ASSERT_RCU_READ_LOCKED(); /* Delete the node first. */ iter.iter.node = ®_enum->node.node; - ret = lttng_ht_del(reg_session->enums, &iter); + ret = lttng_ht_del(reg_session->_enums.get(), &iter); LTTNG_ASSERT(!ret); call_rcu(®_enum->rcu_head, destroy_enum_rcu); } @@ -695,9 +703,10 @@ void destroy_channel_rcu(struct rcu_head *head) struct ust_registry_channel *chan = caa_container_of(head, struct ust_registry_channel, rcu_head); - if (chan->ht) { - lttng_ht_destroy(chan->ht); + if (chan->events) { + lttng_ht_destroy(chan->events); } + free(chan->ctx_fields); free(chan); } @@ -707,7 +716,7 @@ void destroy_channel_rcu(struct rcu_head *head) * free the registry pointer since it might not have been allocated before so * it's the caller responsability. */ -static void destroy_channel(struct ust_registry_channel *chan, bool notif) +void ust_registry_channel_destroy(struct ust_registry_channel *chan, bool notify) { struct lttng_ht_iter iter; struct ust_registry_event *event; @@ -715,7 +724,7 @@ static void destroy_channel(struct ust_registry_channel *chan, bool notif) LTTNG_ASSERT(chan); - if (notif) { + if (notify) { cmd_ret = notification_thread_command_remove_channel( the_notification_thread_handle, chan->consumer_key, LTTNG_DOMAIN_UST); @@ -724,11 +733,11 @@ static void destroy_channel(struct ust_registry_channel *chan, bool notif) } } - if (chan->ht) { + if (chan->events) { rcu_read_lock(); /* Destroy all event associated with this registry. */ cds_lfht_for_each_entry( - chan->ht->ht, &iter.iter, event, node.node) { + chan->events->ht, &iter.iter, event, node.node) { /* Delete the node from the ht and free it. */ ust_registry_destroy_event(chan, event); } @@ -740,7 +749,7 @@ static void destroy_channel(struct ust_registry_channel *chan, bool notif) /* * Initialize registry with default values. */ -int ust_registry_channel_add(struct ust_registry_session *session, +int ust_registry_channel_add(ust_registry_session *session, uint64_t key) { int ret = 0; @@ -748,29 +757,29 @@ int ust_registry_channel_add(struct ust_registry_session *session, LTTNG_ASSERT(session); - chan = (ust_registry_channel *) zmalloc(sizeof(*chan)); + chan = zmalloc(); if (!chan) { PERROR("zmalloc ust registry channel"); ret = -ENOMEM; goto error_alloc; } - chan->ht = lttng_ht_new(0, LTTNG_HT_TYPE_STRING); - if (!chan->ht) { + chan->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING); + if (!chan->events) { ret = -ENOMEM; goto error; } /* Set custom match function. */ - chan->ht->match_fct = ht_match_event; - chan->ht->hash_fct = ht_hash_event; + chan->events->match_fct = ht_match_event; + chan->events->hash_fct = ht_hash_event; /* * Assign a channel ID right now since the event notification comes * *before* the channel notify so the ID needs to be set at this point so * the metadata can be dumped for that event. */ - if (ust_registry_is_max_id(session->used_channel_id)) { + if (ust_registry_is_max_id(session->_used_channel_id)) { ret = -1; goto error; } @@ -778,13 +787,13 @@ int ust_registry_channel_add(struct ust_registry_session *session, rcu_read_lock(); lttng_ht_node_init_u64(&chan->node, key); - lttng_ht_add_unique_u64(session->channels, &chan->node); + lttng_ht_add_unique_u64(session->_channels.get(), &chan->node); rcu_read_unlock(); return 0; error: - destroy_channel(chan, false); + ust_registry_channel_destroy(chan, false); error_alloc: return ret; } @@ -797,18 +806,19 @@ error_alloc: * On success, the pointer is returned else NULL. */ struct ust_registry_channel *ust_registry_channel_find( - struct ust_registry_session *session, uint64_t key) + ust_registry_session *session, uint64_t key) { struct lttng_ht_node_u64 *node; struct lttng_ht_iter iter; struct ust_registry_channel *chan = NULL; LTTNG_ASSERT(session); - LTTNG_ASSERT(session->channels); + LTTNG_ASSERT(session->_channels); + ASSERT_RCU_READ_LOCKED(); DBG3("UST registry channel finding key %" PRIu64, key); - lttng_ht_lookup(session->channels, &key, &iter); + lttng_ht_lookup(session->_channels.get(), &key, &iter); node = lttng_ht_iter_get_node_u64(&iter); if (!node) { goto end; @@ -822,7 +832,7 @@ end: /* * Remove channel using key from registry and free memory. */ -void ust_registry_channel_del_free(struct ust_registry_session *session, +void ust_registry_channel_del_free(ust_registry_session *session, uint64_t key, bool notif) { struct lttng_ht_iter iter; @@ -839,25 +849,16 @@ void ust_registry_channel_del_free(struct ust_registry_session *session, } iter.iter.node = &chan->node.node; - ret = lttng_ht_del(session->channels, &iter); + ret = lttng_ht_del(session->_channels.get(), &iter); LTTNG_ASSERT(!ret); rcu_read_unlock(); - destroy_channel(chan, notif); + ust_registry_channel_destroy(chan, notif); end: return; } -/* - * Initialize registry with default values and set the newly allocated session - * pointer to sessionp. - * - * Return 0 on success and sessionp is set or else return -1 and sessionp is - * kept untouched. - */ -int ust_registry_session_init(struct ust_registry_session **sessionp, - struct ust_app *app, - uint32_t bits_per_long, +ust_registry_session *ust_registry_session_per_uid_create(uint32_t bits_per_long, uint32_t uint8_t_alignment, uint32_t uint16_t_alignment, uint32_t uint32_t_alignment, @@ -873,170 +874,49 @@ int ust_registry_session_init(struct ust_registry_session **sessionp, uint64_t tracing_id, uid_t tracing_uid) { - int ret; - struct ust_registry_session *session; - - LTTNG_ASSERT(sessionp); - - session = (ust_registry_session *) zmalloc(sizeof(*session)); - if (!session) { - PERROR("zmalloc ust registry session"); - goto error_alloc; - } - - pthread_mutex_init(&session->lock, NULL); - session->bits_per_long = bits_per_long; - session->uint8_t_alignment = uint8_t_alignment; - session->uint16_t_alignment = uint16_t_alignment; - session->uint32_t_alignment = uint32_t_alignment; - session->uint64_t_alignment = uint64_t_alignment; - session->long_alignment = long_alignment; - session->byte_order = byte_order; - session->metadata_fd = -1; - session->uid = euid; - session->gid = egid; - session->next_enum_id = 0; - session->major = major; - session->minor = minor; - strncpy(session->root_shm_path, root_shm_path, - sizeof(session->root_shm_path)); - session->root_shm_path[sizeof(session->root_shm_path) - 1] = '\0'; - if (shm_path[0]) { - strncpy(session->shm_path, shm_path, - sizeof(session->shm_path)); - session->shm_path[sizeof(session->shm_path) - 1] = '\0'; - strncpy(session->metadata_path, shm_path, - sizeof(session->metadata_path)); - session->metadata_path[sizeof(session->metadata_path) - 1] = '\0'; - strncat(session->metadata_path, "/metadata", - sizeof(session->metadata_path) - - strlen(session->metadata_path) - 1); - } - if (session->shm_path[0]) { - ret = run_as_mkdir_recursive(session->shm_path, - S_IRWXU | S_IRWXG, - euid, egid); - if (ret) { - PERROR("run_as_mkdir_recursive"); - goto error; - } - } - if (session->metadata_path[0]) { - /* Create metadata file */ - ret = run_as_open(session->metadata_path, - O_WRONLY | O_CREAT | O_EXCL, - S_IRUSR | S_IWUSR, euid, egid); - if (ret < 0) { - PERROR("Opening metadata file"); - goto error; - } - session->metadata_fd = ret; - } - - session->enums = lttng_ht_new(0, LTTNG_HT_TYPE_STRING); - if (!session->enums) { - ERR("Failed to create enums hash table"); - goto error; - } - /* hash/match functions are specified at call site. */ - session->enums->match_fct = NULL; - session->enums->hash_fct = NULL; - - session->channels = lttng_ht_new(0, LTTNG_HT_TYPE_U64); - if (!session->channels) { - goto error; + try { + return new ust_registry_session_per_uid(bits_per_long, uint8_t_alignment, + uint16_t_alignment, uint32_t_alignment, uint64_t_alignment, + long_alignment, byte_order, major, minor, root_shm_path, shm_path, + euid, egid, tracing_id, tracing_uid); + } catch (const std::exception &ex) { + ERR("Failed to create per-uid registry session: %s", ex.what()); + return nullptr; } +} - ret = lttng_uuid_generate(session->uuid); - if (ret) { - ERR("Failed to generate UST uuid (errno = %d)", ret); - goto error; - } - - session->tracing_id = tracing_id; - session->tracing_uid = tracing_uid; - - pthread_mutex_lock(&session->lock); - ret = ust_metadata_session_statedump(session, app, major, minor); - pthread_mutex_unlock(&session->lock); - if (ret) { - ERR("Failed to generate session metadata (errno = %d)", ret); - goto error; +ust_registry_session *ust_registry_session_per_pid_create(struct ust_app *app, + uint32_t bits_per_long, + uint32_t uint8_t_alignment, + uint32_t uint16_t_alignment, + uint32_t uint32_t_alignment, + uint32_t uint64_t_alignment, + uint32_t long_alignment, + int byte_order, + uint32_t major, + uint32_t minor, + const char *root_shm_path, + const char *shm_path, + uid_t euid, + gid_t egid, + uint64_t tracing_id) +{ + try { + return new ust_registry_session_per_pid(*app, bits_per_long, uint8_t_alignment, + uint16_t_alignment, uint32_t_alignment, uint64_t_alignment, + long_alignment, byte_order, major, minor, root_shm_path, shm_path, + euid, egid, tracing_id); + } catch (const std::exception &ex) { + ERR("Failed to create per-pid registry session: %s", ex.what()); + return nullptr; } - - *sessionp = session; - - return 0; - -error: - ust_registry_session_destroy(session); - free(session); -error_alloc: - return -1; } /* * Destroy session registry. This does NOT free the given pointer since it * might get passed as a reference. The registry lock should NOT be acquired. */ -void ust_registry_session_destroy(struct ust_registry_session *reg) +void ust_registry_session_destroy(ust_registry_session *reg) { - int ret; - struct lttng_ht_iter iter; - struct ust_registry_channel *chan; - struct ust_registry_enum *reg_enum; - - if (!reg) { - return; - } - - /* On error, EBUSY can be returned if lock. Code flow error. */ - ret = pthread_mutex_destroy(®->lock); - LTTNG_ASSERT(!ret); - - if (reg->channels) { - rcu_read_lock(); - /* Destroy all event associated with this registry. */ - cds_lfht_for_each_entry(reg->channels->ht, &iter.iter, chan, - node.node) { - /* Delete the node from the ht and free it. */ - ret = lttng_ht_del(reg->channels, &iter); - LTTNG_ASSERT(!ret); - destroy_channel(chan, true); - } - rcu_read_unlock(); - lttng_ht_destroy(reg->channels); - } - - free(reg->metadata); - if (reg->metadata_fd >= 0) { - ret = close(reg->metadata_fd); - if (ret) { - PERROR("close"); - } - ret = run_as_unlink(reg->metadata_path, - reg->uid, reg->gid); - if (ret) { - PERROR("unlink"); - } - } - if (reg->root_shm_path[0]) { - /* - * Try deleting the directory hierarchy. - */ - (void) run_as_rmdir_recursive(reg->root_shm_path, - reg->uid, reg->gid, - LTTNG_DIRECTORY_HANDLE_SKIP_NON_EMPTY_FLAG); - } - /* Destroy the enum hash table */ - if (reg->enums) { - rcu_read_lock(); - /* Destroy all enum entries associated with this registry. */ - cds_lfht_for_each_entry(reg->enums->ht, &iter.iter, reg_enum, - node.node) { - ust_registry_destroy_enum(reg, reg_enum); - } - rcu_read_unlock(); - lttng_ht_destroy(reg->enums); - } + delete reg; }