Clean-up: sessiond: return an lttng_error_code from list_triggers
[lttng-tools.git] / src / bin / lttng-sessiond / agent.c
1 /*
2 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
3 * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 */
8
9 #define _LGPL_SOURCE
10 #include <assert.h>
11 #include <urcu/uatomic.h>
12 #include <urcu/rculist.h>
13
14 #include <lttng/event-rule/event-rule.h>
15 #include <lttng/event-rule/event-rule-internal.h>
16 #include <lttng/event-rule/jul-logging.h>
17 #include <lttng/event-rule/log4j-logging.h>
18 #include <lttng/event-rule/python-logging.h>
19 #include <lttng/condition/condition.h>
20 #include <lttng/condition/event-rule-matches.h>
21 #include <lttng/domain-internal.h>
22 #include <lttng/log-level-rule-internal.h>
23
24 #include <common/common.h>
25 #include <common/sessiond-comm/agent.h>
26
27 #include <common/compat/endian.h>
28
29 #include "agent.h"
30 #include "ust-app.h"
31 #include "utils.h"
32 #include "common/error.h"
33
34 #define AGENT_RET_CODE_INDEX(code) (code - AGENT_RET_CODE_SUCCESS)
35
36 typedef enum lttng_event_rule_status (*event_rule_logging_get_name_pattern)(
37 const struct lttng_event_rule *rule, const char **pattern);
38 typedef enum lttng_event_rule_status (*event_rule_logging_get_log_level_rule)(
39 const struct lttng_event_rule *rule,
40 const struct lttng_log_level_rule **log_level_rule);
41
42 /*
43 * Agent application context representation.
44 */
45 struct agent_app_ctx {
46 char *provider_name;
47 char *ctx_name;
48
49 /* agent_app_ctx are part of the agent app_ctx_list. */
50 struct cds_list_head list_node;
51
52 /* For call_rcu teardown. */
53 struct rcu_head rcu_node;
54 };
55
56 /*
57 * Human readable agent return code.
58 */
59 static const char *error_string_array[] = {
60 [ AGENT_RET_CODE_INDEX(AGENT_RET_CODE_SUCCESS) ] = "Success",
61 [ AGENT_RET_CODE_INDEX(AGENT_RET_CODE_INVALID) ] = "Invalid command",
62 [ AGENT_RET_CODE_INDEX(AGENT_RET_CODE_UNKNOWN_NAME) ] = "Unknown logger name",
63
64 /* Last element */
65 [ AGENT_RET_CODE_INDEX(AGENT_RET_CODE_NR) ] = "Unknown code",
66 };
67
68 static
69 void log_reply_code(uint32_t in_reply_ret_code)
70 {
71 int level = PRINT_DBG3;
72 /*
73 * reply_ret_code and in_reply_ret_code are kept separate to have a
74 * sanitized value (used to retrieve the human readable string) and the
75 * original value which is logged as-is.
76 */
77 uint32_t reply_ret_code = in_reply_ret_code;
78
79 if (reply_ret_code < AGENT_RET_CODE_SUCCESS ||
80 reply_ret_code >= AGENT_RET_CODE_NR) {
81 reply_ret_code = AGENT_RET_CODE_NR;
82 level = PRINT_ERR;
83 }
84
85 LOG(level, "Agent replied with retcode: %s (%"PRIu32")",
86 error_string_array[AGENT_RET_CODE_INDEX(
87 reply_ret_code)],
88 in_reply_ret_code);
89 }
90
91 /*
92 * Match function for the events hash table lookup by name.
93 */
94 static int ht_match_event_by_name(struct cds_lfht_node *node,
95 const void *_key)
96 {
97 struct agent_event *event;
98 const struct agent_ht_key *key;
99
100 assert(node);
101 assert(_key);
102
103 event = caa_container_of(node, struct agent_event, node.node);
104 key = _key;
105
106 /* Match 1 elements of the key: name. */
107
108 /* Event name */
109 if (strncmp(event->name, key->name, sizeof(event->name)) != 0) {
110 goto no_match;
111 }
112 /* Match. */
113 return 1;
114
115 no_match:
116 return 0;
117 }
118
119 /*
120 * Match function for the events hash table lookup by name, log level and
121 * filter expression.
122 */
123 static int ht_match_event(struct cds_lfht_node *node,
124 const void *_key)
125 {
126 struct agent_event *event;
127 const struct agent_ht_key *key;
128 int ll_match;
129
130 assert(node);
131 assert(_key);
132
133 event = caa_container_of(node, struct agent_event, node.node);
134 key = _key;
135
136 /* Match 2 elements of the key: name and loglevel. */
137
138 /* Event name */
139 if (strncmp(event->name, key->name, sizeof(event->name)) != 0) {
140 goto no_match;
141 }
142
143 /* Event loglevel value and type. */
144 ll_match = loglevels_match(event->loglevel_type,
145 event->loglevel_value, key->loglevel_type,
146 key->loglevel_value, LTTNG_EVENT_LOGLEVEL_ALL);
147
148 if (!ll_match) {
149 goto no_match;
150 }
151
152 /* Filter expression */
153 if (!!event->filter_expression != !!key->filter_expression) {
154 /* One has a filter expression, the other does not */
155 goto no_match;
156 }
157
158 if (event->filter_expression) {
159 if (strncmp(event->filter_expression, key->filter_expression,
160 strlen(event->filter_expression)) != 0) {
161 goto no_match;
162 }
163 }
164
165 return 1;
166
167 no_match:
168 return 0;
169 }
170
171 /*
172 * Add unique agent event based on the event name and loglevel.
173 */
174 static void add_unique_agent_event(struct lttng_ht *ht,
175 struct agent_event *event)
176 {
177 struct cds_lfht_node *node_ptr;
178 struct agent_ht_key key;
179
180 assert(ht);
181 assert(ht->ht);
182 assert(event);
183
184 key.name = event->name;
185 key.loglevel_value = event->loglevel_value;
186 key.loglevel_type = event->loglevel_type;
187 key.filter_expression = event->filter_expression;
188
189 node_ptr = cds_lfht_add_unique(ht->ht,
190 ht->hash_fct(event->node.key, lttng_ht_seed),
191 ht_match_event, &key, &event->node.node);
192 assert(node_ptr == &event->node.node);
193 }
194
195 /*
196 * URCU delayed agent event reclaim.
197 */
198 static void destroy_event_agent_rcu(struct rcu_head *head)
199 {
200 struct lttng_ht_node_str *node =
201 caa_container_of(head, struct lttng_ht_node_str, head);
202 struct agent_event *event =
203 caa_container_of(node, struct agent_event, node);
204
205 agent_destroy_event(event);
206 }
207
208 /*
209 * URCU delayed agent app reclaim.
210 */
211 static void destroy_app_agent_rcu(struct rcu_head *head)
212 {
213 struct lttng_ht_node_ulong *node =
214 caa_container_of(head, struct lttng_ht_node_ulong, head);
215 struct agent_app *app =
216 caa_container_of(node, struct agent_app, node);
217
218 free(app);
219 }
220
221 /*
222 * Communication with the agent. Send the message header to the given socket in
223 * big endian.
224 *
225 * Return 0 on success or else a negative errno message of sendmsg() op.
226 */
227 static int send_header(struct lttcomm_sock *sock, uint64_t data_size,
228 uint32_t cmd, uint32_t cmd_version)
229 {
230 int ret;
231 ssize_t size;
232 struct lttcomm_agent_hdr msg;
233
234 assert(sock);
235
236 memset(&msg, 0, sizeof(msg));
237 msg.data_size = htobe64(data_size);
238 msg.cmd = htobe32(cmd);
239 msg.cmd_version = htobe32(cmd_version);
240
241 size = sock->ops->sendmsg(sock, &msg, sizeof(msg), 0);
242 if (size < sizeof(msg)) {
243 ret = -errno;
244 goto error;
245 }
246 ret = 0;
247
248 error:
249 return ret;
250 }
251
252 /*
253 * Communication call with the agent. Send the payload to the given socket. The
254 * header MUST be sent prior to this call.
255 *
256 * Return 0 on success or else a negative errno value of sendmsg() op.
257 */
258 static int send_payload(struct lttcomm_sock *sock, const void *data,
259 size_t size)
260 {
261 int ret;
262 ssize_t len;
263
264 assert(sock);
265 assert(data);
266
267 len = sock->ops->sendmsg(sock, data, size, 0);
268 if (len < size) {
269 ret = -errno;
270 goto error;
271 }
272 ret = 0;
273
274 error:
275 return ret;
276 }
277
278 /*
279 * Communication call with the agent. Receive reply from the agent using the
280 * given socket.
281 *
282 * Return 0 on success or else a negative errno value from recvmsg() op.
283 */
284 static int recv_reply(struct lttcomm_sock *sock, void *buf, size_t size)
285 {
286 int ret;
287 ssize_t len;
288
289 assert(sock);
290 assert(buf);
291
292 len = sock->ops->recvmsg(sock, buf, size, 0);
293 if (len < size) {
294 ret = -errno;
295 goto error;
296 }
297 ret = 0;
298
299 error:
300 return ret;
301 }
302
303 /*
304 * Internal event listing for a given app. Populate events.
305 *
306 * Return number of element in the list or else a negative LTTNG_ERR* code.
307 * On success, the caller is responsible for freeing the memory
308 * allocated for "events".
309 */
310 static ssize_t list_events(struct agent_app *app, struct lttng_event **events)
311 {
312 int ret, i, len = 0, offset = 0;
313 uint32_t nb_event;
314 size_t data_size;
315 uint32_t reply_ret_code;
316 struct lttng_event *tmp_events = NULL;
317 struct lttcomm_agent_list_reply *reply = NULL;
318 struct lttcomm_agent_list_reply_hdr reply_hdr;
319
320 assert(app);
321 assert(app->sock);
322 assert(events);
323
324 DBG2("Agent listing events for app pid: %d and socket %d", app->pid,
325 app->sock->fd);
326
327 ret = send_header(app->sock, 0, AGENT_CMD_LIST, 0);
328 if (ret < 0) {
329 goto error_io;
330 }
331
332 /* Get list header so we know how much we'll receive. */
333 ret = recv_reply(app->sock, &reply_hdr, sizeof(reply_hdr));
334 if (ret < 0) {
335 goto error_io;
336 }
337
338 reply_ret_code = be32toh(reply_hdr.ret_code);
339 log_reply_code(reply_ret_code);
340 switch (reply_ret_code) {
341 case AGENT_RET_CODE_SUCCESS:
342 data_size = be32toh(reply_hdr.data_size) + sizeof(*reply);
343 break;
344 default:
345 ret = LTTNG_ERR_UNK;
346 goto error;
347 }
348
349 reply = zmalloc(data_size);
350 if (!reply) {
351 ret = LTTNG_ERR_NOMEM;
352 goto error;
353 }
354
355 /* Get the list with the appropriate data size. */
356 ret = recv_reply(app->sock, reply, data_size);
357 if (ret < 0) {
358 goto error_io;
359 }
360
361 nb_event = be32toh(reply->nb_event);
362 tmp_events = zmalloc(sizeof(*tmp_events) * nb_event);
363 if (!tmp_events) {
364 ret = LTTNG_ERR_NOMEM;
365 goto error;
366 }
367
368 for (i = 0; i < nb_event; i++) {
369 offset += len;
370 if (lttng_strncpy(tmp_events[i].name, reply->payload + offset,
371 sizeof(tmp_events[i].name))) {
372 ret = LTTNG_ERR_INVALID;
373 goto error;
374 }
375 tmp_events[i].pid = app->pid;
376 tmp_events[i].enabled = -1;
377 len = strlen(reply->payload + offset) + 1;
378 }
379
380 *events = tmp_events;
381
382 free(reply);
383 return nb_event;
384
385 error_io:
386 ret = LTTNG_ERR_UST_LIST_FAIL;
387 error:
388 free(reply);
389 free(tmp_events);
390 return -ret;
391
392 }
393
394 /*
395 * Internal enable agent event on a agent application. This function
396 * communicates with the agent to enable a given event.
397 *
398 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
399 */
400 static int enable_event(const struct agent_app *app, struct agent_event *event)
401 {
402 int ret;
403 char *bytes_to_send;
404 uint64_t data_size;
405 size_t filter_expression_length;
406 uint32_t reply_ret_code;
407 struct lttcomm_agent_enable_event msg;
408 struct lttcomm_agent_generic_reply reply;
409
410 assert(app);
411 assert(app->sock);
412 assert(event);
413
414 DBG2("Agent enabling event %s for app pid: %d and socket %d", event->name,
415 app->pid, app->sock->fd);
416
417 /*
418 * Calculate the payload's size, which is the fixed-size struct followed
419 * by the variable-length filter expression (+1 for the ending \0).
420 */
421 if (!event->filter_expression) {
422 filter_expression_length = 0;
423 } else {
424 filter_expression_length = strlen(event->filter_expression) + 1;
425 }
426 data_size = sizeof(msg) + filter_expression_length;
427
428 memset(&msg, 0, sizeof(msg));
429 msg.loglevel_value = htobe32(event->loglevel_value);
430 msg.loglevel_type = htobe32(event->loglevel_type);
431 if (lttng_strncpy(msg.name, event->name, sizeof(msg.name))) {
432 ret = LTTNG_ERR_INVALID;
433 goto error;
434 }
435 msg.filter_expression_length = htobe32(filter_expression_length);
436
437 ret = send_header(app->sock, data_size, AGENT_CMD_ENABLE, 0);
438 if (ret < 0) {
439 goto error_io;
440 }
441
442 bytes_to_send = zmalloc(data_size);
443 if (!bytes_to_send) {
444 ret = LTTNG_ERR_NOMEM;
445 goto error;
446 }
447
448 memcpy(bytes_to_send, &msg, sizeof(msg));
449 if (filter_expression_length > 0) {
450 memcpy(bytes_to_send + sizeof(msg), event->filter_expression,
451 filter_expression_length);
452 }
453
454 ret = send_payload(app->sock, bytes_to_send, data_size);
455 free(bytes_to_send);
456 if (ret < 0) {
457 goto error_io;
458 }
459
460 ret = recv_reply(app->sock, &reply, sizeof(reply));
461 if (ret < 0) {
462 goto error_io;
463 }
464
465 reply_ret_code = be32toh(reply.ret_code);
466 log_reply_code(reply_ret_code);
467 switch (reply_ret_code) {
468 case AGENT_RET_CODE_SUCCESS:
469 break;
470 case AGENT_RET_CODE_UNKNOWN_NAME:
471 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
472 goto error;
473 default:
474 ret = LTTNG_ERR_UNK;
475 goto error;
476 }
477
478 return LTTNG_OK;
479
480 error_io:
481 ret = LTTNG_ERR_UST_ENABLE_FAIL;
482 error:
483 return ret;
484 }
485
486 /*
487 * Send Pascal-style string. Size is sent as a 32-bit big endian integer.
488 */
489 static
490 int send_pstring(struct lttcomm_sock *sock, const char *str, uint32_t len)
491 {
492 int ret;
493 uint32_t len_be;
494
495 len_be = htobe32(len);
496 ret = send_payload(sock, &len_be, sizeof(len_be));
497 if (ret) {
498 goto end;
499 }
500
501 ret = send_payload(sock, str, len);
502 if (ret) {
503 goto end;
504 }
505 end:
506 return ret;
507 }
508
509 /*
510 * Internal enable application context on an agent application. This function
511 * communicates with the agent to enable a given application context.
512 *
513 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
514 */
515 static int app_context_op(const struct agent_app *app,
516 const struct agent_app_ctx *ctx, enum lttcomm_agent_command cmd)
517 {
518 int ret;
519 uint32_t reply_ret_code;
520 struct lttcomm_agent_generic_reply reply;
521 size_t app_ctx_provider_name_len, app_ctx_name_len, data_size;
522
523 assert(app);
524 assert(app->sock);
525 assert(ctx);
526 assert(cmd == AGENT_CMD_APP_CTX_ENABLE ||
527 cmd == AGENT_CMD_APP_CTX_DISABLE);
528
529 DBG2("Agent %s application %s:%s for app pid: %d and socket %d",
530 cmd == AGENT_CMD_APP_CTX_ENABLE ? "enabling" : "disabling",
531 ctx->provider_name, ctx->ctx_name,
532 app->pid, app->sock->fd);
533
534 /*
535 * Calculate the payload's size, which consists of the size (u32, BE)
536 * of the provider name, the NULL-terminated provider name string, the
537 * size (u32, BE) of the context name, followed by the NULL-terminated
538 * context name string.
539 */
540 app_ctx_provider_name_len = strlen(ctx->provider_name) + 1;
541 app_ctx_name_len = strlen(ctx->ctx_name) + 1;
542 data_size = sizeof(uint32_t) + app_ctx_provider_name_len +
543 sizeof(uint32_t) + app_ctx_name_len;
544
545 ret = send_header(app->sock, data_size, cmd, 0);
546 if (ret < 0) {
547 goto error_io;
548 }
549
550 if (app_ctx_provider_name_len > UINT32_MAX ||
551 app_ctx_name_len > UINT32_MAX) {
552 ERR("Application context name > MAX_UINT32");
553 ret = LTTNG_ERR_INVALID;
554 goto error;
555 }
556
557 ret = send_pstring(app->sock, ctx->provider_name,
558 (uint32_t) app_ctx_provider_name_len);
559 if (ret < 0) {
560 goto error_io;
561 }
562
563 ret = send_pstring(app->sock, ctx->ctx_name,
564 (uint32_t) app_ctx_name_len);
565 if (ret < 0) {
566 goto error_io;
567 }
568
569 ret = recv_reply(app->sock, &reply, sizeof(reply));
570 if (ret < 0) {
571 goto error_io;
572 }
573
574 reply_ret_code = be32toh(reply.ret_code);
575 log_reply_code(reply_ret_code);
576 switch (reply_ret_code) {
577 case AGENT_RET_CODE_SUCCESS:
578 break;
579 default:
580 ret = LTTNG_ERR_UNK;
581 goto error;
582 }
583
584 return LTTNG_OK;
585
586 error_io:
587 ret = LTTNG_ERR_UST_ENABLE_FAIL;
588 error:
589 return ret;
590 }
591
592 /*
593 * Internal disable agent event call on a agent application. This function
594 * communicates with the agent to disable a given event.
595 *
596 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
597 */
598 static int disable_event(struct agent_app *app, struct agent_event *event)
599 {
600 int ret;
601 uint64_t data_size;
602 uint32_t reply_ret_code;
603 struct lttcomm_agent_disable_event msg;
604 struct lttcomm_agent_generic_reply reply;
605
606 assert(app);
607 assert(app->sock);
608 assert(event);
609
610 DBG2("Agent disabling event %s for app pid: %d and socket %d", event->name,
611 app->pid, app->sock->fd);
612
613 data_size = sizeof(msg);
614 memset(&msg, 0, sizeof(msg));
615 if (lttng_strncpy(msg.name, event->name, sizeof(msg.name))) {
616 ret = LTTNG_ERR_INVALID;
617 goto error;
618 }
619
620 ret = send_header(app->sock, data_size, AGENT_CMD_DISABLE, 0);
621 if (ret < 0) {
622 goto error_io;
623 }
624
625 ret = send_payload(app->sock, &msg, sizeof(msg));
626 if (ret < 0) {
627 goto error_io;
628 }
629
630 ret = recv_reply(app->sock, &reply, sizeof(reply));
631 if (ret < 0) {
632 goto error_io;
633 }
634
635 reply_ret_code = be32toh(reply.ret_code);
636 log_reply_code(reply_ret_code);
637 switch (reply_ret_code) {
638 case AGENT_RET_CODE_SUCCESS:
639 break;
640 case AGENT_RET_CODE_UNKNOWN_NAME:
641 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
642 goto error;
643 default:
644 ret = LTTNG_ERR_UNK;
645 goto error;
646 }
647
648 return LTTNG_OK;
649
650 error_io:
651 ret = LTTNG_ERR_UST_DISABLE_FAIL;
652 error:
653 return ret;
654 }
655
656 /*
657 * Send back the registration DONE command to a given agent application.
658 *
659 * Return 0 on success or else a negative value.
660 */
661 int agent_send_registration_done(struct agent_app *app)
662 {
663 assert(app);
664 assert(app->sock);
665
666 DBG("Agent sending registration done to app socket %d", app->sock->fd);
667
668 return send_header(app->sock, 0, AGENT_CMD_REG_DONE, 0);
669 }
670
671 /*
672 * Enable agent event on every agent applications registered with the session
673 * daemon.
674 *
675 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
676 */
677 int agent_enable_event(struct agent_event *event,
678 enum lttng_domain_type domain)
679 {
680 int ret;
681 struct agent_app *app;
682 struct lttng_ht_iter iter;
683
684 assert(event);
685
686 rcu_read_lock();
687
688 cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
689 node.node) {
690 if (app->domain != domain) {
691 continue;
692 }
693
694 /* Enable event on agent application through TCP socket. */
695 ret = enable_event(app, event);
696 if (ret != LTTNG_OK) {
697 goto error;
698 }
699 }
700
701 event->enabled_count++;
702 ret = LTTNG_OK;
703
704 error:
705 rcu_read_unlock();
706 return ret;
707 }
708
709 static
710 void destroy_app_ctx(struct agent_app_ctx *ctx)
711 {
712 free(ctx->provider_name);
713 free(ctx->ctx_name);
714 free(ctx);
715 }
716
717 static
718 struct agent_app_ctx *create_app_ctx(const struct lttng_event_context *ctx)
719 {
720 struct agent_app_ctx *agent_ctx = NULL;
721
722 if (!ctx) {
723 goto end;
724 }
725
726 assert(ctx->ctx == LTTNG_EVENT_CONTEXT_APP_CONTEXT);
727 agent_ctx = zmalloc(sizeof(*ctx));
728 if (!agent_ctx) {
729 goto end;
730 }
731
732 agent_ctx->provider_name = strdup(ctx->u.app_ctx.provider_name);
733 agent_ctx->ctx_name = strdup(ctx->u.app_ctx.ctx_name);
734 if (!agent_ctx->provider_name || !agent_ctx->ctx_name) {
735 destroy_app_ctx(agent_ctx);
736 agent_ctx = NULL;
737 }
738 end:
739 return agent_ctx;
740 }
741
742 /*
743 * Enable agent context on every agent applications registered with the session
744 * daemon.
745 *
746 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
747 */
748 int agent_enable_context(const struct lttng_event_context *ctx,
749 enum lttng_domain_type domain)
750 {
751 int ret;
752 struct agent_app *app;
753 struct lttng_ht_iter iter;
754
755 assert(ctx);
756 if (ctx->ctx != LTTNG_EVENT_CONTEXT_APP_CONTEXT) {
757 ret = LTTNG_ERR_INVALID;
758 goto error;
759 }
760
761 rcu_read_lock();
762
763 cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
764 node.node) {
765 struct agent_app_ctx *agent_ctx;
766
767 if (app->domain != domain) {
768 continue;
769 }
770
771 agent_ctx = create_app_ctx(ctx);
772 if (!agent_ctx) {
773 ret = LTTNG_ERR_NOMEM;
774 goto error_unlock;
775 }
776
777 /* Enable event on agent application through TCP socket. */
778 ret = app_context_op(app, agent_ctx, AGENT_CMD_APP_CTX_ENABLE);
779 destroy_app_ctx(agent_ctx);
780 if (ret != LTTNG_OK) {
781 goto error_unlock;
782 }
783 }
784
785 ret = LTTNG_OK;
786
787 error_unlock:
788 rcu_read_unlock();
789 error:
790 return ret;
791 }
792
793 /*
794 * Disable agent event on every agent application registered with the session
795 * daemon.
796 *
797 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
798 */
799 int agent_disable_event(struct agent_event *event,
800 enum lttng_domain_type domain)
801 {
802 int ret = LTTNG_OK;
803 struct agent_app *app;
804 struct lttng_ht_iter iter;
805
806 assert(event);
807 if (!AGENT_EVENT_IS_ENABLED(event)) {
808 goto end;
809 }
810
811 if (--event->enabled_count != 0) {
812 /*
813 * Agent event still enabled. Disable the agent event only when
814 * all "users" have disabled it (event notifiers, event rules,
815 * etc.).
816 */
817 ret = LTTNG_OK;
818 goto end;
819 }
820
821 rcu_read_lock();
822
823 cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
824 node.node) {
825 if (app->domain != domain) {
826 continue;
827 }
828
829 /* Enable event on agent application through TCP socket. */
830 ret = disable_event(app, event);
831 if (ret != LTTNG_OK) {
832 goto error;
833 }
834 }
835
836 /* event->enabled_count is now 0. */
837 assert(!AGENT_EVENT_IS_ENABLED(event));
838
839 error:
840 rcu_read_unlock();
841 end:
842 return ret;
843 }
844
845 /*
846 * Disable agent context on every agent application registered with the session
847 * daemon.
848 *
849 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
850 */
851 static int disable_context(struct agent_app_ctx *ctx,
852 enum lttng_domain_type domain)
853 {
854 int ret = LTTNG_OK;
855 struct agent_app *app;
856 struct lttng_ht_iter iter;
857
858 assert(ctx);
859
860 rcu_read_lock();
861 DBG2("Disabling agent application context %s:%s",
862 ctx->provider_name, ctx->ctx_name);
863 cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
864 node.node) {
865 if (app->domain != domain) {
866 continue;
867 }
868
869 ret = app_context_op(app, ctx, AGENT_CMD_APP_CTX_DISABLE);
870 if (ret != LTTNG_OK) {
871 goto end;
872 }
873 }
874 end:
875 rcu_read_unlock();
876 return ret;
877 }
878
879 /*
880 * Ask every agent for the list of possible event. Events is allocated with the
881 * events of every agent application.
882 *
883 * Return the number of events or else a negative value.
884 */
885 int agent_list_events(struct lttng_event **events,
886 enum lttng_domain_type domain)
887 {
888 int ret;
889 size_t nbmem, count = 0;
890 struct agent_app *app;
891 struct lttng_event *tmp_events = NULL;
892 struct lttng_ht_iter iter;
893
894 assert(events);
895
896 DBG2("Agent listing events for domain %d", domain);
897
898 nbmem = UST_APP_EVENT_LIST_SIZE;
899 tmp_events = zmalloc(nbmem * sizeof(*tmp_events));
900 if (!tmp_events) {
901 PERROR("zmalloc agent list events");
902 ret = -ENOMEM;
903 goto error;
904 }
905
906 rcu_read_lock();
907 cds_lfht_for_each_entry(the_agent_apps_ht_by_sock->ht, &iter.iter, app,
908 node.node) {
909 ssize_t nb_ev;
910 struct lttng_event *agent_events;
911
912 /* Skip domain not asked by the list. */
913 if (app->domain != domain) {
914 continue;
915 }
916
917 nb_ev = list_events(app, &agent_events);
918 if (nb_ev < 0) {
919 ret = nb_ev;
920 goto error_unlock;
921 }
922
923 if (count + nb_ev > nbmem) {
924 /* In case the realloc fails, we free the memory */
925 struct lttng_event *new_tmp_events;
926 size_t new_nbmem;
927
928 new_nbmem = max_t(size_t, count + nb_ev, nbmem << 1);
929 DBG2("Reallocating agent event list from %zu to %zu entries",
930 nbmem, new_nbmem);
931 new_tmp_events = realloc(tmp_events,
932 new_nbmem * sizeof(*new_tmp_events));
933 if (!new_tmp_events) {
934 PERROR("realloc agent events");
935 ret = -ENOMEM;
936 free(agent_events);
937 goto error_unlock;
938 }
939 /* Zero the new memory */
940 memset(new_tmp_events + nbmem, 0,
941 (new_nbmem - nbmem) * sizeof(*new_tmp_events));
942 nbmem = new_nbmem;
943 tmp_events = new_tmp_events;
944 }
945 memcpy(tmp_events + count, agent_events,
946 nb_ev * sizeof(*tmp_events));
947 free(agent_events);
948 count += nb_ev;
949 }
950 rcu_read_unlock();
951
952 ret = count;
953 *events = tmp_events;
954 return ret;
955
956 error_unlock:
957 rcu_read_unlock();
958 error:
959 free(tmp_events);
960 return ret;
961 }
962
963 /*
964 * Create a agent app object using the given PID.
965 *
966 * Return newly allocated object or else NULL on error.
967 */
968 struct agent_app *agent_create_app(pid_t pid, enum lttng_domain_type domain,
969 struct lttcomm_sock *sock)
970 {
971 struct agent_app *app;
972
973 assert(sock);
974
975 app = zmalloc(sizeof(*app));
976 if (!app) {
977 PERROR("Failed to allocate agent application instance");
978 goto error;
979 }
980
981 app->pid = pid;
982 app->domain = domain;
983 app->sock = sock;
984 lttng_ht_node_init_ulong(&app->node, (unsigned long) app->sock->fd);
985
986 error:
987 return app;
988 }
989
990 /*
991 * Lookup agent app by socket in the global hash table.
992 *
993 * RCU read side lock MUST be acquired.
994 *
995 * Return object if found else NULL.
996 */
997 struct agent_app *agent_find_app_by_sock(int sock)
998 {
999 struct lttng_ht_node_ulong *node;
1000 struct lttng_ht_iter iter;
1001 struct agent_app *app;
1002
1003 assert(sock >= 0);
1004
1005 lttng_ht_lookup(the_agent_apps_ht_by_sock,
1006 (void *) ((unsigned long) sock), &iter);
1007 node = lttng_ht_iter_get_node_ulong(&iter);
1008 if (node == NULL) {
1009 goto error;
1010 }
1011 app = caa_container_of(node, struct agent_app, node);
1012
1013 DBG3("Agent app pid %d found by sock %d.", app->pid, sock);
1014 return app;
1015
1016 error:
1017 DBG3("Agent app NOT found by sock %d.", sock);
1018 return NULL;
1019 }
1020
1021 /*
1022 * Add agent application object to the global hash table.
1023 */
1024 void agent_add_app(struct agent_app *app)
1025 {
1026 assert(app);
1027
1028 DBG3("Agent adding app sock: %d and pid: %d to ht", app->sock->fd, app->pid);
1029 lttng_ht_add_unique_ulong(the_agent_apps_ht_by_sock, &app->node);
1030 }
1031
1032 /*
1033 * Delete agent application from the global hash table.
1034 *
1035 * rcu_read_lock() must be held by the caller.
1036 */
1037 void agent_delete_app(struct agent_app *app)
1038 {
1039 int ret;
1040 struct lttng_ht_iter iter;
1041
1042 assert(app);
1043
1044 DBG3("Agent deleting app pid: %d and sock: %d", app->pid, app->sock->fd);
1045
1046 iter.iter.node = &app->node.node;
1047 ret = lttng_ht_del(the_agent_apps_ht_by_sock, &iter);
1048 assert(!ret);
1049 }
1050
1051 /*
1052 * Destroy an agent application object by detaching it from its corresponding
1053 * UST app if one is connected by closing the socket. Finally, perform a
1054 * delayed memory reclaim.
1055 */
1056 void agent_destroy_app(struct agent_app *app)
1057 {
1058 assert(app);
1059
1060 if (app->sock) {
1061 app->sock->ops->close(app->sock);
1062 lttcomm_destroy_sock(app->sock);
1063 }
1064
1065 call_rcu(&app->node.head, destroy_app_agent_rcu);
1066 }
1067
1068 /*
1069 * Initialize an already allocated agent object.
1070 *
1071 * Return 0 on success or else a negative errno value.
1072 */
1073 int agent_init(struct agent *agt)
1074 {
1075 int ret;
1076
1077 assert(agt);
1078
1079 agt->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
1080 if (!agt->events) {
1081 ret = -ENOMEM;
1082 goto error;
1083 }
1084 lttng_ht_node_init_u64(&agt->node, agt->domain);
1085
1086 CDS_INIT_LIST_HEAD(&agt->app_ctx_list);
1087 return 0;
1088
1089 error:
1090 return ret;
1091 }
1092
1093 /*
1094 * Add agent object to the given hash table.
1095 */
1096 void agent_add(struct agent *agt, struct lttng_ht *ht)
1097 {
1098 assert(agt);
1099 assert(ht);
1100
1101 DBG3("Agent adding from domain %d", agt->domain);
1102
1103 lttng_ht_add_unique_u64(ht, &agt->node);
1104 }
1105
1106 /*
1107 * Create an agent object for the given domain.
1108 *
1109 * Return the allocated agent or NULL on error.
1110 */
1111 struct agent *agent_create(enum lttng_domain_type domain)
1112 {
1113 int ret;
1114 struct agent *agt;
1115
1116 agt = zmalloc(sizeof(struct agent));
1117 if (!agt) {
1118 goto error;
1119 }
1120 agt->domain = domain;
1121
1122 ret = agent_init(agt);
1123 if (ret < 0) {
1124 free(agt);
1125 agt = NULL;
1126 goto error;
1127 }
1128
1129 error:
1130 return agt;
1131 }
1132
1133 /*
1134 * Create a newly allocated agent event data structure.
1135 * Ownership of filter_expression is taken.
1136 *
1137 * Return a new object else NULL on error.
1138 */
1139 struct agent_event *agent_create_event(const char *name,
1140 enum lttng_loglevel_type loglevel_type, int loglevel_value,
1141 struct lttng_bytecode *filter, char *filter_expression)
1142 {
1143 struct agent_event *event = NULL;
1144
1145 DBG3("Agent create new event with name %s, loglevel type %d, \
1146 loglevel value %d and filter %s",
1147 name, loglevel_type, loglevel_value,
1148 filter_expression ? filter_expression : "NULL");
1149
1150 if (!name) {
1151 ERR("Failed to create agent event; no name provided.");
1152 goto error;
1153 }
1154
1155 event = zmalloc(sizeof(*event));
1156 if (!event) {
1157 goto error;
1158 }
1159
1160 strncpy(event->name, name, sizeof(event->name));
1161 event->name[sizeof(event->name) - 1] = '\0';
1162 lttng_ht_node_init_str(&event->node, event->name);
1163
1164 event->loglevel_value = loglevel_value;
1165 event->loglevel_type = loglevel_type;
1166 event->filter = filter;
1167 event->filter_expression = filter_expression;
1168 error:
1169 return event;
1170 }
1171
1172 /*
1173 * Unique add of a agent event to an agent object.
1174 */
1175 void agent_add_event(struct agent_event *event, struct agent *agt)
1176 {
1177 assert(event);
1178 assert(agt);
1179 assert(agt->events);
1180
1181 DBG3("Agent adding event %s", event->name);
1182 add_unique_agent_event(agt->events, event);
1183 agt->being_used = 1;
1184 }
1185
1186 /*
1187 * Unique add of a agent context to an agent object.
1188 */
1189 int agent_add_context(const struct lttng_event_context *ctx, struct agent *agt)
1190 {
1191 int ret = LTTNG_OK;
1192 struct agent_app_ctx *agent_ctx = NULL;
1193
1194 assert(ctx);
1195 assert(agt);
1196 assert(agt->events);
1197 assert(ctx->ctx == LTTNG_EVENT_CONTEXT_APP_CONTEXT);
1198
1199 agent_ctx = create_app_ctx(ctx);
1200 if (!agent_ctx) {
1201 ret = LTTNG_ERR_NOMEM;
1202 goto end;
1203 }
1204
1205 DBG3("Agent adding context %s:%s", ctx->u.app_ctx.provider_name,
1206 ctx->u.app_ctx.ctx_name);
1207 cds_list_add_tail_rcu(&agent_ctx->list_node, &agt->app_ctx_list);
1208 end:
1209 return ret;
1210 }
1211
1212 /*
1213 * Find multiple agent events sharing the given name.
1214 *
1215 * RCU read side lock MUST be acquired. It must be held for the
1216 * duration of the iteration.
1217 *
1218 * Sets the given iterator.
1219 */
1220 void agent_find_events_by_name(const char *name, struct agent *agt,
1221 struct lttng_ht_iter* iter)
1222 {
1223 struct lttng_ht *ht;
1224 struct agent_ht_key key;
1225
1226 assert(name);
1227 assert(agt);
1228 assert(agt->events);
1229 assert(iter);
1230
1231 ht = agt->events;
1232 key.name = name;
1233
1234 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
1235 ht_match_event_by_name, &key, &iter->iter);
1236 }
1237
1238 /*
1239 * Find the agent event matching a trigger.
1240 *
1241 * RCU read side lock MUST be acquired. It must be held for as long as
1242 * the returned agent_event is used.
1243 *
1244 * Return object if found else NULL.
1245 */
1246 struct agent_event *agent_find_event_by_trigger(
1247 const struct lttng_trigger *trigger, struct agent *agt)
1248 {
1249 enum lttng_condition_status c_status;
1250 enum lttng_event_rule_status er_status;
1251 enum lttng_domain_type domain;
1252 const struct lttng_condition *condition;
1253 const struct lttng_event_rule *rule;
1254 const char *name;
1255 const char *filter_expression;
1256 const struct lttng_log_level_rule *log_level_rule;
1257 /* Unused when loglevel_type is 'ALL'. */
1258 int loglevel_value = 0;
1259 enum lttng_loglevel_type loglevel_type;
1260 event_rule_logging_get_name_pattern logging_get_name_pattern;
1261 event_rule_logging_get_log_level_rule logging_get_log_level_rule;
1262
1263 assert(agt);
1264 assert(agt->events);
1265
1266 condition = lttng_trigger_get_const_condition(trigger);
1267
1268 assert(lttng_condition_get_type(condition) ==
1269 LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES);
1270
1271 c_status = lttng_condition_event_rule_matches_get_rule(
1272 condition, &rule);
1273 assert(c_status == LTTNG_CONDITION_STATUS_OK);
1274
1275 switch (lttng_event_rule_get_type(rule)) {
1276 case LTTNG_EVENT_RULE_TYPE_JUL_LOGGING:
1277 logging_get_name_pattern =
1278 lttng_event_rule_jul_logging_get_name_pattern;
1279 logging_get_log_level_rule =
1280 lttng_event_rule_jul_logging_get_log_level_rule;
1281 break;
1282 case LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING:
1283 logging_get_name_pattern =
1284 lttng_event_rule_log4j_logging_get_name_pattern;
1285 logging_get_log_level_rule =
1286 lttng_event_rule_log4j_logging_get_log_level_rule;
1287 break;
1288 case LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING:
1289 logging_get_name_pattern =
1290 lttng_event_rule_python_logging_get_name_pattern;
1291 logging_get_log_level_rule =
1292 lttng_event_rule_python_logging_get_log_level_rule;
1293 break;
1294 default:
1295 abort();
1296 break;
1297 }
1298
1299 domain = lttng_event_rule_get_domain_type(rule);
1300 assert(domain == LTTNG_DOMAIN_JUL || domain == LTTNG_DOMAIN_LOG4J ||
1301 domain == LTTNG_DOMAIN_PYTHON);
1302
1303 /* Get the event's pattern name ('name' in the legacy terminology). */
1304 er_status = logging_get_name_pattern(rule, &name);
1305 assert(er_status == LTTNG_EVENT_RULE_STATUS_OK);
1306
1307 /* Get the internal filter expression. */
1308 filter_expression = lttng_event_rule_get_filter(rule);
1309
1310 /* Map log_level_rule to loglevel value. */
1311 er_status = logging_get_log_level_rule(rule, &log_level_rule);
1312 if (er_status == LTTNG_EVENT_RULE_STATUS_UNSET) {
1313 loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL;
1314 loglevel_value = 0;
1315 } else if (er_status == LTTNG_EVENT_RULE_STATUS_OK) {
1316 lttng_log_level_rule_to_loglevel(log_level_rule, &loglevel_type, &loglevel_value);
1317 } else {
1318 abort();
1319 }
1320
1321 return agent_find_event(name, loglevel_type, loglevel_value,
1322 filter_expression, agt);
1323 }
1324
1325 /*
1326 * Get the next agent event duplicate by name. This should be called
1327 * after a call to agent_find_events_by_name() to iterate on events.
1328 *
1329 * The RCU read lock must be held during the iteration and for as long
1330 * as the object the iterator points to remains in use.
1331 */
1332 void agent_event_next_duplicate(const char *name,
1333 struct agent *agt, struct lttng_ht_iter* iter)
1334 {
1335 struct agent_ht_key key;
1336
1337 key.name = name;
1338
1339 cds_lfht_next_duplicate(agt->events->ht, ht_match_event_by_name,
1340 &key, &iter->iter);
1341 }
1342
1343 /*
1344 * Find a agent event in the given agent using name, loglevel and filter.
1345 *
1346 * RCU read side lock MUST be acquired. It must be kept for as long as
1347 * the returned agent_event is used.
1348 *
1349 * Return object if found else NULL.
1350 */
1351 struct agent_event *agent_find_event(const char *name,
1352 enum lttng_loglevel_type loglevel_type,
1353 int loglevel_value,
1354 const char *filter_expression,
1355 struct agent *agt)
1356 {
1357 struct lttng_ht_node_str *node;
1358 struct lttng_ht_iter iter;
1359 struct lttng_ht *ht;
1360 struct agent_ht_key key;
1361
1362 assert(name);
1363 assert(agt);
1364 assert(agt->events);
1365
1366 ht = agt->events;
1367 key.name = name;
1368 key.loglevel_value = loglevel_value;
1369 key.loglevel_type = loglevel_type;
1370 key.filter_expression = filter_expression;
1371
1372 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
1373 ht_match_event, &key, &iter.iter);
1374 node = lttng_ht_iter_get_node_str(&iter);
1375 if (node == NULL) {
1376 goto error;
1377 }
1378
1379 DBG3("Agent event found %s.", name);
1380 return caa_container_of(node, struct agent_event, node);
1381
1382 error:
1383 DBG3("Agent event NOT found %s.", name);
1384 return NULL;
1385 }
1386
1387 /*
1388 * Free given agent event. This event must not be globally visible at this
1389 * point (only expected to be used on failure just after event creation). After
1390 * this call, the pointer is not usable anymore.
1391 */
1392 void agent_destroy_event(struct agent_event *event)
1393 {
1394 assert(event);
1395
1396 free(event->filter);
1397 free(event->filter_expression);
1398 free(event->exclusion);
1399 free(event);
1400 }
1401
1402 static
1403 void destroy_app_ctx_rcu(struct rcu_head *head)
1404 {
1405 struct agent_app_ctx *ctx =
1406 caa_container_of(head, struct agent_app_ctx, rcu_node);
1407
1408 destroy_app_ctx(ctx);
1409 }
1410
1411 /*
1412 * Destroy an agent completely.
1413 */
1414 void agent_destroy(struct agent *agt)
1415 {
1416 struct lttng_ht_node_str *node;
1417 struct lttng_ht_iter iter;
1418 struct agent_app_ctx *ctx;
1419
1420 assert(agt);
1421
1422 DBG3("Agent destroy");
1423
1424 rcu_read_lock();
1425 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, node, node) {
1426 int ret;
1427 struct agent_event *event;
1428
1429 /*
1430 * When destroying an event, we have to try to disable it on the
1431 * agent side so the event stops generating data. The return
1432 * value is not important since we have to continue anyway
1433 * destroying the object.
1434 */
1435 event = caa_container_of(node, struct agent_event, node);
1436 (void) agent_disable_event(event, agt->domain);
1437
1438 ret = lttng_ht_del(agt->events, &iter);
1439 assert(!ret);
1440 call_rcu(&node->head, destroy_event_agent_rcu);
1441 }
1442
1443 cds_list_for_each_entry_rcu(ctx, &agt->app_ctx_list, list_node) {
1444 (void) disable_context(ctx, agt->domain);
1445 cds_list_del(&ctx->list_node);
1446 call_rcu(&ctx->rcu_node, destroy_app_ctx_rcu);
1447 }
1448 rcu_read_unlock();
1449 ht_cleanup_push(agt->events);
1450 free(agt);
1451 }
1452
1453 /*
1454 * Allocate agent_apps_ht_by_sock.
1455 */
1456 int agent_app_ht_alloc(void)
1457 {
1458 the_agent_apps_ht_by_sock = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
1459 return the_agent_apps_ht_by_sock ? 0 : -1;
1460 }
1461
1462 /*
1463 * Destroy a agent application by socket.
1464 */
1465 void agent_destroy_app_by_sock(int sock)
1466 {
1467 struct agent_app *app;
1468
1469 assert(sock >= 0);
1470
1471 /*
1472 * Not finding an application is a very important error that should NEVER
1473 * happen. The hash table deletion is ONLY done through this call when the
1474 * main sessiond thread is torn down.
1475 */
1476 rcu_read_lock();
1477 app = agent_find_app_by_sock(sock);
1478 assert(app);
1479
1480 /* RCU read side lock is assumed to be held by this function. */
1481 agent_delete_app(app);
1482
1483 /* The application is freed in a RCU call but the socket is closed here. */
1484 agent_destroy_app(app);
1485 rcu_read_unlock();
1486 }
1487
1488 /*
1489 * Clean-up the agent app hash table and destroy it.
1490 */
1491 void agent_app_ht_clean(void)
1492 {
1493 struct lttng_ht_node_ulong *node;
1494 struct lttng_ht_iter iter;
1495
1496 if (!the_agent_apps_ht_by_sock) {
1497 return;
1498 }
1499 rcu_read_lock();
1500 cds_lfht_for_each_entry(
1501 the_agent_apps_ht_by_sock->ht, &iter.iter, node, node) {
1502 struct agent_app *app;
1503
1504 app = caa_container_of(node, struct agent_app, node);
1505 agent_destroy_app_by_sock(app->sock->fd);
1506 }
1507 rcu_read_unlock();
1508
1509 lttng_ht_destroy(the_agent_apps_ht_by_sock);
1510 }
1511
1512 /*
1513 * Update a agent application (given socket) using the given agent.
1514 *
1515 * Note that this function is most likely to be used with a tracing session
1516 * thus the caller should make sure to hold the appropriate lock(s).
1517 */
1518 void agent_update(const struct agent *agt, const struct agent_app *app)
1519 {
1520 int ret;
1521 struct agent_event *event;
1522 struct lttng_ht_iter iter;
1523 struct agent_app_ctx *ctx;
1524
1525 assert(agt);
1526 assert(app);
1527
1528 DBG("Agent updating app: pid = %ld", (long) app->pid);
1529
1530 rcu_read_lock();
1531 /*
1532 * We are in the registration path thus if the application is gone,
1533 * there is a serious code flow error.
1534 */
1535
1536 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) {
1537 /* Skip event if disabled. */
1538 if (!AGENT_EVENT_IS_ENABLED(event)) {
1539 continue;
1540 }
1541
1542 ret = enable_event(app, event);
1543 if (ret != LTTNG_OK) {
1544 DBG2("Agent update unable to enable event %s on app pid: %d sock %d",
1545 event->name, app->pid, app->sock->fd);
1546 /* Let's try the others here and don't assume the app is dead. */
1547 continue;
1548 }
1549 }
1550
1551 cds_list_for_each_entry_rcu(ctx, &agt->app_ctx_list, list_node) {
1552 ret = app_context_op(app, ctx, AGENT_CMD_APP_CTX_ENABLE);
1553 if (ret != LTTNG_OK) {
1554 DBG2("Agent update unable to add application context %s:%s on app pid: %d sock %d",
1555 ctx->provider_name, ctx->ctx_name,
1556 app->pid, app->sock->fd);
1557 continue;
1558 }
1559 }
1560
1561 rcu_read_unlock();
1562 }
1563
1564 /*
1565 * Allocate the per-event notifier domain agent hash table. It is lazily
1566 * populated as domains are used.
1567 */
1568 int agent_by_event_notifier_domain_ht_create(void)
1569 {
1570 the_trigger_agents_ht_by_domain = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
1571 return the_trigger_agents_ht_by_domain ? 0 : -1;
1572 }
1573
1574 /*
1575 * Clean-up the per-event notifier domain agent hash table and destroy it.
1576 */
1577 void agent_by_event_notifier_domain_ht_destroy(void)
1578 {
1579 struct lttng_ht_node_u64 *node;
1580 struct lttng_ht_iter iter;
1581
1582 if (!the_trigger_agents_ht_by_domain) {
1583 return;
1584 }
1585
1586 rcu_read_lock();
1587 cds_lfht_for_each_entry(the_trigger_agents_ht_by_domain->ht,
1588 &iter.iter, node, node) {
1589 struct agent *agent =
1590 caa_container_of(node, struct agent, node);
1591 const int ret = lttng_ht_del(
1592 the_trigger_agents_ht_by_domain, &iter);
1593
1594 assert(ret == 0);
1595 agent_destroy(agent);
1596 }
1597
1598 rcu_read_unlock();
1599 lttng_ht_destroy(the_trigger_agents_ht_by_domain);
1600 }
1601
1602 struct agent *agent_find_by_event_notifier_domain(
1603 enum lttng_domain_type domain_type)
1604 {
1605 struct agent *agt = NULL;
1606 struct lttng_ht_node_u64 *node;
1607 struct lttng_ht_iter iter;
1608 const uint64_t key = (uint64_t) domain_type;
1609
1610 assert(the_trigger_agents_ht_by_domain);
1611
1612 DBG3("Per-event notifier domain agent lookup for domain '%s'",
1613 lttng_domain_type_str(domain_type));
1614
1615 lttng_ht_lookup(the_trigger_agents_ht_by_domain, &key, &iter);
1616 node = lttng_ht_iter_get_node_u64(&iter);
1617 if (!node) {
1618 goto end;
1619 }
1620
1621 agt = caa_container_of(node, struct agent, node);
1622
1623 end:
1624 return agt;
1625 }
This page took 0.096604 seconds and 4 git commands to generate.