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