Add a save API to lttng-ctl
[lttng-tools.git] / src / bin / lttng-sessiond / jul.c
1 /*
2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
3 *
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.
7 *
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
11 * more details.
12 *
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.
16 */
17
18 #define _GNU_SOURCE
19 #include <assert.h>
20 #include <urcu/uatomic.h>
21
22 #include <common/common.h>
23 #include <common/sessiond-comm/jul.h>
24
25 #include "jul.h"
26 #include "ust-app.h"
27 #include "utils.h"
28
29 /*
30 * Match function for the events hash table lookup by name.
31 */
32 static int ht_match_event_by_name(struct cds_lfht_node *node,
33 const void *_key)
34 {
35 struct jul_event *event;
36 const struct jul_ht_key *key;
37
38 assert(node);
39 assert(_key);
40
41 event = caa_container_of(node, struct jul_event, node.node);
42 key = _key;
43
44 /* Match 1 elements of the key: name. */
45
46 /* Event name */
47 if (strncmp(event->name, key->name, sizeof(event->name)) != 0) {
48 goto no_match;
49 }
50 /* Match. */
51 return 1;
52
53 no_match:
54 return 0;
55 }
56
57 /*
58 * Match function for the events hash table lookup by name and loglevel.
59 */
60 static int ht_match_event(struct cds_lfht_node *node,
61 const void *_key)
62 {
63 struct jul_event *event;
64 const struct jul_ht_key *key;
65
66 assert(node);
67 assert(_key);
68
69 event = caa_container_of(node, struct jul_event, node.node);
70 key = _key;
71
72 /* Match 2 elements of the key: name and loglevel. */
73
74 /* Event name */
75 if (strncmp(event->name, key->name, sizeof(event->name)) != 0) {
76 goto no_match;
77 }
78
79 if (event->loglevel != key->loglevel) {
80 if (event->loglevel_type == LTTNG_EVENT_LOGLEVEL_ALL &&
81 key->loglevel == 0 && event->loglevel == -1) {
82 goto match;
83 }
84 goto no_match;
85 }
86 match:
87 return 1;
88
89 no_match:
90 return 0;
91 }
92
93 /*
94 * Add unique JUL event based on the event name and loglevel.
95 */
96 static void add_unique_jul_event(struct lttng_ht *ht, struct jul_event *event)
97 {
98 struct cds_lfht_node *node_ptr;
99 struct jul_ht_key key;
100
101 assert(ht);
102 assert(ht->ht);
103 assert(event);
104
105 key.name = event->name;
106 key.loglevel = event->loglevel;
107
108 node_ptr = cds_lfht_add_unique(ht->ht,
109 ht->hash_fct(event->node.key, lttng_ht_seed),
110 ht_match_event, &key, &event->node.node);
111 assert(node_ptr == &event->node.node);
112 }
113
114 /*
115 * URCU delayed JUL event reclaim.
116 */
117 static void destroy_event_jul_rcu(struct rcu_head *head)
118 {
119 struct lttng_ht_node_str *node =
120 caa_container_of(head, struct lttng_ht_node_str, head);
121 struct jul_event *event =
122 caa_container_of(node, struct jul_event, node);
123
124 free(event);
125 }
126
127 /*
128 * URCU delayed JUL app reclaim.
129 */
130 static void destroy_app_jul_rcu(struct rcu_head *head)
131 {
132 struct lttng_ht_node_ulong *node =
133 caa_container_of(head, struct lttng_ht_node_ulong, head);
134 struct jul_app *app =
135 caa_container_of(node, struct jul_app, node);
136
137 free(app);
138 }
139
140 /*
141 * Communication with Java agent. Send the message header to the given
142 * socket in big endian.
143 *
144 * Return 0 on success or else a negative errno message of sendmsg() op.
145 */
146 static int send_header(struct lttcomm_sock *sock, uint64_t data_size,
147 uint32_t cmd, uint32_t cmd_version)
148 {
149 int ret;
150 ssize_t size;
151 struct lttcomm_jul_hdr msg;
152
153 assert(sock);
154
155 memset(&msg, 0, sizeof(msg));
156 msg.data_size = htobe64(data_size);
157 msg.cmd = htobe32(cmd);
158 msg.cmd_version = htobe32(cmd_version);
159
160 size = sock->ops->sendmsg(sock, &msg, sizeof(msg), 0);
161 if (size < sizeof(msg)) {
162 ret = -errno;
163 goto error;
164 }
165 ret = 0;
166
167 error:
168 return ret;
169 }
170
171 /*
172 * Communication call with the Java agent. Send the payload to the given
173 * socket. The header MUST be sent prior to this call.
174 *
175 * Return 0 on success or else a negative errno value of sendmsg() op.
176 */
177 static int send_payload(struct lttcomm_sock *sock, void *data,
178 size_t size)
179 {
180 int ret;
181 ssize_t len;
182
183 assert(sock);
184 assert(data);
185
186 len = sock->ops->sendmsg(sock, data, size, 0);
187 if (len < size) {
188 ret = -errno;
189 goto error;
190 }
191 ret = 0;
192
193 error:
194 return ret;
195 }
196
197 /*
198 * Communication call with the Java agent. Receive reply from the agent using
199 * the given socket.
200 *
201 * Return 0 on success or else a negative errno value from recvmsg() op.
202 */
203 static int recv_reply(struct lttcomm_sock *sock, void *buf, size_t size)
204 {
205 int ret;
206 ssize_t len;
207
208 assert(sock);
209 assert(buf);
210
211 len = sock->ops->recvmsg(sock, buf, size, 0);
212 if (len < size) {
213 ret = -errno;
214 goto error;
215 }
216 ret = 0;
217
218 error:
219 return ret;
220 }
221
222
223 /*
224 * Internal event listing for a given app. Populate events.
225 *
226 * Return number of element in the list or else a negative LTTNG_ERR* code.
227 * On success, the caller is responsible for freeing the memory
228 * allocated for "events".
229 */
230 static ssize_t list_events(struct jul_app *app, struct lttng_event **events)
231 {
232 int ret, i, len = 0, offset = 0;
233 uint32_t nb_event;
234 size_t data_size;
235 struct lttng_event *tmp_events = NULL;
236 struct lttcomm_jul_list_reply *reply = NULL;
237 struct lttcomm_jul_list_reply_hdr reply_hdr;
238
239 assert(app);
240 assert(app->sock);
241 assert(events);
242
243 DBG2("JUL listing events for app pid: %d and socket %d", app->pid,
244 app->sock->fd);
245
246 ret = send_header(app->sock, 0, JUL_CMD_LIST, 0);
247 if (ret < 0) {
248 goto error_io;
249 }
250
251 /* Get list header so we know how much we'll receive. */
252 ret = recv_reply(app->sock, &reply_hdr, sizeof(reply_hdr));
253 if (ret < 0) {
254 goto error_io;
255 }
256
257 switch (be32toh(reply_hdr.ret_code)) {
258 case JUL_RET_CODE_SUCCESS:
259 data_size = be32toh(reply_hdr.data_size) + sizeof(*reply);
260 break;
261 default:
262 ERR("Java agent returned an unknown code: %" PRIu32,
263 be32toh(reply_hdr.ret_code));
264 ret = LTTNG_ERR_FATAL;
265 goto error;
266 }
267
268 reply = zmalloc(data_size);
269 if (!reply) {
270 ret = LTTNG_ERR_NOMEM;
271 goto error;
272 }
273
274 /* Get the list with the appropriate data size. */
275 ret = recv_reply(app->sock, reply, data_size);
276 if (ret < 0) {
277 goto error_io;
278 }
279
280 nb_event = be32toh(reply->nb_event);
281 tmp_events = zmalloc(sizeof(*tmp_events) * nb_event);
282 if (!tmp_events) {
283 ret = LTTNG_ERR_NOMEM;
284 goto error;
285 }
286
287 for (i = 0; i < nb_event; i++) {
288 offset += len;
289 strncpy(tmp_events[i].name, reply->payload + offset,
290 sizeof(tmp_events[i].name));
291 tmp_events[i].pid = app->pid;
292 tmp_events[i].enabled = -1;
293 len = strlen(reply->payload + offset) + 1;
294 }
295
296 *events = tmp_events;
297
298 free(reply);
299 return nb_event;
300
301 error_io:
302 ret = LTTNG_ERR_UST_LIST_FAIL;
303 error:
304 free(reply);
305 free(tmp_events);
306 return -ret;
307
308 }
309
310 /*
311 * Internal enable JUL event on a JUL application. This function
312 * communicates with the Java agent to enable a given event (Logger name).
313 *
314 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
315 */
316 static int enable_event(struct jul_app *app, struct jul_event *event)
317 {
318 int ret;
319 uint64_t data_size;
320 struct lttcomm_jul_enable msg;
321 struct lttcomm_jul_generic_reply reply;
322
323 assert(app);
324 assert(app->sock);
325 assert(event);
326
327 DBG2("JUL enabling event %s for app pid: %d and socket %d", event->name,
328 app->pid, app->sock->fd);
329
330 data_size = sizeof(msg);
331
332 ret = send_header(app->sock, data_size, JUL_CMD_ENABLE, 0);
333 if (ret < 0) {
334 goto error_io;
335 }
336
337 memset(&msg, 0, sizeof(msg));
338 msg.loglevel = event->loglevel;
339 msg.loglevel_type = event->loglevel_type;
340 strncpy(msg.name, event->name, sizeof(msg.name));
341 ret = send_payload(app->sock, &msg, sizeof(msg));
342 if (ret < 0) {
343 goto error_io;
344 }
345
346 ret = recv_reply(app->sock, &reply, sizeof(reply));
347 if (ret < 0) {
348 goto error_io;
349 }
350
351 switch (be32toh(reply.ret_code)) {
352 case JUL_RET_CODE_SUCCESS:
353 break;
354 case JUL_RET_CODE_UNKNOWN_NAME:
355 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
356 goto error;
357 default:
358 ERR("Java agent returned an unknown code: %" PRIu32,
359 be32toh(reply.ret_code));
360 ret = LTTNG_ERR_FATAL;
361 goto error;
362 }
363
364 return LTTNG_OK;
365
366 error_io:
367 ret = LTTNG_ERR_UST_ENABLE_FAIL;
368 error:
369 return ret;
370 }
371
372 /*
373 * Internal disable JUL event call on a JUL application. This function
374 * communicates with the Java agent to disable a given event (Logger name).
375 *
376 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
377 */
378 static int disable_event(struct jul_app *app, struct jul_event *event)
379 {
380 int ret;
381 uint64_t data_size;
382 struct lttcomm_jul_disable msg;
383 struct lttcomm_jul_generic_reply reply;
384
385 assert(app);
386 assert(app->sock);
387 assert(event);
388
389 DBG2("JUL disabling event %s for app pid: %d and socket %d", event->name,
390 app->pid, app->sock->fd);
391
392 data_size = sizeof(msg);
393
394 ret = send_header(app->sock, data_size, JUL_CMD_DISABLE, 0);
395 if (ret < 0) {
396 goto error_io;
397 }
398
399 memset(&msg, 0, sizeof(msg));
400 strncpy(msg.name, event->name, sizeof(msg.name));
401 ret = send_payload(app->sock, &msg, sizeof(msg));
402 if (ret < 0) {
403 goto error_io;
404 }
405
406 ret = recv_reply(app->sock, &reply, sizeof(reply));
407 if (ret < 0) {
408 goto error_io;
409 }
410
411 switch (be32toh(reply.ret_code)) {
412 case JUL_RET_CODE_SUCCESS:
413 break;
414 case JUL_RET_CODE_UNKNOWN_NAME:
415 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
416 goto error;
417 default:
418 ERR("Java agent returned an unknown code: %" PRIu32,
419 be32toh(reply.ret_code));
420 ret = LTTNG_ERR_FATAL;
421 goto error;
422 }
423
424 return LTTNG_OK;
425
426 error_io:
427 ret = LTTNG_ERR_UST_DISABLE_FAIL;
428 error:
429 return ret;
430 }
431
432 /*
433 * Send back the registration DONE command to a given JUL application.
434 *
435 * Return 0 on success or else a negative value.
436 */
437 int jul_send_registration_done(struct jul_app *app)
438 {
439 assert(app);
440 assert(app->sock);
441
442 DBG("JUL sending registration done to app socket %d", app->sock->fd);
443
444 return send_header(app->sock, 0, JUL_CMD_REG_DONE, 0);
445 }
446
447 /*
448 * Enable JUL event on every JUL applications registered with the session
449 * daemon.
450 *
451 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
452 */
453 int jul_enable_event(struct jul_event *event)
454 {
455 int ret;
456 struct jul_app *app;
457 struct lttng_ht_iter iter;
458
459 assert(event);
460
461 rcu_read_lock();
462
463 cds_lfht_for_each_entry(jul_apps_ht_by_sock->ht, &iter.iter, app,
464 node.node) {
465 /* Enable event on JUL application through TCP socket. */
466 ret = enable_event(app, event);
467 if (ret != LTTNG_OK) {
468 goto error;
469 }
470 }
471
472 event->enabled = 1;
473 ret = LTTNG_OK;
474
475 error:
476 rcu_read_unlock();
477 return ret;
478 }
479
480 /*
481 * Disable JUL event on every JUL applications registered with the session
482 * daemon.
483 *
484 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
485 */
486 int jul_disable_event(struct jul_event *event)
487 {
488 int ret;
489 struct jul_app *app;
490 struct lttng_ht_iter iter;
491
492 assert(event);
493
494 rcu_read_lock();
495
496 cds_lfht_for_each_entry(jul_apps_ht_by_sock->ht, &iter.iter, app,
497 node.node) {
498 /* Enable event on JUL application through TCP socket. */
499 ret = disable_event(app, event);
500 if (ret != LTTNG_OK) {
501 goto error;
502 }
503 }
504
505 event->enabled = 0;
506 ret = LTTNG_OK;
507
508 error:
509 rcu_read_unlock();
510 return ret;
511 }
512
513 /*
514 * Ask every java agent for the list of possible event (logger name). Events is
515 * allocated with the events of every JUL application.
516 *
517 * Return the number of events or else a negative value.
518 */
519 int jul_list_events(struct lttng_event **events)
520 {
521 int ret;
522 size_t nbmem, count = 0;
523 struct jul_app *app;
524 struct lttng_event *tmp_events = NULL;
525 struct lttng_ht_iter iter;
526
527 assert(events);
528
529 nbmem = UST_APP_EVENT_LIST_SIZE;
530 tmp_events = zmalloc(nbmem * sizeof(*tmp_events));
531 if (!tmp_events) {
532 PERROR("zmalloc jul list events");
533 ret = -ENOMEM;
534 goto error;
535 }
536
537 rcu_read_lock();
538 cds_lfht_for_each_entry(jul_apps_ht_by_sock->ht, &iter.iter, app,
539 node.node) {
540 ssize_t nb_ev;
541 struct lttng_event *jul_events;
542
543 nb_ev = list_events(app, &jul_events);
544 if (nb_ev < 0) {
545 ret = nb_ev;
546 goto error_unlock;
547 }
548
549 if (count + nb_ev > nbmem) {
550 /* In case the realloc fails, we free the memory */
551 struct lttng_event *new_tmp_events;
552 size_t new_nbmem;
553
554 new_nbmem = max_t(size_t, count + nb_ev, nbmem << 1);
555 DBG2("Reallocating JUL event list from %zu to %zu entries",
556 nbmem, new_nbmem);
557 new_tmp_events = realloc(tmp_events,
558 new_nbmem * sizeof(*new_tmp_events));
559 if (!new_tmp_events) {
560 PERROR("realloc JUL events");
561 ret = -ENOMEM;
562 free(jul_events);
563 goto error_unlock;
564 }
565 /* Zero the new memory */
566 memset(new_tmp_events + nbmem, 0,
567 (new_nbmem - nbmem) * sizeof(*new_tmp_events));
568 nbmem = new_nbmem;
569 tmp_events = new_tmp_events;
570 }
571 memcpy(tmp_events + count, jul_events,
572 nb_ev * sizeof(*tmp_events));
573 free(jul_events);
574 count += nb_ev;
575 }
576 rcu_read_unlock();
577
578 ret = count;
579 *events = tmp_events;
580 return ret;
581
582 error_unlock:
583 rcu_read_unlock();
584 error:
585 free(tmp_events);
586 return ret;
587 }
588
589 /*
590 * Create a JUL app object using the given PID.
591 *
592 * Return newly allocated object or else NULL on error.
593 */
594 struct jul_app *jul_create_app(pid_t pid, struct lttcomm_sock *sock)
595 {
596 struct jul_app *app;
597
598 assert(sock);
599
600 app = zmalloc(sizeof(*app));
601 if (!app) {
602 PERROR("zmalloc JUL create");
603 goto error;
604 }
605
606 app->pid = pid;
607 app->sock = sock;
608 lttng_ht_node_init_ulong(&app->node, (unsigned long) app->sock->fd);
609
610 error:
611 return app;
612 }
613
614 /*
615 * Lookup JUL app by socket in the global hash table.
616 *
617 * RCU read side lock MUST be acquired.
618 *
619 * Return object if found else NULL.
620 */
621 struct jul_app *jul_find_app_by_sock(int sock)
622 {
623 struct lttng_ht_node_ulong *node;
624 struct lttng_ht_iter iter;
625 struct jul_app *app;
626
627 assert(sock >= 0);
628
629 lttng_ht_lookup(jul_apps_ht_by_sock, (void *)((unsigned long) sock), &iter);
630 node = lttng_ht_iter_get_node_ulong(&iter);
631 if (node == NULL) {
632 goto error;
633 }
634 app = caa_container_of(node, struct jul_app, node);
635
636 DBG3("JUL app pid %d found by sock %d.", app->pid, sock);
637 return app;
638
639 error:
640 DBG3("JUL app NOT found by sock %d.", sock);
641 return NULL;
642 }
643
644 /*
645 * Add JUL application object to a given hash table.
646 */
647 void jul_add_app(struct jul_app *app)
648 {
649 assert(app);
650
651 DBG3("JUL adding app sock: %d and pid: %d to ht", app->sock->fd, app->pid);
652
653 rcu_read_lock();
654 lttng_ht_add_unique_ulong(jul_apps_ht_by_sock, &app->node);
655 rcu_read_unlock();
656 }
657
658 /*
659 * Delete JUL application from the global hash table.
660 */
661 void jul_delete_app(struct jul_app *app)
662 {
663 int ret;
664 struct lttng_ht_iter iter;
665
666 assert(app);
667
668 DBG3("JUL deleting app pid: %d and sock: %d", app->pid, app->sock->fd);
669
670 iter.iter.node = &app->node.node;
671 rcu_read_lock();
672 ret = lttng_ht_del(jul_apps_ht_by_sock, &iter);
673 rcu_read_unlock();
674 assert(!ret);
675 }
676
677 /*
678 * Destroy a JUL application object by detaching it from its corresponding UST
679 * app if one is connected by closing the socket. Finally, perform a
680 * delayed memory reclaim.
681 */
682 void jul_destroy_app(struct jul_app *app)
683 {
684 assert(app);
685
686 if (app->sock) {
687 app->sock->ops->close(app->sock);
688 lttcomm_destroy_sock(app->sock);
689 }
690
691 call_rcu(&app->node.head, destroy_app_jul_rcu);
692 }
693
694 /*
695 * Initialize an already allocated JUL domain object.
696 *
697 * Return 0 on success or else a negative errno value.
698 */
699 int jul_init_domain(struct jul_domain *dom)
700 {
701 int ret;
702
703 assert(dom);
704
705 dom->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
706 if (!dom->events) {
707 ret = -ENOMEM;
708 goto error;
709 }
710
711 return 0;
712
713 error:
714 return ret;
715 }
716
717 /*
718 * Create a newly allocated JUL event data structure. If name is valid, it's
719 * copied into the created event.
720 *
721 * Return a new object else NULL on error.
722 */
723 struct jul_event *jul_create_event(const char *name)
724 {
725 struct jul_event *event;
726
727 DBG3("JUL create new event with name %s", name);
728
729 event = zmalloc(sizeof(*event));
730 if (!event) {
731 goto error;
732 }
733
734 if (name) {
735 strncpy(event->name, name, sizeof(event->name));
736 event->name[sizeof(event->name) - 1] = '\0';
737 lttng_ht_node_init_str(&event->node, event->name);
738 }
739
740 error:
741 return event;
742 }
743
744 /*
745 * Unique add of a JUL event to a given domain.
746 */
747 void jul_add_event(struct jul_event *event, struct jul_domain *dom)
748 {
749 assert(event);
750 assert(dom);
751 assert(dom->events);
752
753 DBG3("JUL adding event %s to domain", event->name);
754
755 rcu_read_lock();
756 add_unique_jul_event(dom->events, event);
757 rcu_read_unlock();
758 dom->being_used = 1;
759 }
760
761 /*
762 * Find a JUL event in the given domain using name and loglevel.
763 *
764 * RCU read side lock MUST be acquired.
765 *
766 * Return object if found else NULL.
767 */
768 struct jul_event *jul_find_event_by_name(const char *name,
769 struct jul_domain *dom)
770 {
771 struct lttng_ht_node_str *node;
772 struct lttng_ht_iter iter;
773 struct lttng_ht *ht;
774 struct jul_ht_key key;
775
776 assert(name);
777 assert(dom);
778 assert(dom->events);
779
780 ht = dom->events;
781 key.name = name;
782
783 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
784 ht_match_event_by_name, &key, &iter.iter);
785 node = lttng_ht_iter_get_node_str(&iter);
786 if (node == NULL) {
787 goto error;
788 }
789
790 DBG3("JUL event found %s by name.", name);
791 return caa_container_of(node, struct jul_event, node);
792
793 error:
794 DBG3("JUL NOT found by name %s.", name);
795 return NULL;
796 }
797
798 /*
799 * Find a JUL event in the given domain using name and loglevel.
800 *
801 * RCU read side lock MUST be acquired.
802 *
803 * Return object if found else NULL.
804 */
805 struct jul_event *jul_find_event(const char *name,
806 enum lttng_loglevel_jul loglevel, struct jul_domain *dom)
807 {
808 struct lttng_ht_node_str *node;
809 struct lttng_ht_iter iter;
810 struct lttng_ht *ht;
811 struct jul_ht_key key;
812
813 assert(name);
814 assert(dom);
815 assert(dom->events);
816
817 ht = dom->events;
818 key.name = name;
819 key.loglevel = loglevel;
820
821 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
822 ht_match_event, &key, &iter.iter);
823 node = lttng_ht_iter_get_node_str(&iter);
824 if (node == NULL) {
825 goto error;
826 }
827
828 DBG3("JUL event found %s.", name);
829 return caa_container_of(node, struct jul_event, node);
830
831 error:
832 DBG3("JUL NOT found %s.", name);
833 return NULL;
834 }
835
836 /*
837 * Free given JUL event. This event must not be globally visible at this
838 * point (only expected to be used on failure just after event
839 * creation). After this call, the pointer is not usable anymore.
840 */
841 void jul_destroy_event(struct jul_event *event)
842 {
843 assert(event);
844
845 free(event);
846 }
847
848 /*
849 * Destroy a JUL domain completely. Note that the given pointer is NOT freed
850 * thus a reference to static or stack data can be passed to this function.
851 */
852 void jul_destroy_domain(struct jul_domain *dom)
853 {
854 struct lttng_ht_node_str *node;
855 struct lttng_ht_iter iter;
856
857 assert(dom);
858
859 DBG3("JUL destroy domain");
860
861 /*
862 * Just ignore if no events hash table exists. This is possible if for
863 * instance a JUL domain object was allocated but not initialized.
864 */
865 if (!dom->events) {
866 return;
867 }
868
869 rcu_read_lock();
870 cds_lfht_for_each_entry(dom->events->ht, &iter.iter, node, node) {
871 int ret;
872
873 ret = lttng_ht_del(dom->events, &iter);
874 assert(!ret);
875 call_rcu(&node->head, destroy_event_jul_rcu);
876 }
877 rcu_read_unlock();
878
879 lttng_ht_destroy(dom->events);
880 }
881
882 /*
883 * Initialize JUL subsystem.
884 */
885 int jul_init(void)
886 {
887 jul_apps_ht_by_sock = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
888 if (!jul_apps_ht_by_sock) {
889 return -1;
890 }
891
892 return 0;
893 }
894
895 /*
896 * Update a JUL application (given socket) using the given domain.
897 *
898 * Note that this function is most likely to be used with a tracing session
899 * thus the caller should make sure to hold the appropriate lock(s).
900 */
901 void jul_update(struct jul_domain *domain, int sock)
902 {
903 int ret;
904 struct jul_app *app;
905 struct jul_event *event;
906 struct lttng_ht_iter iter;
907
908 assert(domain);
909 assert(sock >= 0);
910
911 DBG("JUL updating app socket %d", sock);
912
913 rcu_read_lock();
914 cds_lfht_for_each_entry(domain->events->ht, &iter.iter, event, node.node) {
915 /* Skip event if disabled. */
916 if (!event->enabled) {
917 continue;
918 }
919
920 app = jul_find_app_by_sock(sock);
921 /*
922 * We are in the registration path thus if the application is gone,
923 * there is a serious code flow error.
924 */
925 assert(app);
926
927 ret = enable_event(app, event);
928 if (ret != LTTNG_OK) {
929 DBG2("JUL update unable to enable event %s on app pid: %d sock %d",
930 event->name, app->pid, app->sock->fd);
931 /* Let's try the others here and don't assume the app is dead. */
932 continue;
933 }
934 }
935 rcu_read_unlock();
936 }
This page took 0.048169 seconds and 4 git commands to generate.