2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <common/common.h>
21 #include "ust-registry.h"
24 * Hash table match function for event in the registry.
26 static int ht_match_event(struct cds_lfht_node
*node
, const void *_key
)
28 struct ust_registry_event
*event
;
29 const struct ust_registry_event
*key
;
34 event
= caa_container_of(node
, struct ust_registry_event
, node
.node
);
38 /* It has to be a perfect match. */
39 if (strncmp(event
->name
, key
->name
, sizeof(event
->name
)) != 0) {
43 /* It has to be a perfect match. */
44 if (strncmp(event
->signature
, key
->signature
,
45 strlen(event
->signature
) != 0)) {
57 * Allocate event and initialize it. This does NOT set a valid event id from a
60 static struct ust_registry_event
*alloc_event(int session_objd
,
61 int channel_objd
, char *name
, char *sig
, size_t nr_fields
,
62 struct ustctl_field
*fields
, int loglevel
, char *model_emf_uri
)
64 struct ust_registry_event
*event
= NULL
;
66 event
= zmalloc(sizeof(*event
));
68 PERROR("zmalloc ust registry event");
72 event
->session_objd
= session_objd
;
73 event
->channel_objd
= channel_objd
;
74 /* Allocated by ustctl. */
75 event
->signature
= sig
;
76 event
->nr_fields
= nr_fields
;
77 event
->fields
= fields
;
78 event
->loglevel
= loglevel
;
79 event
->model_emf_uri
= model_emf_uri
;
81 /* Copy event name and force NULL byte. */
82 strncpy(event
->name
, name
, sizeof(event
->name
));
83 event
->name
[sizeof(event
->name
) - 1] = '\0';
85 lttng_ht_node_init_str(&event
->node
, event
->name
);
92 * Free event data structure. This does NOT delete it from any hash table. It's
93 * safe to pass a NULL pointer. This shoudl be called inside a call RCU if the
94 * event is previously deleted from a rcu hash table.
96 static void destroy_event(struct ust_registry_event
*event
)
103 free(event
->model_emf_uri
);
104 free(event
->signature
);
109 * Destroy event function call of the call RCU.
111 static void destroy_event_rcu(struct rcu_head
*head
)
113 struct lttng_ht_node_str
*node
=
114 caa_container_of(head
, struct lttng_ht_node_str
, head
);
115 struct ust_registry_event
*event
=
116 caa_container_of(node
, struct ust_registry_event
, node
);
118 destroy_event(event
);
122 * Find an event using the name and signature in the given registry. RCU read
123 * side lock MUST be acquired before calling this function and as long as the
124 * event reference is kept by the caller.
126 * On success, the event pointer is returned else NULL.
128 struct ust_registry_event
*ust_registry_find_event(
129 struct ust_registry_channel
*chan
, char *name
, char *sig
)
131 struct lttng_ht_node_str
*node
;
132 struct lttng_ht_iter iter
;
133 struct ust_registry_event
*event
= NULL
;
134 struct ust_registry_event key
;
140 /* Setup key for the match function. */
141 strncpy(key
.name
, name
, sizeof(key
.name
));
142 key
.name
[sizeof(key
.name
) - 1] = '\0';
145 cds_lfht_lookup(chan
->ht
->ht
, chan
->ht
->hash_fct(name
, lttng_ht_seed
),
146 chan
->ht
->match_fct
, &key
, &iter
.iter
);
147 node
= lttng_ht_iter_get_node_str(&iter
);
151 event
= caa_container_of(node
, struct ust_registry_event
, node
);
158 * Create a ust_registry_event from the given parameters and add it to the
159 * registry hash table. If event_id is valid, it is set with the newly created
162 * On success, return 0 else a negative value. The created event MUST be unique
163 * so on duplicate entry -EINVAL is returned. On error, event_id is untouched.
165 * Should be called with session registry mutex held.
167 int ust_registry_create_event(struct ust_registry_session
*session
,
168 struct ust_registry_channel
*chan
,
169 int session_objd
, int channel_objd
, char *name
, char *sig
,
170 size_t nr_fields
, struct ustctl_field
*fields
, int loglevel
,
171 char *model_emf_uri
, uint32_t *event_id
)
174 struct cds_lfht_node
*nptr
;
175 struct ust_registry_event
*event
= NULL
;
183 * This should not happen but since it comes from the UST tracer, an
184 * external party, don't assert and simply validate values.
186 if (session_objd
< 0 || channel_objd
< 0) {
191 /* Check if we've reached the maximum possible id. */
192 if (ust_registry_is_max_id(chan
->used_event_id
)) {
197 event
= alloc_event(session_objd
, channel_objd
, name
, sig
, nr_fields
,
198 fields
, loglevel
, model_emf_uri
);
204 event
->id
= ust_registry_get_next_event_id(chan
);
206 DBG3("UST registry creating event with event: %s, sig: %s, id: %u, "
207 "chan_objd: %u, sess_objd: %u", event
->name
, event
->signature
,
208 event
->id
, event
->channel_objd
, event
->session_objd
);
212 * This is an add unique with a custom match function for event. The node
213 * are matched using the event name and signature.
215 nptr
= cds_lfht_add_unique(chan
->ht
->ht
, chan
->ht
->hash_fct(event
->node
.key
,
216 lttng_ht_seed
), chan
->ht
->match_fct
, event
, &event
->node
.node
);
217 if (nptr
!= &event
->node
.node
) {
218 ERR("UST registry create event add unique failed for event: %s, "
219 "sig: %s, id: %u, chan_objd: %u, sess_objd: %u", event
->name
,
220 event
->signature
, event
->id
, event
->channel_objd
,
221 event
->session_objd
);
226 /* Set event id if user wants it. */
228 *event_id
= event
->id
;
232 /* Append to metadata */
233 ret
= ust_metadata_event_statedump(session
, chan
, event
);
235 ERR("Error appending event metadata (errno = %d)", ret
);
244 destroy_event(event
);
249 * For a given event in a registry, delete the entry and destroy the event.
250 * This MUST be called within a RCU read side lock section.
252 void ust_registry_destroy_event(struct ust_registry_channel
*chan
,
253 struct ust_registry_event
*event
)
256 struct lttng_ht_iter iter
;
261 /* Delete the node first. */
262 iter
.iter
.node
= &event
->node
.node
;
263 ret
= lttng_ht_del(chan
->ht
, &iter
);
266 call_rcu(&event
->node
.head
, destroy_event_rcu
);
272 * Initialize registry with default values.
274 void ust_registry_channel_init(struct ust_registry_session
*session
,
275 struct ust_registry_channel
*chan
)
279 memset(chan
, 0, sizeof(struct ust_registry_channel
));
281 chan
->ht
= lttng_ht_new(0, LTTNG_HT_TYPE_STRING
);
284 /* Set custom match function. */
285 chan
->ht
->match_fct
= ht_match_event
;
289 * Destroy every element of the registry and free the memory. This does NOT
290 * free the registry pointer since it might not have been allocated before so
291 * it's the caller responsability.
293 * This MUST be called within a RCU read side lock section.
295 void ust_registry_channel_destroy(struct ust_registry_session
*session
,
296 struct ust_registry_channel
*chan
)
298 struct lttng_ht_iter iter
;
299 struct ust_registry_event
*event
;
303 /* Destroy all event associated with this registry. */
304 cds_lfht_for_each_entry(chan
->ht
->ht
, &iter
.iter
, event
, node
.node
) {
305 /* Delete the node from the ht and free it. */
306 ust_registry_destroy_event(chan
, event
);
308 lttng_ht_destroy(chan
->ht
);
312 * Initialize registry with default values.
314 int ust_registry_session_init(struct ust_registry_session
*session
,
316 uint32_t bits_per_long
,
317 uint32_t uint8_t_alignment
,
318 uint32_t uint16_t_alignment
,
319 uint32_t uint32_t_alignment
,
320 uint32_t uint64_t_alignment
,
321 uint32_t long_alignment
,
328 memset(session
, 0, sizeof(struct ust_registry_session
));
330 pthread_mutex_init(&session
->lock
, NULL
);
331 session
->bits_per_long
= bits_per_long
;
332 session
->uint8_t_alignment
= uint8_t_alignment
;
333 session
->uint16_t_alignment
= uint16_t_alignment
;
334 session
->uint32_t_alignment
= uint32_t_alignment
;
335 session
->uint64_t_alignment
= uint64_t_alignment
;
336 session
->long_alignment
= long_alignment
;
337 session
->byte_order
= byte_order
;
339 ret
= lttng_uuid_generate(session
->uuid
);
341 ERR("Failed to generate UST uuid (errno = %d)", ret
);
345 pthread_mutex_lock(&session
->lock
);
346 ret
= ust_metadata_session_statedump(session
, app
);
347 pthread_mutex_unlock(&session
->lock
);
349 ERR("Failed to generate session metadata (errno = %d)", ret
);
360 * Destroy session registry. This does NOT free the given pointer since it
361 * might get passed as a reference. The registry lock should NOT be acquired.
363 void ust_registry_session_destroy(struct ust_registry_session
*reg
)
367 /* On error, EBUSY can be returned if lock. Code flow error. */
368 ret
= pthread_mutex_destroy(®
->lock
);
This page took 0.04085 seconds and 6 git commands to generate.