librarize run_as
[lttng-tools.git] / lttng-sessiond / ust-app.c
1 /*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; only version 2
7 * of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #define _GNU_SOURCE
20 #include <errno.h>
21 #include <pthread.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <runas.h>
29
30 #include <urcu/compiler.h>
31 #include <lttngerr.h>
32 #include <lttng-share.h>
33 #include <runas.h>
34
35 #include "hashtable.h"
36 #include "ust-app.h"
37 #include "ust-consumer.h"
38 #include "ust-ctl.h"
39
40 /*
41 * Delete ust context safely. RCU read lock must be held before calling
42 * this function.
43 */
44 static
45 void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx)
46 {
47 if (ua_ctx->obj) {
48 ustctl_release_object(sock, ua_ctx->obj);
49 free(ua_ctx->obj);
50 }
51 free(ua_ctx);
52 }
53
54 /*
55 * Delete ust app event safely. RCU read lock must be held before calling
56 * this function.
57 */
58 static
59 void delete_ust_app_event(int sock, struct ust_app_event *ua_event)
60 {
61 int ret;
62 struct cds_lfht_iter iter;
63 struct ust_app_ctx *ua_ctx;
64
65 cds_lfht_for_each_entry(ua_event->ctx, &iter, ua_ctx, node) {
66 ret = hashtable_del(ua_event->ctx, &iter);
67 assert(!ret);
68 delete_ust_app_ctx(sock, ua_ctx);
69 }
70 ret = hashtable_destroy(ua_event->ctx);
71 assert(!ret);
72
73 if (ua_event->obj != NULL) {
74 ustctl_release_object(sock, ua_event->obj);
75 free(ua_event->obj);
76 }
77 free(ua_event);
78 }
79
80 /*
81 * Delete ust app stream safely. RCU read lock must be held before calling
82 * this function.
83 */
84 static
85 void delete_ust_app_stream(int sock, struct ltt_ust_stream *stream)
86 {
87 if (stream->obj) {
88 ustctl_release_object(sock, stream->obj);
89 free(stream->obj);
90 }
91 free(stream);
92 }
93
94 /*
95 * Delete ust app channel safely. RCU read lock must be held before calling
96 * this function.
97 */
98 static
99 void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan)
100 {
101 int ret;
102 struct cds_lfht_iter iter;
103 struct ust_app_event *ua_event;
104 struct ust_app_ctx *ua_ctx;
105 struct ltt_ust_stream *stream, *stmp;
106
107 /* Wipe stream */
108 cds_list_for_each_entry_safe(stream, stmp, &ua_chan->streams.head, list) {
109 cds_list_del(&stream->list);
110 delete_ust_app_stream(sock, stream);
111 }
112
113 /* Wipe context */
114 cds_lfht_for_each_entry(ua_chan->ctx, &iter, ua_ctx, node) {
115 ret = hashtable_del(ua_chan->ctx, &iter);
116 assert(!ret);
117 delete_ust_app_ctx(sock, ua_ctx);
118 }
119 ret = hashtable_destroy(ua_chan->ctx);
120 assert(!ret);
121
122 /* Wipe events */
123 cds_lfht_for_each_entry(ua_chan->events, &iter, ua_event, node) {
124 ret = hashtable_del(ua_chan->events, &iter);
125 assert(!ret);
126 delete_ust_app_event(sock, ua_event);
127 }
128 ret = hashtable_destroy(ua_chan->events);
129 assert(!ret);
130
131 if (ua_chan->obj != NULL) {
132 ustctl_release_object(sock, ua_chan->obj);
133 free(ua_chan->obj);
134 }
135 free(ua_chan);
136 }
137
138 /*
139 * Delete ust app session safely. RCU read lock must be held before calling
140 * this function.
141 */
142 static
143 void delete_ust_app_session(int sock, struct ust_app_session *ua_sess)
144 {
145 int ret;
146 struct cds_lfht_iter iter;
147 struct ust_app_channel *ua_chan;
148
149 if (ua_sess->metadata) {
150 if (ua_sess->metadata->stream_obj) {
151 ustctl_release_object(sock, ua_sess->metadata->stream_obj);
152 free(ua_sess->metadata->stream_obj);
153 }
154 if (ua_sess->metadata->obj) {
155 ustctl_release_object(sock, ua_sess->metadata->obj);
156 free(ua_sess->metadata->obj);
157 }
158 }
159
160 cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) {
161 ret = hashtable_del(ua_sess->channels, &iter);
162 assert(!ret);
163 delete_ust_app_channel(sock, ua_chan);
164 }
165 ret = hashtable_destroy(ua_sess->channels);
166 assert(!ret);
167
168 if (ua_sess->handle != -1) {
169 ustctl_release_handle(sock, ua_sess->handle);
170 }
171 free(ua_sess);
172 }
173
174 /*
175 * Delete a traceable application structure from the global list. Never call
176 * this function outside of a call_rcu call.
177 */
178 static
179 void delete_ust_app(struct ust_app *app)
180 {
181 int ret, sock;
182 struct cds_lfht_node *node;
183 struct cds_lfht_iter iter;
184 struct ust_app_session *ua_sess;
185
186 rcu_read_lock();
187
188 /* Remove from key hash table */
189 node = hashtable_lookup(ust_app_sock_key_map,
190 (void *) ((unsigned long) app->key.sock), sizeof(void *), &iter);
191 if (node == NULL) {
192 /* Not suppose to happen */
193 ERR("UST app key %d not found in key hash table", app->key.sock);
194 goto end;
195 }
196
197 ret = hashtable_del(ust_app_sock_key_map, &iter);
198 if (ret) {
199 ERR("UST app unable to delete app sock %d from key hash table",
200 app->key.sock);
201 } else {
202 DBG2("UST app pair sock %d key %d deleted",
203 app->key.sock, app->key.pid);
204 }
205
206 /* Socket is already closed at this point */
207
208 /* Delete ust app sessions info */
209 sock = app->key.sock;
210 app->key.sock = -1;
211
212 /* Wipe sessions */
213 cds_lfht_for_each_entry(app->sessions, &iter, ua_sess, node) {
214 ret = hashtable_del(app->sessions, &iter);
215 assert(!ret);
216 delete_ust_app_session(app->key.sock, ua_sess);
217 }
218 ret = hashtable_destroy(app->sessions);
219 assert(!ret);
220
221 /*
222 * Wait until we have removed the key from the sock hash table
223 * before closing this socket, otherwise an application could
224 * re-use the socket ID and race with the teardown, using the
225 * same hash table entry.
226 */
227 close(sock);
228
229 DBG2("UST app pid %d deleted", app->key.pid);
230 free(app);
231 end:
232 rcu_read_unlock();
233 }
234
235 /*
236 * URCU intermediate call to delete an UST app.
237 */
238 static
239 void delete_ust_app_rcu(struct rcu_head *head)
240 {
241 struct cds_lfht_node *node =
242 caa_container_of(head, struct cds_lfht_node, head);
243 struct ust_app *app =
244 caa_container_of(node, struct ust_app, node);
245
246 delete_ust_app(app);
247 }
248
249 /*
250 * Alloc new UST app session.
251 */
252 static
253 struct ust_app_session *alloc_ust_app_session(void)
254 {
255 struct ust_app_session *ua_sess;
256
257 /* Init most of the default value by allocating and zeroing */
258 ua_sess = zmalloc(sizeof(struct ust_app_session));
259 if (ua_sess == NULL) {
260 PERROR("malloc");
261 goto error;
262 }
263
264 ua_sess->handle = -1;
265 ua_sess->channels = hashtable_new_str(0);
266
267 return ua_sess;
268
269 error:
270 return NULL;
271 }
272
273 /*
274 * Alloc new UST app channel.
275 */
276 static
277 struct ust_app_channel *alloc_ust_app_channel(char *name,
278 struct lttng_ust_channel *attr)
279 {
280 struct ust_app_channel *ua_chan;
281
282 /* Init most of the default value by allocating and zeroing */
283 ua_chan = zmalloc(sizeof(struct ust_app_channel));
284 if (ua_chan == NULL) {
285 PERROR("malloc");
286 goto error;
287 }
288
289 /* Setup channel name */
290 strncpy(ua_chan->name, name, sizeof(ua_chan->name));
291 ua_chan->name[sizeof(ua_chan->name) - 1] = '\0';
292
293 ua_chan->enabled = 1;
294 ua_chan->handle = -1;
295 ua_chan->ctx = hashtable_new(0);
296 ua_chan->events = hashtable_new_str(0);
297 hashtable_node_init(&ua_chan->node, (void *) ua_chan->name,
298 strlen(ua_chan->name));
299
300 CDS_INIT_LIST_HEAD(&ua_chan->streams.head);
301
302 /* Copy attributes */
303 if (attr) {
304 memcpy(&ua_chan->attr, attr, sizeof(ua_chan->attr));
305 }
306
307 DBG3("UST app channel %s allocated", ua_chan->name);
308
309 return ua_chan;
310
311 error:
312 return NULL;
313 }
314
315 /*
316 * Alloc new UST app event.
317 */
318 static
319 struct ust_app_event *alloc_ust_app_event(char *name,
320 struct lttng_ust_event *attr)
321 {
322 struct ust_app_event *ua_event;
323
324 /* Init most of the default value by allocating and zeroing */
325 ua_event = zmalloc(sizeof(struct ust_app_event));
326 if (ua_event == NULL) {
327 PERROR("malloc");
328 goto error;
329 }
330
331 ua_event->enabled = 1;
332 strncpy(ua_event->name, name, sizeof(ua_event->name));
333 ua_event->name[sizeof(ua_event->name) - 1] = '\0';
334 ua_event->ctx = hashtable_new(0);
335 hashtable_node_init(&ua_event->node, (void *) ua_event->name,
336 strlen(ua_event->name));
337
338 /* Copy attributes */
339 if (attr) {
340 memcpy(&ua_event->attr, attr, sizeof(ua_event->attr));
341 }
342
343 DBG3("UST app event %s allocated", ua_event->name);
344
345 return ua_event;
346
347 error:
348 return NULL;
349 }
350
351 /*
352 * Alloc new UST app context.
353 */
354 static
355 struct ust_app_ctx *alloc_ust_app_ctx(struct lttng_ust_context *uctx)
356 {
357 struct ust_app_ctx *ua_ctx;
358
359 ua_ctx = zmalloc(sizeof(struct ust_app_ctx));
360 if (ua_ctx == NULL) {
361 goto error;
362 }
363
364 if (uctx) {
365 memcpy(&ua_ctx->ctx, uctx, sizeof(ua_ctx->ctx));
366 }
367
368 DBG3("UST app context %d allocated", ua_ctx->ctx.ctx);
369
370 error:
371 return ua_ctx;
372 }
373
374 /*
375 * Find an ust_app using the sock and return it. RCU read side lock must be
376 * held before calling this helper function.
377 */
378 static
379 struct ust_app *find_app_by_sock(int sock)
380 {
381 struct cds_lfht_node *node;
382 struct ust_app_key *key;
383 struct cds_lfht_iter iter;
384
385 node = hashtable_lookup(ust_app_sock_key_map,
386 (void *)((unsigned long) sock), sizeof(void *), &iter);
387 if (node == NULL) {
388 DBG2("UST app find by sock %d key not found", sock);
389 goto error;
390 }
391
392 key = caa_container_of(node, struct ust_app_key, node);
393
394 node = hashtable_lookup(ust_app_ht,
395 (void *)((unsigned long) key->pid), sizeof(void *), &iter);
396 if (node == NULL) {
397 DBG2("UST app find by sock %d not found", sock);
398 goto error;
399 }
400 return caa_container_of(node, struct ust_app, node);
401
402 error:
403 return NULL;
404 }
405
406 /*
407 * Create the channel context on the tracer.
408 */
409 static
410 int create_ust_channel_context(struct ust_app_channel *ua_chan,
411 struct ust_app_ctx *ua_ctx, struct ust_app *app)
412 {
413 int ret;
414
415 ret = ustctl_add_context(app->key.sock, &ua_ctx->ctx,
416 ua_chan->obj, &ua_ctx->obj);
417 if (ret < 0) {
418 goto error;
419 }
420
421 ua_ctx->handle = ua_ctx->obj->handle;
422
423 DBG2("UST app context added to channel %s successfully", ua_chan->name);
424
425 error:
426 return ret;
427 }
428
429 /*
430 * Create the event context on the tracer.
431 */
432 static
433 int create_ust_event_context(struct ust_app_event *ua_event,
434 struct ust_app_ctx *ua_ctx, struct ust_app *app)
435 {
436 int ret;
437
438 ret = ustctl_add_context(app->key.sock, &ua_ctx->ctx,
439 ua_event->obj, &ua_ctx->obj);
440 if (ret < 0) {
441 goto error;
442 }
443
444 ua_ctx->handle = ua_ctx->obj->handle;
445
446 DBG2("UST app context added to event %s successfully", ua_event->name);
447
448 error:
449 return ret;
450 }
451
452 /*
453 * Disable the specified event on to UST tracer for the UST session.
454 */
455 static int disable_ust_event(struct ust_app *app,
456 struct ust_app_session *ua_sess, struct ust_app_event *ua_event)
457 {
458 int ret;
459
460 ret = ustctl_disable(app->key.sock, ua_event->obj);
461 if (ret < 0) {
462 ERR("UST app event %s disable failed for app (pid: %d) "
463 "and session handle %d with ret %d",
464 ua_event->attr.name, app->key.pid, ua_sess->handle, ret);
465 goto error;
466 }
467
468 DBG2("UST app event %s disabled successfully for app (pid: %d)",
469 ua_event->attr.name, app->key.pid);
470
471 error:
472 return ret;
473 }
474
475 /*
476 * Disable the specified channel on to UST tracer for the UST session.
477 */
478 static int disable_ust_channel(struct ust_app *app,
479 struct ust_app_session *ua_sess, struct ust_app_channel *ua_chan)
480 {
481 int ret;
482
483 ret = ustctl_disable(app->key.sock, ua_chan->obj);
484 if (ret < 0) {
485 ERR("UST app channel %s disable failed for app (pid: %d) "
486 "and session handle %d with ret %d",
487 ua_chan->name, app->key.pid, ua_sess->handle, ret);
488 goto error;
489 }
490
491 DBG2("UST app channel %s disabled successfully for app (pid: %d)",
492 ua_chan->name, app->key.pid);
493
494 error:
495 return ret;
496 }
497
498 /*
499 * Enable the specified channel on to UST tracer for the UST session.
500 */
501 static int enable_ust_channel(struct ust_app *app,
502 struct ust_app_session *ua_sess, struct ust_app_channel *ua_chan)
503 {
504 int ret;
505
506 ret = ustctl_enable(app->key.sock, ua_chan->obj);
507 if (ret < 0) {
508 ERR("UST app channel %s enable failed for app (pid: %d) "
509 "and session handle %d with ret %d",
510 ua_chan->name, app->key.pid, ua_sess->handle, ret);
511 goto error;
512 }
513
514 ua_chan->enabled = 1;
515
516 DBG2("UST app channel %s enabled successfully for app (pid: %d)",
517 ua_chan->name, app->key.pid);
518
519 error:
520 return ret;
521 }
522
523 /*
524 * Enable the specified event on to UST tracer for the UST session.
525 */
526 static int enable_ust_event(struct ust_app *app,
527 struct ust_app_session *ua_sess, struct ust_app_event *ua_event)
528 {
529 int ret;
530
531 ret = ustctl_enable(app->key.sock, ua_event->obj);
532 if (ret < 0) {
533 ERR("UST app event %s enable failed for app (pid: %d) "
534 "and session handle %d with ret %d",
535 ua_event->attr.name, app->key.pid, ua_sess->handle, ret);
536 goto error;
537 }
538
539 DBG2("UST app event %s enabled successfully for app (pid: %d)",
540 ua_event->attr.name, app->key.pid);
541
542 error:
543 return ret;
544 }
545
546 /*
547 * Open metadata onto the UST tracer for a UST session.
548 */
549 static int open_ust_metadata(struct ust_app *app,
550 struct ust_app_session *ua_sess)
551 {
552 int ret;
553 struct lttng_ust_channel_attr uattr;
554
555 uattr.overwrite = ua_sess->metadata->attr.overwrite;
556 uattr.subbuf_size = ua_sess->metadata->attr.subbuf_size;
557 uattr.num_subbuf = ua_sess->metadata->attr.num_subbuf;
558 uattr.switch_timer_interval =
559 ua_sess->metadata->attr.switch_timer_interval;
560 uattr.read_timer_interval =
561 ua_sess->metadata->attr.read_timer_interval;
562 uattr.output = ua_sess->metadata->attr.output;
563
564 /* UST tracer metadata creation */
565 ret = ustctl_open_metadata(app->key.sock, ua_sess->handle, &uattr,
566 &ua_sess->metadata->obj);
567 if (ret < 0) {
568 ERR("UST app open metadata failed for app pid:%d",
569 app->key.pid);
570 goto error;
571 }
572
573 ua_sess->metadata->handle = ua_sess->metadata->obj->handle;
574
575 error:
576 return ret;
577 }
578
579 /*
580 * Create stream onto the UST tracer for a UST session.
581 */
582 static int create_ust_stream(struct ust_app *app,
583 struct ust_app_session *ua_sess)
584 {
585 int ret;
586
587 ret = ustctl_create_stream(app->key.sock, ua_sess->metadata->obj,
588 &ua_sess->metadata->stream_obj);
589 if (ret < 0) {
590 ERR("UST create metadata stream failed");
591 goto error;
592 }
593
594 error:
595 return ret;
596 }
597
598 /*
599 * Create the specified channel onto the UST tracer for a UST session.
600 */
601 static int create_ust_channel(struct ust_app *app,
602 struct ust_app_session *ua_sess, struct ust_app_channel *ua_chan)
603 {
604 int ret;
605
606 /* TODO: remove cast and use lttng-ust-abi.h */
607 ret = ustctl_create_channel(app->key.sock, ua_sess->handle,
608 (struct lttng_ust_channel_attr *)&ua_chan->attr, &ua_chan->obj);
609 if (ret < 0) {
610 DBG("Error creating channel %s for app (pid: %d, sock: %d) "
611 "and session handle %d with ret %d",
612 ua_chan->name, app->key.pid, app->key.sock,
613 ua_sess->handle, ret);
614 goto error;
615 }
616
617 ua_chan->handle = ua_chan->obj->handle;
618 ua_chan->attr.shm_fd = ua_chan->obj->shm_fd;
619 ua_chan->attr.wait_fd = ua_chan->obj->wait_fd;
620 ua_chan->attr.memory_map_size = ua_chan->obj->memory_map_size;
621
622 DBG2("UST app channel %s created successfully for pid:%d and sock:%d",
623 ua_chan->name, app->key.pid, app->key.sock);
624
625 /* If channel is not enabled, disable it on the tracer */
626 if (!ua_chan->enabled) {
627 ret = disable_ust_channel(app, ua_sess, ua_chan);
628 if (ret < 0) {
629 goto error;
630 }
631 }
632
633 error:
634 return ret;
635 }
636
637 /*
638 * Create the specified event onto the UST tracer for a UST session.
639 */
640 static
641 int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess,
642 struct ust_app_channel *ua_chan, struct ust_app_event *ua_event)
643 {
644 int ret = 0;
645
646 /* Create UST event on tracer */
647 ret = ustctl_create_event(app->key.sock, &ua_event->attr, ua_chan->obj,
648 &ua_event->obj);
649 if (ret < 0) {
650 ERR("Error ustctl create event %s for app pid: %d with ret %d",
651 ua_event->attr.name, app->key.pid, ret);
652 goto error;
653 }
654
655 ua_event->handle = ua_event->obj->handle;
656
657 DBG2("UST app event %s created successfully for pid:%d",
658 ua_event->attr.name, app->key.pid);
659
660 /* If event not enabled, disable it on the tracer */
661 if (!ua_event->enabled) {
662 ret = disable_ust_event(app, ua_sess, ua_event);
663 if (ret < 0) {
664 goto error;
665 }
666 }
667
668 error:
669 return ret;
670 }
671
672 /*
673 * Copy data between an UST app event and a LTT event.
674 */
675 static void shadow_copy_event(struct ust_app_event *ua_event,
676 struct ltt_ust_event *uevent)
677 {
678 struct cds_lfht_iter iter;
679 struct ltt_ust_context *uctx;
680 struct ust_app_ctx *ua_ctx;
681
682 strncpy(ua_event->name, uevent->attr.name, sizeof(ua_event->name));
683 ua_event->name[sizeof(ua_event->name) - 1] = '\0';
684
685 /* Copy event attributes */
686 memcpy(&ua_event->attr, &uevent->attr, sizeof(ua_event->attr));
687
688 cds_lfht_for_each_entry(uevent->ctx, &iter, uctx, node) {
689 ua_ctx = alloc_ust_app_ctx(&uctx->ctx);
690 if (ua_ctx == NULL) {
691 continue;
692 }
693 hashtable_node_init(&ua_ctx->node,
694 (void *)((unsigned long) ua_ctx->ctx.ctx), sizeof(void *));
695 hashtable_add_unique(ua_event->ctx, &ua_ctx->node);
696 }
697 }
698
699 /*
700 * Copy data between an UST app channel and a LTT channel.
701 */
702 static void shadow_copy_channel(struct ust_app_channel *ua_chan,
703 struct ltt_ust_channel *uchan)
704 {
705 struct cds_lfht_iter iter;
706 struct cds_lfht_node *ua_event_node;
707 struct ltt_ust_event *uevent;
708 struct ltt_ust_context *uctx;
709 struct ust_app_event *ua_event;
710 struct ust_app_ctx *ua_ctx;
711
712 DBG2("Shadow copy of UST app channel %s", ua_chan->name);
713
714 strncpy(ua_chan->name, uchan->name, sizeof(ua_chan->name));
715 ua_chan->name[sizeof(ua_chan->name) - 1] = '\0';
716 /* Copy event attributes */
717 memcpy(&ua_chan->attr, &uchan->attr, sizeof(ua_chan->attr));
718
719 cds_lfht_for_each_entry(uchan->ctx, &iter, uctx, node) {
720 ua_ctx = alloc_ust_app_ctx(&uctx->ctx);
721 if (ua_ctx == NULL) {
722 continue;
723 }
724 hashtable_node_init(&ua_ctx->node,
725 (void *)((unsigned long) ua_ctx->ctx.ctx), sizeof(void *));
726 hashtable_add_unique(ua_chan->ctx, &ua_ctx->node);
727 }
728
729 /* Copy all events from ltt ust channel to ust app channel */
730 cds_lfht_for_each_entry(uchan->events, &iter, uevent, node) {
731 struct cds_lfht_iter uiter;
732
733 ua_event_node = hashtable_lookup(ua_chan->events,
734 (void *) uevent->attr.name, strlen(uevent->attr.name),
735 &uiter);
736 if (ua_event_node == NULL) {
737 DBG2("UST event %s not found on shadow copy channel",
738 uevent->attr.name);
739 ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr);
740 if (ua_event == NULL) {
741 continue;
742 }
743 shadow_copy_event(ua_event, uevent);
744 hashtable_add_unique(ua_chan->events, &ua_event->node);
745 }
746 }
747
748 DBG3("Shadow copy channel done");
749 }
750
751 /*
752 * Copy data between a UST app session and a regular LTT session.
753 */
754 static void shadow_copy_session(struct ust_app_session *ua_sess,
755 struct ltt_ust_session *usess,
756 struct ust_app *app)
757 {
758 struct cds_lfht_node *ua_chan_node;
759 struct cds_lfht_iter iter;
760 struct ltt_ust_channel *uchan;
761 struct ust_app_channel *ua_chan;
762 time_t rawtime;
763 struct tm *timeinfo;
764 char datetime[16];
765 int ret;
766
767 /* Get date and time for unique app path */
768 time(&rawtime);
769 timeinfo = localtime(&rawtime);
770 strftime(datetime, sizeof(datetime), "%Y%m%d-%H%M%S", timeinfo);
771
772 DBG2("Shadow copy of session handle %d", ua_sess->handle);
773
774 ua_sess->id = usess->id;
775 ua_sess->uid = usess->uid;
776 ua_sess->gid = usess->gid;
777
778 ret = snprintf(ua_sess->path, PATH_MAX,
779 "%s/%s-%d-%s",
780 usess->pathname, app->name, app->key.pid,
781 datetime);
782 if (ret < 0) {
783 PERROR("asprintf UST shadow copy session");
784 /* TODO: We cannot return an error from here.. */
785 assert(0);
786 }
787
788 /* TODO: support all UST domain */
789
790 /* Iterate over all channels in global domain. */
791 cds_lfht_for_each_entry(usess->domain_global.channels, &iter,
792 uchan, node) {
793 struct cds_lfht_iter uiter;
794
795 ua_chan_node = hashtable_lookup(ua_sess->channels,
796 (void *)uchan->name, strlen(uchan->name),
797 &uiter);
798 if (ua_chan_node != NULL) {
799 continue;
800 }
801
802 DBG2("Channel %s not found on shadow session copy, creating it",
803 uchan->name);
804 ua_chan = alloc_ust_app_channel(uchan->name, &uchan->attr);
805 if (ua_chan == NULL) {
806 /* malloc failed... continuing */
807 continue;
808 }
809
810 shadow_copy_channel(ua_chan, uchan);
811 hashtable_add_unique(ua_sess->channels, &ua_chan->node);
812 }
813 }
814
815 /*
816 * Lookup sesison wrapper.
817 */
818 static
819 void __lookup_session_by_app(struct ltt_ust_session *usess,
820 struct ust_app *app, struct cds_lfht_iter *iter)
821 {
822 /* Get right UST app session from app */
823 (void) hashtable_lookup(app->sessions,
824 (void *) ((unsigned long) usess->id), sizeof(void *),
825 iter);
826 }
827
828 /*
829 * Return ust app session from the app session hashtable using the UST session
830 * id.
831 */
832 static struct ust_app_session *lookup_session_by_app(
833 struct ltt_ust_session *usess, struct ust_app *app)
834 {
835 struct cds_lfht_iter iter;
836 struct cds_lfht_node *node;
837
838 __lookup_session_by_app(usess, app, &iter);
839 node = hashtable_iter_get_node(&iter);
840 if (node == NULL) {
841 goto error;
842 }
843
844 return caa_container_of(node, struct ust_app_session, node);
845
846 error:
847 return NULL;
848 }
849
850 /*
851 * Create a UST session onto the tracer of app and add it the session
852 * hashtable.
853 *
854 * Return ust app session or NULL on error.
855 */
856 static struct ust_app_session *create_ust_app_session(
857 struct ltt_ust_session *usess, struct ust_app *app)
858 {
859 int ret;
860 struct ust_app_session *ua_sess;
861
862 ua_sess = lookup_session_by_app(usess, app);
863 if (ua_sess == NULL) {
864 DBG2("UST app pid: %d session id %d not found, creating it",
865 app->key.pid, usess->id);
866 ua_sess = alloc_ust_app_session();
867 if (ua_sess == NULL) {
868 /* Only malloc can failed so something is really wrong */
869 goto error;
870 }
871 shadow_copy_session(ua_sess, usess, app);
872 }
873
874 if (ua_sess->handle == -1) {
875 ret = ustctl_create_session(app->key.sock);
876 if (ret < 0) {
877 ERR("Error creating session for app pid %d, sock %d",
878 app->key.pid, app->key.sock);
879 /* TODO: free() ua_sess */
880 goto error;
881 }
882
883 DBG2("UST app ustctl create session handle %d", ret);
884 ua_sess->handle = ret;
885
886 /* Add ust app session to app's HT */
887 hashtable_node_init(&ua_sess->node,
888 (void *)((unsigned long) ua_sess->id), sizeof(void *));
889 hashtable_add_unique(app->sessions, &ua_sess->node);
890
891 DBG2("UST app session created successfully with handle %d", ret);
892 }
893
894 return ua_sess;
895
896 error:
897 return NULL;
898 }
899
900 /*
901 * Create a context for the channel on the tracer.
902 */
903 static
904 int create_ust_app_channel_context(struct ust_app_session *ua_sess,
905 struct ust_app_channel *ua_chan, struct lttng_ust_context *uctx,
906 struct ust_app *app)
907 {
908 int ret = 0;
909 struct cds_lfht_iter iter;
910 struct cds_lfht_node *node;
911 struct ust_app_ctx *ua_ctx;
912
913 DBG2("UST app adding context to channel %s", ua_chan->name);
914
915 node = hashtable_lookup(ua_chan->ctx, (void *)((unsigned long)uctx->ctx),
916 sizeof(void *), &iter);
917 if (node != NULL) {
918 ret = -EEXIST;
919 goto error;
920 }
921
922 ua_ctx = alloc_ust_app_ctx(uctx);
923 if (ua_ctx == NULL) {
924 /* malloc failed */
925 ret = -1;
926 goto error;
927 }
928
929 hashtable_node_init(&ua_ctx->node,
930 (void *)((unsigned long) ua_ctx->ctx.ctx), sizeof(void *));
931 hashtable_add_unique(ua_chan->ctx, &ua_ctx->node);
932
933 ret = create_ust_channel_context(ua_chan, ua_ctx, app);
934 if (ret < 0) {
935 goto error;
936 }
937
938 error:
939 return ret;
940 }
941
942 /*
943 * Create an UST context and enable it for the event on the tracer.
944 */
945 static
946 int create_ust_app_event_context(struct ust_app_session *ua_sess,
947 struct ust_app_event *ua_event, struct lttng_ust_context *uctx,
948 struct ust_app *app)
949 {
950 int ret = 0;
951 struct cds_lfht_iter iter;
952 struct cds_lfht_node *node;
953 struct ust_app_ctx *ua_ctx;
954
955 DBG2("UST app adding context to event %s", ua_event->name);
956
957 node = hashtable_lookup(ua_event->ctx, (void *)((unsigned long)uctx->ctx),
958 sizeof(void *), &iter);
959 if (node != NULL) {
960 ret = -EEXIST;
961 goto error;
962 }
963
964 ua_ctx = alloc_ust_app_ctx(uctx);
965 if (ua_ctx == NULL) {
966 /* malloc failed */
967 ret = -1;
968 goto error;
969 }
970
971 hashtable_node_init(&ua_ctx->node,
972 (void *)((unsigned long) ua_ctx->ctx.ctx), sizeof(void *));
973 hashtable_add_unique(ua_event->ctx, &ua_ctx->node);
974
975 ret = create_ust_event_context(ua_event, ua_ctx, app);
976 if (ret < 0) {
977 goto error;
978 }
979
980 error:
981 return ret;
982 }
983
984 /*
985 * Enable on the tracer side a ust app event for the session and channel.
986 */
987 static
988 int enable_ust_app_event(struct ust_app_session *ua_sess,
989 struct ust_app_event *ua_event, struct ust_app *app)
990 {
991 int ret;
992
993 ret = enable_ust_event(app, ua_sess, ua_event);
994 if (ret < 0) {
995 goto error;
996 }
997
998 ua_event->enabled = 1;
999
1000 error:
1001 return ret;
1002 }
1003
1004 /*
1005 * Disable on the tracer side a ust app event for the session and channel.
1006 */
1007 static int disable_ust_app_event(struct ust_app_session *ua_sess,
1008 struct ust_app_event *ua_event, struct ust_app *app)
1009 {
1010 int ret;
1011
1012 ret = disable_ust_event(app, ua_sess, ua_event);
1013 if (ret < 0) {
1014 goto error;
1015 }
1016
1017 ua_event->enabled = 0;
1018
1019 error:
1020 return ret;
1021 }
1022
1023 /*
1024 * Lookup ust app channel for session and disable it on the tracer side.
1025 */
1026 static
1027 int disable_ust_app_channel(struct ust_app_session *ua_sess,
1028 struct ust_app_channel *ua_chan, struct ust_app *app)
1029 {
1030 int ret;
1031
1032 ret = disable_ust_channel(app, ua_sess, ua_chan);
1033 if (ret < 0) {
1034 goto error;
1035 }
1036
1037 ua_chan->enabled = 0;
1038
1039 error:
1040 return ret;
1041 }
1042
1043 /*
1044 * Lookup ust app channel for session and enable it on the tracer side.
1045 */
1046 static int enable_ust_app_channel(struct ust_app_session *ua_sess,
1047 struct ltt_ust_channel *uchan, struct ust_app *app)
1048 {
1049 int ret = 0;
1050 struct cds_lfht_iter iter;
1051 struct cds_lfht_node *ua_chan_node;
1052 struct ust_app_channel *ua_chan;
1053
1054 ua_chan_node = hashtable_lookup(ua_sess->channels,
1055 (void *)uchan->name, strlen(uchan->name), &iter);
1056 if (ua_chan_node == NULL) {
1057 DBG2("Unable to find channel %s in ust session id %u",
1058 uchan->name, ua_sess->id);
1059 goto error;
1060 }
1061
1062 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1063
1064 ret = enable_ust_channel(app, ua_sess, ua_chan);
1065 if (ret < 0) {
1066 goto error;
1067 }
1068
1069 error:
1070 return ret;
1071 }
1072
1073 /*
1074 * Create UST app channel and create it on the tracer.
1075 */
1076 static struct ust_app_channel *create_ust_app_channel(
1077 struct ust_app_session *ua_sess, struct ltt_ust_channel *uchan,
1078 struct ust_app *app)
1079 {
1080 int ret = 0;
1081 struct cds_lfht_iter iter;
1082 struct cds_lfht_node *ua_chan_node;
1083 struct ust_app_channel *ua_chan;
1084
1085 /* Lookup channel in the ust app session */
1086 ua_chan_node = hashtable_lookup(ua_sess->channels,
1087 (void *)uchan->name, strlen(uchan->name), &iter);
1088 if (ua_chan_node == NULL) {
1089 DBG2("Unable to find channel %s in ust session id %u",
1090 uchan->name, ua_sess->id);
1091 ua_chan = alloc_ust_app_channel(uchan->name, &uchan->attr);
1092 if (ua_chan == NULL) {
1093 goto error;
1094 }
1095 shadow_copy_channel(ua_chan, uchan);
1096
1097 hashtable_add_unique(ua_sess->channels, &ua_chan->node);
1098 } else {
1099 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1100 }
1101
1102 ret = create_ust_channel(app, ua_sess, ua_chan);
1103 if (ret < 0) {
1104 goto error;
1105 }
1106
1107 return ua_chan;
1108
1109 error:
1110 return NULL;
1111 }
1112
1113 /*
1114 * Create UST app event and create it on the tracer side.
1115 */
1116 static
1117 int create_ust_app_event(struct ust_app_session *ua_sess,
1118 struct ust_app_channel *ua_chan, struct ltt_ust_event *uevent,
1119 struct ust_app *app)
1120 {
1121 int ret = 0;
1122 struct cds_lfht_iter iter;
1123 struct cds_lfht_node *ua_event_node;
1124 struct ust_app_event *ua_event;
1125
1126 /* Get event node */
1127 ua_event_node = hashtable_lookup(ua_chan->events,
1128 (void *)uevent->attr.name, strlen(uevent->attr.name), &iter);
1129 if (ua_event_node != NULL) {
1130 ERR("UST app event %s already exist. Stopping creation.",
1131 uevent->attr.name);
1132 goto end;
1133 }
1134
1135 /* Does not exist so create one */
1136 ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr);
1137 if (ua_event == NULL) {
1138 /* Only malloc can failed so something is really wrong */
1139 ret = -ENOMEM;
1140 goto error;
1141 }
1142 shadow_copy_event(ua_event, uevent);
1143
1144 /* Create it on the tracer side */
1145 ret = create_ust_event(app, ua_sess, ua_chan, ua_event);
1146 if (ret < 0) {
1147 rcu_read_lock();
1148 delete_ust_app_event(app->key.sock, ua_event);
1149 rcu_read_unlock();
1150 goto error;
1151 }
1152
1153 ua_event->enabled = 1;
1154
1155 hashtable_add_unique(ua_chan->events, &ua_event->node);
1156
1157 DBG2("UST app create event %s for PID %d completed",
1158 ua_event->name, app->key.pid);
1159
1160 end:
1161 error:
1162 return ret;
1163 }
1164
1165 /*
1166 * Create UST metadata and open it on the tracer side.
1167 */
1168 static int create_ust_app_metadata(struct ust_app_session *ua_sess,
1169 char *pathname, struct ust_app *app)
1170 {
1171 int ret = 0;
1172
1173 if (ua_sess->metadata == NULL) {
1174 /* Allocate UST metadata */
1175 ua_sess->metadata = trace_ust_create_metadata(pathname);
1176 if (ua_sess->metadata == NULL) {
1177 ERR("UST app session %d creating metadata failed",
1178 ua_sess->handle);
1179 goto error;
1180 }
1181
1182 ret = open_ust_metadata(app, ua_sess);
1183 if (ret < 0) {
1184 goto error;
1185 }
1186
1187 DBG2("UST metadata opened for app pid %d", app->key.pid);
1188 }
1189
1190 /* Open UST metadata stream */
1191 if (ua_sess->metadata->stream_obj == NULL) {
1192 ret = create_ust_stream(app, ua_sess);
1193 if (ret < 0) {
1194 goto error;
1195 }
1196
1197 ret = mkdir_run_as(ua_sess->path, S_IRWXU | S_IRWXG,
1198 ua_sess->uid, ua_sess->gid);
1199 if (ret < 0) {
1200 PERROR("mkdir UST metadata");
1201 goto error;
1202 }
1203
1204 ret = snprintf(ua_sess->metadata->pathname, PATH_MAX,
1205 "%s/metadata", ua_sess->path);
1206 if (ret < 0) {
1207 PERROR("asprintf UST create stream");
1208 goto error;
1209 }
1210
1211 DBG2("UST metadata stream object created for app pid %d",
1212 app->key.pid);
1213 } else {
1214 ERR("Attempting to create stream without metadata opened");
1215 goto error;
1216 }
1217
1218 return 0;
1219
1220 error:
1221 return -1;
1222 }
1223
1224 /*
1225 * Return pointer to traceable apps list.
1226 */
1227 struct cds_lfht *ust_app_get_ht(void)
1228 {
1229 return ust_app_ht;
1230 }
1231
1232 /*
1233 * Return ust app pointer or NULL if not found.
1234 */
1235 struct ust_app *ust_app_find_by_pid(pid_t pid)
1236 {
1237 struct cds_lfht_node *node;
1238 struct cds_lfht_iter iter;
1239
1240 rcu_read_lock();
1241 node = hashtable_lookup(ust_app_ht,
1242 (void *)((unsigned long) pid), sizeof(void *), &iter);
1243 if (node == NULL) {
1244 DBG2("UST app no found with pid %d", pid);
1245 goto error;
1246 }
1247 rcu_read_unlock();
1248
1249 DBG2("Found UST app by pid %d", pid);
1250
1251 return caa_container_of(node, struct ust_app, node);
1252
1253 error:
1254 rcu_read_unlock();
1255 return NULL;
1256 }
1257
1258 /*
1259 * Using pid and uid (of the app), allocate a new ust_app struct and
1260 * add it to the global traceable app list.
1261 *
1262 * On success, return 0, else return malloc -ENOMEM, or -EINVAL if app
1263 * bitness is not supported.
1264 */
1265 int ust_app_register(struct ust_register_msg *msg, int sock)
1266 {
1267 struct ust_app *lta;
1268
1269 if ((msg->bits_per_long == 64 && ust_consumerd64_fd == -EINVAL)
1270 || (msg->bits_per_long == 32 && ust_consumerd32_fd == -EINVAL)) {
1271 ERR("Registration failed: application \"%s\" (pid: %d) has "
1272 "%d-bit long, but no consumerd for this long size is available.\n",
1273 msg->name, msg->pid, msg->bits_per_long);
1274 close(sock);
1275 return -EINVAL;
1276 }
1277 lta = zmalloc(sizeof(struct ust_app));
1278 if (lta == NULL) {
1279 PERROR("malloc");
1280 return -ENOMEM;
1281 }
1282
1283 lta->ppid = msg->ppid;
1284 lta->uid = msg->uid;
1285 lta->gid = msg->gid;
1286 lta->bits_per_long = msg->bits_per_long;
1287 lta->v_major = msg->major;
1288 lta->v_minor = msg->minor;
1289 strncpy(lta->name, msg->name, sizeof(lta->name));
1290 lta->name[16] = '\0';
1291 lta->sessions = hashtable_new(0);
1292
1293 /* Set key map */
1294 lta->key.pid = msg->pid;
1295 hashtable_node_init(&lta->node, (void *)((unsigned long)lta->key.pid),
1296 sizeof(void *));
1297 lta->key.sock = sock;
1298 hashtable_node_init(&lta->key.node, (void *)((unsigned long)lta->key.sock),
1299 sizeof(void *));
1300
1301 rcu_read_lock();
1302 hashtable_add_unique(ust_app_sock_key_map, &lta->key.node);
1303 hashtable_add_unique(ust_app_ht, &lta->node);
1304 rcu_read_unlock();
1305
1306 DBG("App registered with pid:%d ppid:%d uid:%d gid:%d sock:%d name:%s"
1307 " (version %d.%d)", lta->key.pid, lta->ppid, lta->uid, lta->gid,
1308 lta->key.sock, lta->name, lta->v_major, lta->v_minor);
1309
1310 return 0;
1311 }
1312
1313 /*
1314 * Unregister app by removing it from the global traceable app list and freeing
1315 * the data struct.
1316 *
1317 * The socket is already closed at this point so no close to sock.
1318 */
1319 void ust_app_unregister(int sock)
1320 {
1321 struct ust_app *lta;
1322 struct cds_lfht_node *node;
1323 struct cds_lfht_iter iter;
1324 int ret;
1325
1326 rcu_read_lock();
1327 lta = find_app_by_sock(sock);
1328 if (lta == NULL) {
1329 ERR("Unregister app sock %d not found!", sock);
1330 goto error;
1331 }
1332
1333 DBG("PID %d unregistering with sock %d", lta->key.pid, sock);
1334
1335 /* Get the node reference for a call_rcu */
1336 node = hashtable_lookup(ust_app_ht,
1337 (void *)((unsigned long) lta->key.pid), sizeof(void *), &iter);
1338 if (node == NULL) {
1339 ERR("Unable to find app sock %d by pid %d", sock, lta->key.pid);
1340 goto error;
1341 }
1342
1343 ret = hashtable_del(ust_app_ht, &iter);
1344 assert(!ret);
1345 call_rcu(&node->head, delete_ust_app_rcu);
1346 error:
1347 rcu_read_unlock();
1348 return;
1349 }
1350
1351 /*
1352 * Return traceable_app_count
1353 */
1354 unsigned long ust_app_list_count(void)
1355 {
1356 unsigned long count;
1357
1358 rcu_read_lock();
1359 count = hashtable_get_count(ust_app_ht);
1360 rcu_read_unlock();
1361
1362 return count;
1363 }
1364
1365 /*
1366 * Fill events array with all events name of all registered apps.
1367 */
1368 int ust_app_list_events(struct lttng_event **events)
1369 {
1370 int ret, handle;
1371 size_t nbmem, count = 0;
1372 struct cds_lfht_iter iter;
1373 struct ust_app *app;
1374 struct lttng_event *tmp;
1375
1376 nbmem = UST_APP_EVENT_LIST_SIZE;
1377 tmp = zmalloc(nbmem * sizeof(struct lttng_event));
1378 if (tmp == NULL) {
1379 PERROR("zmalloc ust app events");
1380 ret = -ENOMEM;
1381 goto error;
1382 }
1383
1384 rcu_read_lock();
1385
1386 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1387 struct lttng_ust_tracepoint_iter uiter;
1388
1389 handle = ustctl_tracepoint_list(app->key.sock);
1390 if (handle < 0) {
1391 ERR("UST app list events getting handle failed for app pid %d",
1392 app->key.pid);
1393 continue;
1394 }
1395
1396 while ((ret = ustctl_tracepoint_list_get(app->key.sock, handle,
1397 &uiter)) != -ENOENT) {
1398 if (count >= nbmem) {
1399 DBG2("Reallocating event list from %zu to %zu entries", nbmem,
1400 2 * nbmem);
1401 nbmem *= 2;
1402 tmp = realloc(tmp, nbmem * sizeof(struct lttng_event));
1403 if (tmp == NULL) {
1404 PERROR("realloc ust app events");
1405 ret = -ENOMEM;
1406 goto rcu_error;
1407 }
1408 }
1409 memcpy(tmp[count].name, uiter.name, LTTNG_UST_SYM_NAME_LEN);
1410 memcpy(tmp[count].loglevel, uiter.loglevel, LTTNG_UST_SYM_NAME_LEN);
1411 tmp[count].loglevel_value = uiter.loglevel_value;
1412 tmp[count].type = LTTNG_UST_TRACEPOINT;
1413 tmp[count].pid = app->key.pid;
1414 tmp[count].enabled = -1;
1415 count++;
1416 }
1417 }
1418
1419 ret = count;
1420 *events = tmp;
1421
1422 DBG2("UST app list events done (%zu events)", count);
1423
1424 rcu_error:
1425 rcu_read_unlock();
1426 error:
1427 return ret;
1428 }
1429
1430 /*
1431 * Free and clean all traceable apps of the global list.
1432 */
1433 void ust_app_clean_list(void)
1434 {
1435 int ret;
1436 struct cds_lfht_iter iter;
1437 struct ust_app *app;
1438
1439 DBG2("UST app cleaning registered apps hash table");
1440
1441 rcu_read_lock();
1442
1443 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1444 ret = hashtable_del(ust_app_ht, &iter);
1445 assert(!ret);
1446 call_rcu(&iter.node->head, delete_ust_app_rcu);
1447 }
1448
1449 hashtable_destroy(ust_app_ht);
1450 hashtable_destroy(ust_app_sock_key_map);
1451
1452 rcu_read_unlock();
1453 }
1454
1455 /*
1456 * Init UST app hash table.
1457 */
1458 void ust_app_ht_alloc(void)
1459 {
1460 ust_app_ht = hashtable_new(0);
1461 ust_app_sock_key_map = hashtable_new(0);
1462 }
1463
1464 /*
1465 * For a specific UST session, disable the channel for all registered apps.
1466 */
1467 int ust_app_disable_channel_glb(struct ltt_ust_session *usess,
1468 struct ltt_ust_channel *uchan)
1469 {
1470 int ret = 0;
1471 struct cds_lfht_iter iter;
1472 struct cds_lfht_node *ua_chan_node;
1473 struct ust_app *app;
1474 struct ust_app_session *ua_sess;
1475 struct ust_app_channel *ua_chan;
1476
1477 if (usess == NULL || uchan == NULL) {
1478 ERR("Disabling UST global channel with NULL values");
1479 ret = -1;
1480 goto error;
1481 }
1482
1483 DBG2("UST app disabling channel %s from global domain for session id %d",
1484 uchan->name, usess->id);
1485
1486 rcu_read_lock();
1487
1488 /* For every registered applications */
1489 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1490 struct cds_lfht_iter uiter;
1491
1492 ua_sess = lookup_session_by_app(usess, app);
1493 if (ua_sess == NULL) {
1494 continue;
1495 }
1496
1497 /* Get channel */
1498 ua_chan_node = hashtable_lookup(ua_sess->channels,
1499 (void *)uchan->name, strlen(uchan->name), &uiter);
1500 /* If the session if found for the app, the channel must be there */
1501 assert(ua_chan_node);
1502
1503 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1504 /* The channel must not be already disabled */
1505 assert(ua_chan->enabled == 1);
1506
1507 /* Disable channel onto application */
1508 ret = disable_ust_app_channel(ua_sess, ua_chan, app);
1509 if (ret < 0) {
1510 /* XXX: We might want to report this error at some point... */
1511 continue;
1512 }
1513 }
1514
1515 rcu_read_unlock();
1516
1517 error:
1518 return ret;
1519 }
1520
1521 /*
1522 * For a specific UST session, enable the channel for all registered apps.
1523 */
1524 int ust_app_enable_channel_glb(struct ltt_ust_session *usess,
1525 struct ltt_ust_channel *uchan)
1526 {
1527 int ret = 0;
1528 struct cds_lfht_iter iter;
1529 struct ust_app *app;
1530 struct ust_app_session *ua_sess;
1531
1532 if (usess == NULL || uchan == NULL) {
1533 ERR("Adding UST global channel to NULL values");
1534 ret = -1;
1535 goto error;
1536 }
1537
1538 DBG2("UST app enabling channel %s to global domain for session id %d",
1539 uchan->name, usess->id);
1540
1541 rcu_read_lock();
1542
1543 /* For every registered applications */
1544 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1545 ua_sess = lookup_session_by_app(usess, app);
1546 if (ua_sess == NULL) {
1547 continue;
1548 }
1549
1550 /* Enable channel onto application */
1551 ret = enable_ust_app_channel(ua_sess, uchan, app);
1552 if (ret < 0) {
1553 /* XXX: We might want to report this error at some point... */
1554 continue;
1555 }
1556 }
1557
1558 rcu_read_unlock();
1559
1560 error:
1561 return ret;
1562 }
1563
1564 /*
1565 * Disable an event in a channel and for a specific session.
1566 */
1567 int ust_app_disable_event_glb(struct ltt_ust_session *usess,
1568 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent)
1569 {
1570 int ret = 0;
1571 struct cds_lfht_iter iter;
1572 struct cds_lfht_node *ua_chan_node, *ua_event_node;
1573 struct ust_app *app;
1574 struct ust_app_session *ua_sess;
1575 struct ust_app_channel *ua_chan;
1576 struct ust_app_event *ua_event;
1577
1578 DBG("UST app disabling event %s for all apps in channel "
1579 "%s for session id %d", uevent->attr.name, uchan->name, usess->id);
1580
1581 rcu_read_lock();
1582
1583 /* For all registered applications */
1584 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1585 struct cds_lfht_iter uiter;
1586
1587 ua_sess = lookup_session_by_app(usess, app);
1588 if (ua_sess == NULL) {
1589 /* Next app */
1590 continue;
1591 }
1592
1593 /* Lookup channel in the ust app session */
1594 ua_chan_node = hashtable_lookup(ua_sess->channels,
1595 (void *)uchan->name, strlen(uchan->name), &uiter);
1596 if (ua_chan_node == NULL) {
1597 DBG2("Channel %s not found in session id %d for app pid %d."
1598 "Skipping", uchan->name, usess->id, app->key.pid);
1599 continue;
1600 }
1601 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1602
1603 ua_event_node = hashtable_lookup(ua_chan->events,
1604 (void *)uevent->attr.name, strlen(uevent->attr.name), &uiter);
1605 if (ua_event_node == NULL) {
1606 DBG2("Event %s not found in channel %s for app pid %d."
1607 "Skipping", uevent->attr.name, uchan->name, app->key.pid);
1608 continue;
1609 }
1610 ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
1611
1612 ret = disable_ust_app_event(ua_sess, ua_event, app);
1613 if (ret < 0) {
1614 /* XXX: Report error someday... */
1615 continue;
1616 }
1617 }
1618
1619 rcu_read_unlock();
1620
1621 return ret;
1622 }
1623
1624 /*
1625 * For a specific UST session and UST channel, the event for all
1626 * registered apps.
1627 */
1628 int ust_app_disable_all_event_glb(struct ltt_ust_session *usess,
1629 struct ltt_ust_channel *uchan)
1630 {
1631 int ret = 0;
1632 struct cds_lfht_iter iter;
1633 struct cds_lfht_node *ua_chan_node;
1634 struct ust_app *app;
1635 struct ust_app_session *ua_sess;
1636 struct ust_app_channel *ua_chan;
1637 struct ust_app_event *ua_event;
1638
1639 DBG("UST app disabling all event for all apps in channel "
1640 "%s for session id %d", uchan->name, usess->id);
1641
1642 rcu_read_lock();
1643
1644 /* For all registered applications */
1645 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1646 struct cds_lfht_iter uiter;
1647
1648 ua_sess = lookup_session_by_app(usess, app);
1649 /* If ua_sess is NULL, there is a code flow error */
1650 assert(ua_sess);
1651
1652 /* Lookup channel in the ust app session */
1653 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
1654 strlen(uchan->name), &uiter);
1655 /* If the channel is not found, there is a code flow error */
1656 assert(ua_chan_node);
1657
1658 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1659
1660 /* Disable each events of channel */
1661 cds_lfht_for_each_entry(ua_chan->events, &uiter, ua_event, node) {
1662 ret = disable_ust_app_event(ua_sess, ua_event, app);
1663 if (ret < 0) {
1664 /* XXX: Report error someday... */
1665 continue;
1666 }
1667 }
1668 }
1669
1670 rcu_read_unlock();
1671
1672 return ret;
1673 }
1674
1675 /*
1676 * For a specific UST session, create the channel for all registered apps.
1677 */
1678 int ust_app_create_channel_glb(struct ltt_ust_session *usess,
1679 struct ltt_ust_channel *uchan)
1680 {
1681 int ret = 0;
1682 struct cds_lfht_iter iter;
1683 struct ust_app *app;
1684 struct ust_app_session *ua_sess;
1685 struct ust_app_channel *ua_chan;
1686
1687 if (usess == NULL || uchan == NULL) {
1688 ERR("Adding UST global channel to NULL values");
1689 ret = -1;
1690 goto error;
1691 }
1692
1693 DBG2("UST app adding channel %s to global domain for session id %d",
1694 uchan->name, usess->id);
1695
1696 rcu_read_lock();
1697
1698 /* For every registered applications */
1699 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1700 /*
1701 * Create session on the tracer side and add it to app session HT. Note
1702 * that if session exist, it will simply return a pointer to the ust
1703 * app session.
1704 */
1705 ua_sess = create_ust_app_session(usess, app);
1706 if (ua_sess == NULL) {
1707 continue;
1708 }
1709
1710 /* Create channel onto application */
1711 ua_chan = create_ust_app_channel(ua_sess, uchan, app);
1712 if (ua_chan == NULL) {
1713 continue;
1714 }
1715 }
1716
1717 rcu_read_unlock();
1718
1719 error:
1720 return ret;
1721 }
1722
1723 /*
1724 * Enable event for a specific session and channel on the tracer.
1725 */
1726 int ust_app_enable_event_glb(struct ltt_ust_session *usess,
1727 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent)
1728 {
1729 int ret = 0;
1730 struct cds_lfht_iter iter;
1731 struct cds_lfht_node *ua_chan_node, *ua_event_node;
1732 struct ust_app *app;
1733 struct ust_app_session *ua_sess;
1734 struct ust_app_channel *ua_chan;
1735 struct ust_app_event *ua_event;
1736
1737 DBG("UST app enabling event %s for all apps for session id %d",
1738 uevent->attr.name, usess->id);
1739
1740 /*
1741 * NOTE: At this point, this function is called only if the session and
1742 * channel passed are already created for all apps. and enabled on the
1743 * tracer also.
1744 */
1745
1746 rcu_read_lock();
1747
1748 /* For all registered applications */
1749 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1750 struct cds_lfht_iter uiter;
1751
1752 ua_sess = lookup_session_by_app(usess, app);
1753 /* If ua_sess is NULL, there is a code flow error */
1754 assert(ua_sess);
1755
1756 /* Lookup channel in the ust app session */
1757 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
1758 strlen(uchan->name), &uiter);
1759 /* If the channel is not found, there is a code flow error */
1760 assert(ua_chan_node);
1761
1762 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1763
1764 ua_event_node = hashtable_lookup(ua_chan->events,
1765 (void*)uevent->attr.name, strlen(uevent->attr.name), &uiter);
1766 if (ua_event_node == NULL) {
1767 DBG3("UST app enable event %s not found for app PID %d."
1768 "Skipping app", uevent->attr.name, app->key.pid);
1769 continue;
1770 }
1771 ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
1772
1773 ret = enable_ust_app_event(ua_sess, ua_event, app);
1774 if (ret < 0) {
1775 goto error;
1776 }
1777 }
1778
1779 error:
1780 rcu_read_unlock();
1781 return ret;
1782 }
1783
1784 /*
1785 * For a specific existing UST session and UST channel, creates the event for
1786 * all registered apps.
1787 */
1788 int ust_app_create_event_glb(struct ltt_ust_session *usess,
1789 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent)
1790 {
1791 int ret = 0;
1792 struct cds_lfht_iter iter;
1793 struct cds_lfht_node *ua_chan_node;
1794 struct ust_app *app;
1795 struct ust_app_session *ua_sess;
1796 struct ust_app_channel *ua_chan;
1797
1798 DBG("UST app creating event %s for all apps for session id %d",
1799 uevent->attr.name, usess->id);
1800
1801 /*
1802 * NOTE: At this point, this function is called only if the session and
1803 * channel passed are already created for all apps. and enabled on the
1804 * tracer also.
1805 */
1806
1807 rcu_read_lock();
1808
1809 /* For all registered applications */
1810 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1811 struct cds_lfht_iter uiter;
1812
1813 ua_sess = lookup_session_by_app(usess, app);
1814 /* If ua_sess is NULL, there is a code flow error */
1815 assert(ua_sess);
1816
1817 /* Lookup channel in the ust app session */
1818 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
1819 strlen(uchan->name), &uiter);
1820 /* If the channel is not found, there is a code flow error */
1821 assert(ua_chan_node);
1822
1823 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1824
1825 ret = create_ust_app_event(ua_sess, ua_chan, uevent, app);
1826 if (ret < 0) {
1827 continue;
1828 }
1829 }
1830
1831 rcu_read_unlock();
1832
1833 return ret;
1834 }
1835
1836 /*
1837 * Start tracing for a specific UST session and app.
1838 */
1839 int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app)
1840 {
1841 int ret = 0;
1842 struct cds_lfht_iter iter;
1843 struct ust_app_session *ua_sess;
1844 struct ust_app_channel *ua_chan;
1845 struct ltt_ust_stream *ustream;
1846 int consumerd_fd;
1847
1848 DBG("Starting tracing for ust app pid %d", app->key.pid);
1849
1850 rcu_read_lock();
1851
1852 ua_sess = lookup_session_by_app(usess, app);
1853 if (ua_sess == NULL) {
1854 goto error_rcu_unlock;
1855 }
1856
1857 /* Upon restart, we skip the setup, already done */
1858 if (ua_sess->started) {
1859 goto skip_setup;
1860 }
1861
1862 ret = create_ust_app_metadata(ua_sess, usess->pathname, app);
1863 if (ret < 0) {
1864 goto error_rcu_unlock;
1865 }
1866
1867 /* For each channel */
1868 cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) {
1869 /* Create all streams */
1870 while (1) {
1871 /* Create UST stream */
1872 ustream = zmalloc(sizeof(*ustream));
1873 if (ustream == NULL) {
1874 PERROR("zmalloc ust stream");
1875 goto error_rcu_unlock;
1876 }
1877
1878 ret = ustctl_create_stream(app->key.sock, ua_chan->obj,
1879 &ustream->obj);
1880 if (ret < 0) {
1881 /* Got all streams */
1882 break;
1883 }
1884 ustream->handle = ustream->obj->handle;
1885
1886 /* Order is important */
1887 cds_list_add_tail(&ustream->list, &ua_chan->streams.head);
1888 ret = snprintf(ustream->pathname, PATH_MAX, "%s/%s_%u",
1889 ua_sess->path, ua_chan->name,
1890 ua_chan->streams.count++);
1891 if (ret < 0) {
1892 PERROR("asprintf UST create stream");
1893 continue;
1894 }
1895 DBG2("UST stream %d ready at %s", ua_chan->streams.count,
1896 ustream->pathname);
1897 }
1898 }
1899
1900 switch (app->bits_per_long) {
1901 case 64:
1902 consumerd_fd = ust_consumerd64_fd;
1903 break;
1904 case 32:
1905 consumerd_fd = ust_consumerd32_fd;
1906 break;
1907 default:
1908 ret = -EINVAL;
1909 goto error_rcu_unlock;
1910 }
1911
1912 /* Setup UST consumer socket and send fds to it */
1913 ret = ust_consumer_send_session(consumerd_fd, ua_sess);
1914 if (ret < 0) {
1915 goto error_rcu_unlock;
1916 }
1917 ua_sess->started = 1;
1918
1919 skip_setup:
1920 /* This start the UST tracing */
1921 ret = ustctl_start_session(app->key.sock, ua_sess->handle);
1922 if (ret < 0) {
1923 ERR("Error starting tracing for app pid: %d", app->key.pid);
1924 goto error_rcu_unlock;
1925 }
1926
1927 rcu_read_unlock();
1928
1929 /* Quiescent wait after starting trace */
1930 ustctl_wait_quiescent(app->key.sock);
1931
1932 return 0;
1933
1934 error_rcu_unlock:
1935 rcu_read_unlock();
1936 return -1;
1937 }
1938
1939 /*
1940 * Stop tracing for a specific UST session and app.
1941 */
1942 int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app)
1943 {
1944 int ret = 0;
1945 struct cds_lfht_iter iter;
1946 struct ust_app_session *ua_sess;
1947 struct ust_app_channel *ua_chan;
1948
1949 DBG("Stopping tracing for ust app pid %d", app->key.pid);
1950
1951 rcu_read_lock();
1952
1953 ua_sess = lookup_session_by_app(usess, app);
1954 if (ua_sess == NULL) {
1955 /* Only malloc can failed so something is really wrong */
1956 goto error_rcu_unlock;
1957 }
1958
1959 /* This inhibits UST tracing */
1960 ret = ustctl_stop_session(app->key.sock, ua_sess->handle);
1961 if (ret < 0) {
1962 ERR("Error stopping tracing for app pid: %d", app->key.pid);
1963 goto error_rcu_unlock;
1964 }
1965
1966 /* Quiescent wait after stopping trace */
1967 ustctl_wait_quiescent(app->key.sock);
1968
1969 /* Flushing buffers */
1970 cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) {
1971 ret = ustctl_sock_flush_buffer(app->key.sock, ua_chan->obj);
1972 if (ret < 0) {
1973 ERR("UST app PID %d channel %s flush failed",
1974 app->key.pid, ua_chan->name);
1975 ERR("Ended with ret %d", ret);
1976 /* Continuing flushing all buffers */
1977 continue;
1978 }
1979 }
1980
1981 /* Flush all buffers before stopping */
1982 ret = ustctl_sock_flush_buffer(app->key.sock, ua_sess->metadata->obj);
1983 if (ret < 0) {
1984 ERR("UST app PID %d metadata flush failed", app->key.pid);
1985 ERR("Ended with ret %d", ret);
1986 }
1987
1988 rcu_read_unlock();
1989
1990 return 0;
1991
1992 error_rcu_unlock:
1993 rcu_read_unlock();
1994 return -1;
1995 }
1996
1997 /*
1998 * Destroy a specific UST session in apps.
1999 */
2000 int ust_app_destroy_trace(struct ltt_ust_session *usess, struct ust_app *app)
2001 {
2002 struct ust_app_session *ua_sess;
2003 struct lttng_ust_object_data obj;
2004 struct cds_lfht_iter iter;
2005 struct cds_lfht_node *node;
2006 int ret;
2007
2008 DBG("Destroy tracing for ust app pid %d", app->key.pid);
2009
2010 rcu_read_lock();
2011
2012 __lookup_session_by_app(usess, app, &iter);
2013 node = hashtable_iter_get_node(&iter);
2014 if (node == NULL) {
2015 /* Only malloc can failed so something is really wrong */
2016 goto error_rcu_unlock;
2017 }
2018 ua_sess = caa_container_of(node, struct ust_app_session, node);
2019 ret = hashtable_del(app->sessions, &iter);
2020 assert(!ret);
2021 delete_ust_app_session(app->key.sock, ua_sess);
2022 obj.handle = ua_sess->handle;
2023 obj.shm_fd = -1;
2024 obj.wait_fd = -1;
2025 obj.memory_map_size = 0;
2026 ustctl_release_object(app->key.sock, &obj);
2027
2028 rcu_read_unlock();
2029
2030 /* Quiescent wait after stopping trace */
2031 ustctl_wait_quiescent(app->key.sock);
2032
2033 return 0;
2034
2035 error_rcu_unlock:
2036 rcu_read_unlock();
2037 return -1;
2038 }
2039
2040 /*
2041 * Start tracing for the UST session.
2042 */
2043 int ust_app_start_trace_all(struct ltt_ust_session *usess)
2044 {
2045 int ret = 0;
2046 struct cds_lfht_iter iter;
2047 struct ust_app *app;
2048
2049 DBG("Starting all UST traces");
2050
2051 rcu_read_lock();
2052
2053 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
2054 ret = ust_app_start_trace(usess, app);
2055 if (ret < 0) {
2056 /* Continue to next apps even on error */
2057 continue;
2058 }
2059 }
2060
2061 rcu_read_unlock();
2062
2063 return 0;
2064 }
2065
2066 /*
2067 * Start tracing for the UST session.
2068 */
2069 int ust_app_stop_trace_all(struct ltt_ust_session *usess)
2070 {
2071 int ret = 0;
2072 struct cds_lfht_iter iter;
2073 struct ust_app *app;
2074
2075 DBG("Stopping all UST traces");
2076
2077 rcu_read_lock();
2078
2079 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
2080 ret = ust_app_stop_trace(usess, app);
2081 if (ret < 0) {
2082 /* Continue to next apps even on error */
2083 continue;
2084 }
2085 }
2086
2087 rcu_read_unlock();
2088
2089 return 0;
2090 }
2091
2092 /*
2093 * Destroy app UST session.
2094 */
2095 int ust_app_destroy_trace_all(struct ltt_ust_session *usess)
2096 {
2097 int ret = 0;
2098 struct cds_lfht_iter iter;
2099 struct ust_app *app;
2100
2101 DBG("Destroy all UST traces");
2102
2103 rcu_read_lock();
2104
2105 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
2106 ret = ust_app_destroy_trace(usess, app);
2107 if (ret < 0) {
2108 /* Continue to next apps even on error */
2109 continue;
2110 }
2111 }
2112
2113 rcu_read_unlock();
2114
2115 return 0;
2116 }
2117
2118 /*
2119 * Add channels/events from UST global domain to registered apps at sock.
2120 */
2121 void ust_app_global_update(struct ltt_ust_session *usess, int sock)
2122 {
2123 int ret = 0;
2124 struct cds_lfht_iter iter;
2125 struct ust_app *app;
2126 struct ust_app_session *ua_sess;
2127 struct ust_app_channel *ua_chan;
2128 struct ust_app_event *ua_event;
2129
2130 if (usess == NULL) {
2131 ERR("No UST session on global update. Returning");
2132 goto error;
2133 }
2134
2135 DBG2("UST app global update for app sock %d for session id %d", sock,
2136 usess->id);
2137
2138 rcu_read_lock();
2139
2140 app = find_app_by_sock(sock);
2141 if (app == NULL) {
2142 ERR("Failed to update app sock %d", sock);
2143 goto error;
2144 }
2145
2146 ua_sess = create_ust_app_session(usess, app);
2147 if (ua_sess == NULL) {
2148 goto error;
2149 }
2150
2151 /*
2152 * We can iterate safely here over all UST app session sicne the create ust
2153 * app session above made a shadow copy of the UST global domain from the
2154 * ltt ust session.
2155 */
2156 cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) {
2157 struct cds_lfht_iter uiter;
2158
2159 ret = create_ust_channel(app, ua_sess, ua_chan);
2160 if (ret < 0) {
2161 /* FIXME: Should we quit here or continue... */
2162 continue;
2163 }
2164
2165 /* For each events */
2166 cds_lfht_for_each_entry(ua_chan->events, &uiter, ua_event, node) {
2167 ret = create_ust_event(app, ua_sess, ua_chan, ua_event);
2168 if (ret < 0) {
2169 /* FIXME: Should we quit here or continue... */
2170 continue;
2171 }
2172 }
2173 }
2174
2175 if (usess->start_trace) {
2176 ret = ust_app_start_trace(usess, app);
2177 if (ret < 0) {
2178 goto error;
2179 }
2180
2181 DBG2("UST trace started for app pid %d", app->key.pid);
2182 }
2183
2184 error:
2185 rcu_read_unlock();
2186 return;
2187 }
2188
2189 /*
2190 * Add context to a specific channel for global UST domain.
2191 */
2192 int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess,
2193 struct ltt_ust_channel *uchan, struct ltt_ust_context *uctx)
2194 {
2195 int ret = 0;
2196 struct cds_lfht_node *ua_chan_node;
2197 struct cds_lfht_iter iter;
2198 struct ust_app_channel *ua_chan = NULL;
2199 struct ust_app_session *ua_sess;
2200 struct ust_app *app;
2201
2202 rcu_read_lock();
2203
2204 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
2205 struct cds_lfht_iter uiter;
2206
2207 ua_sess = lookup_session_by_app(usess, app);
2208 if (ua_sess == NULL) {
2209 continue;
2210 }
2211
2212 /* Lookup channel in the ust app session */
2213 ua_chan_node = hashtable_lookup(ua_sess->channels,
2214 (void *)uchan->name, strlen(uchan->name), &uiter);
2215 if (ua_chan_node == NULL) {
2216 continue;
2217 }
2218 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel,
2219 node);
2220
2221 ret = create_ust_app_channel_context(ua_sess, ua_chan, &uctx->ctx, app);
2222 if (ret < 0) {
2223 continue;
2224 }
2225 }
2226
2227 rcu_read_unlock();
2228 return ret;
2229 }
2230
2231 /*
2232 * Add context to a specific event in a channel for global UST domain.
2233 */
2234 int ust_app_add_ctx_event_glb(struct ltt_ust_session *usess,
2235 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent,
2236 struct ltt_ust_context *uctx)
2237 {
2238 int ret = 0;
2239 struct cds_lfht_node *ua_chan_node, *ua_event_node;
2240 struct cds_lfht_iter iter;
2241 struct ust_app_session *ua_sess;
2242 struct ust_app_event *ua_event;
2243 struct ust_app_channel *ua_chan = NULL;
2244 struct ust_app *app;
2245
2246 rcu_read_lock();
2247
2248 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
2249 struct cds_lfht_iter uiter;
2250
2251 ua_sess = lookup_session_by_app(usess, app);
2252 if (ua_sess == NULL) {
2253 continue;
2254 }
2255
2256 /* Lookup channel in the ust app session */
2257 ua_chan_node = hashtable_lookup(ua_sess->channels,
2258 (void *)uchan->name, strlen(uchan->name), &uiter);
2259 if (ua_chan_node == NULL) {
2260 continue;
2261 }
2262 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel,
2263 node);
2264
2265 ua_event_node = hashtable_lookup(ua_chan->events,
2266 (void *)uevent->attr.name, strlen(uevent->attr.name), &uiter);
2267 if (ua_event_node == NULL) {
2268 continue;
2269 }
2270 ua_event = caa_container_of(ua_event_node, struct ust_app_event,
2271 node);
2272
2273 ret = create_ust_app_event_context(ua_sess, ua_event, &uctx->ctx, app);
2274 if (ret < 0) {
2275 continue;
2276 }
2277 }
2278
2279 rcu_read_unlock();
2280 return ret;
2281 }
2282
2283 /*
2284 * Enable event for a channel from a UST session for a specific PID.
2285 */
2286 int ust_app_enable_event_pid(struct ltt_ust_session *usess,
2287 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, pid_t pid)
2288 {
2289 int ret = 0;
2290 struct cds_lfht_iter iter;
2291 struct cds_lfht_node *ua_chan_node, *ua_event_node;
2292 struct ust_app *app;
2293 struct ust_app_session *ua_sess;
2294 struct ust_app_channel *ua_chan;
2295 struct ust_app_event *ua_event;
2296
2297 DBG("UST app enabling event %s for PID %d", uevent->attr.name, pid);
2298
2299 rcu_read_lock();
2300
2301 app = ust_app_find_by_pid(pid);
2302 if (app == NULL) {
2303 ERR("UST app enable event per PID %d not found", pid);
2304 ret = -1;
2305 goto error;
2306 }
2307
2308 ua_sess = lookup_session_by_app(usess, app);
2309 /* If ua_sess is NULL, there is a code flow error */
2310 assert(ua_sess);
2311
2312 /* Lookup channel in the ust app session */
2313 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
2314 strlen(uchan->name), &iter);
2315 /* If the channel is not found, there is a code flow error */
2316 assert(ua_chan_node);
2317
2318 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
2319
2320 ua_event_node = hashtable_lookup(ua_chan->events,
2321 (void*)uevent->attr.name, strlen(uevent->attr.name), &iter);
2322 if (ua_event_node == NULL) {
2323 ret = create_ust_app_event(ua_sess, ua_chan, uevent, app);
2324 if (ret < 0) {
2325 goto error;
2326 }
2327 } else {
2328 ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
2329
2330 ret = enable_ust_app_event(ua_sess, ua_event, app);
2331 if (ret < 0) {
2332 goto error;
2333 }
2334 }
2335
2336 error:
2337 rcu_read_unlock();
2338 return ret;
2339 }
2340
2341 /*
2342 * Disable event for a channel from a UST session for a specific PID.
2343 */
2344 int ust_app_disable_event_pid(struct ltt_ust_session *usess,
2345 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, pid_t pid)
2346 {
2347 int ret = 0;
2348 struct cds_lfht_iter iter;
2349 struct cds_lfht_node *ua_chan_node, *ua_event_node;
2350 struct ust_app *app;
2351 struct ust_app_session *ua_sess;
2352 struct ust_app_channel *ua_chan;
2353 struct ust_app_event *ua_event;
2354
2355 DBG("UST app disabling event %s for PID %d", uevent->attr.name, pid);
2356
2357 rcu_read_lock();
2358
2359 app = ust_app_find_by_pid(pid);
2360 if (app == NULL) {
2361 ERR("UST app disable event per PID %d not found", pid);
2362 ret = -1;
2363 goto error;
2364 }
2365
2366 ua_sess = lookup_session_by_app(usess, app);
2367 /* If ua_sess is NULL, there is a code flow error */
2368 assert(ua_sess);
2369
2370 /* Lookup channel in the ust app session */
2371 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
2372 strlen(uchan->name), &iter);
2373 if (ua_chan_node == NULL) {
2374 /* Channel does not exist, skip disabling */
2375 goto error;
2376 }
2377 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
2378
2379 ua_event_node = hashtable_lookup(ua_chan->events,
2380 (void*)uevent->attr.name, strlen(uevent->attr.name), &iter);
2381 if (ua_event_node == NULL) {
2382 /* Event does not exist, skip disabling */
2383 goto error;
2384 }
2385 ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
2386
2387 ret = disable_ust_app_event(ua_sess, ua_event, app);
2388 if (ret < 0) {
2389 goto error;
2390 }
2391
2392 error:
2393 rcu_read_unlock();
2394 return ret;
2395 }
This page took 0.113048 seconds and 5 git commands to generate.