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