Add tracepoint listing for UST
[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 <lttngerr.h>
30 #include <lttng-share.h>
31
32 #include "hashtable.h"
33 #include "ust-app.h"
34 #include "../hashtable/hash.h"
35 #include "ust-ctl.h"
36 #include "ust-consumer.h"
37
38 /*
39 * Delete a traceable application structure from the global list.
40 */
41 static void delete_ust_app(struct ust_app *lta)
42 {
43 int ret;
44 struct cds_lfht_node *node;
45 struct cds_lfht_iter iter;
46
47 rcu_read_lock();
48
49 /* TODO: clean session hashtable */
50 free(lta->sessions);
51 close(lta->key.sock);
52
53 /* Remove from apps hash table */
54 node = hashtable_lookup(ust_app_ht,
55 (void *) ((unsigned long) lta->key.pid), sizeof(void *), &iter);
56 if (node == NULL) {
57 ERR("UST app pid %d not found in hash table", lta->key.pid);
58 } else {
59 ret = hashtable_del(ust_app_ht, &iter);
60 if (ret) {
61 ERR("UST app unable to delete app %d from hash table",
62 lta->key.pid);
63 } else {
64 DBG2("UST app pid %d deleted", lta->key.pid);
65 }
66 }
67
68 /* Remove from key hash table */
69 node = hashtable_lookup(ust_app_sock_key_map,
70 (void *) ((unsigned long) lta->key.sock), sizeof(void *), &iter);
71 if (node == NULL) {
72 ERR("UST app key %d not found in key hash table", lta->key.sock);
73 } else {
74 ret = hashtable_del(ust_app_sock_key_map, &iter);
75 if (ret) {
76 ERR("UST app unable to delete app sock %d from key hash table",
77 lta->key.sock);
78 } else {
79 DBG2("UST app pair sock %d key %d deleted",
80 lta->key.sock, lta->key.pid);
81 }
82 }
83
84 free(lta);
85
86 rcu_read_unlock();
87 }
88
89 /*
90 * URCU intermediate call to delete an UST app.
91 */
92 static void delete_ust_app_rcu(struct rcu_head *head)
93 {
94 struct cds_lfht_node *node =
95 caa_container_of(head, struct cds_lfht_node, head);
96 struct ust_app *app =
97 caa_container_of(node, struct ust_app, node);
98
99 delete_ust_app(app);
100 }
101
102 /*
103 * Find an ust_app using the sock and return it. RCU read side lock must be
104 * held before calling this helper function.
105 */
106 static struct ust_app *find_app_by_sock(int sock)
107 {
108 struct cds_lfht_node *node;
109 struct ust_app_key *key;
110 struct cds_lfht_iter iter;
111
112 node = hashtable_lookup(ust_app_sock_key_map,
113 (void *)((unsigned long) sock), sizeof(void *), &iter);
114 if (node == NULL) {
115 DBG2("UST app find by sock %d key not found", sock);
116 rcu_read_unlock();
117 goto error;
118 }
119
120 key = caa_container_of(node, struct ust_app_key, node);
121
122 node = hashtable_lookup(ust_app_ht,
123 (void *)((unsigned long) key->pid), sizeof(void *), &iter);
124 if (node == NULL) {
125 DBG2("UST app find by sock %d not found", sock);
126 rcu_read_unlock();
127 goto error;
128 }
129
130 return caa_container_of(node, struct ust_app, node);
131
132 error:
133 return NULL;
134 }
135
136 /*
137 * Return pointer to traceable apps list.
138 */
139 struct cds_lfht *ust_app_get_ht(void)
140 {
141 return ust_app_ht;
142 }
143
144 /*
145 * Return ust app pointer or NULL if not found.
146 */
147 struct ust_app *ust_app_find_by_pid(pid_t pid)
148 {
149 struct cds_lfht_node *node;
150 struct cds_lfht_iter iter;
151
152 rcu_read_lock();
153 node = hashtable_lookup(ust_app_ht,
154 (void *)((unsigned long) pid), sizeof(void *), &iter);
155 if (node == NULL) {
156 rcu_read_unlock();
157 DBG2("UST app no found with pid %d", pid);
158 goto error;
159 }
160 rcu_read_unlock();
161
162 DBG2("Found UST app by pid %d", pid);
163
164 return caa_container_of(node, struct ust_app, node);
165
166 error:
167 return NULL;
168 }
169
170 /*
171 * Using pid and uid (of the app), allocate a new ust_app struct and
172 * add it to the global traceable app list.
173 *
174 * On success, return 0, else return malloc ENOMEM.
175 */
176 int ust_app_register(struct ust_register_msg *msg, int sock)
177 {
178 struct ust_app *lta;
179
180 lta = malloc(sizeof(struct ust_app));
181 if (lta == NULL) {
182 PERROR("malloc");
183 return -ENOMEM;
184 }
185
186 lta->uid = msg->uid;
187 lta->gid = msg->gid;
188 lta->key.pid = msg->pid;
189 lta->ppid = msg->ppid;
190 lta->v_major = msg->major;
191 lta->v_minor = msg->minor;
192 lta->key.sock = sock;
193 strncpy(lta->name, msg->name, sizeof(lta->name));
194 lta->name[16] = '\0';
195 hashtable_node_init(&lta->node, (void *)((unsigned long)lta->key.pid),
196 sizeof(void *));
197
198 /* Session hashtable */
199 lta->sessions = hashtable_new(0);
200
201 /* Set sock key map */
202 hashtable_node_init(&lta->key.node, (void *)((unsigned long)lta->key.sock),
203 sizeof(void *));
204
205 rcu_read_lock();
206 hashtable_add_unique(ust_app_ht, &lta->node);
207 hashtable_add_unique(ust_app_sock_key_map, &lta->key.node);
208 rcu_read_unlock();
209
210 DBG("App registered with pid:%d ppid:%d uid:%d gid:%d sock:%d name:%s"
211 " (version %d.%d)", lta->key.pid, lta->ppid, lta->uid, lta->gid,
212 lta->key.sock, lta->name, lta->v_major, lta->v_minor);
213
214 return 0;
215 }
216
217 /*
218 * Unregister app by removing it from the global traceable app list and freeing
219 * the data struct.
220 *
221 * The socket is already closed at this point so no close to sock.
222 */
223 void ust_app_unregister(int sock)
224 {
225 struct ust_app *lta;
226 struct cds_lfht_node *node;
227 struct cds_lfht_iter iter;
228
229 rcu_read_lock();
230 lta = find_app_by_sock(sock);
231 if (lta == NULL) {
232 ERR("Unregister app sock %d not found!", sock);
233 goto error;
234 }
235
236 DBG("PID %d unregistering with sock %d", lta->key.pid, sock);
237
238 /* Get the node reference for a call_rcu */
239 node = hashtable_lookup(ust_app_ht,
240 (void *)((unsigned long) lta->key.pid), sizeof(void *), &iter);
241 if (node == NULL) {
242 ERR("Unable to find app sock %d by pid %d", sock, lta->key.pid);
243 goto error;
244 }
245
246 call_rcu(&node->head, delete_ust_app_rcu);
247
248 error:
249 rcu_read_unlock();
250 return;
251 }
252
253 /*
254 * Return traceable_app_count
255 */
256 unsigned long ust_app_list_count(void)
257 {
258 unsigned long count;
259
260 rcu_read_lock();
261 count = hashtable_get_count(ust_app_ht);
262 rcu_read_unlock();
263
264 return count;
265 }
266
267 /*
268 * Fill events array with all events name of all registered apps.
269 */
270 int ust_app_list_events(struct lttng_event **events)
271 {
272 int ret, handle;
273 size_t nbmem, count = 0;
274 struct cds_lfht_iter iter;
275 struct ust_app *app;
276 struct lttng_event *tmp;
277
278 nbmem = UST_APP_EVENT_LIST_SIZE;
279 tmp = zmalloc(nbmem * sizeof(struct lttng_event));
280 if (tmp == NULL) {
281 PERROR("zmalloc ust app events");
282 ret = -ENOMEM;
283 goto error;
284 }
285
286 rcu_read_lock();
287
288 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
289 handle = ustctl_tracepoint_list(app->key.sock);
290 if (handle < 0) {
291 ERR("UST app list events getting handle failed for app pid %d",
292 app->key.pid);
293 continue;
294 }
295
296 while ((ret = ustctl_tracepoint_list_get(app->key.sock, handle,
297 tmp[count].name)) != -ENOENT) {
298 if (count > nbmem) {
299 DBG2("Reallocating event list from %zu to %zu bytes", nbmem,
300 nbmem + UST_APP_EVENT_LIST_SIZE);
301 nbmem += UST_APP_EVENT_LIST_SIZE;
302 tmp = realloc(tmp, nbmem);
303 if (tmp == NULL) {
304 PERROR("realloc ust app events");
305 ret = -ENOMEM;
306 goto rcu_error;
307 }
308 }
309
310 tmp[count].type = LTTNG_UST_TRACEPOINT;
311 tmp[count].pid = app->key.pid;
312 count++;
313 }
314 }
315
316 ret = count;
317 *events = tmp;
318
319 DBG2("UST app list events done (%zu events)", count);
320
321 rcu_error:
322 rcu_read_unlock();
323 error:
324 return ret;
325 }
326
327 /*
328 * Free and clean all traceable apps of the global list.
329 */
330 void ust_app_clean_list(void)
331 {
332 int ret;
333 struct cds_lfht_node *node;
334 struct cds_lfht_iter iter;
335
336 DBG2("UST app clean hash table");
337
338 rcu_read_lock();
339
340 hashtable_get_first(ust_app_ht, &iter);
341 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
342 ret = hashtable_del(ust_app_ht, &iter);
343 if (!ret) {
344 call_rcu(&node->head, delete_ust_app_rcu);
345 }
346 hashtable_get_next(ust_app_ht, &iter);
347 }
348
349 rcu_read_unlock();
350 }
351
352 /*
353 * Init UST app hash table.
354 */
355 void ust_app_ht_alloc(void)
356 {
357 ust_app_ht = hashtable_new(0);
358 ust_app_sock_key_map = hashtable_new(0);
359 }
360
361 /*
362 * Alloc new UST app session.
363 */
364 static struct ust_app_session *alloc_ust_app_session(void)
365 {
366 struct ust_app_session *ua_sess;
367
368 /* Init most of the default value by allocating and zeroing */
369 ua_sess = zmalloc(sizeof(struct ust_app_session));
370 if (ua_sess == NULL) {
371 PERROR("malloc");
372 goto error;
373 }
374
375 ua_sess->handle = -1;
376 ua_sess->channels = hashtable_new_str(0);
377
378 return ua_sess;
379
380 error:
381 return NULL;
382 }
383
384 /*
385 * Alloc new UST app channel.
386 */
387 static struct ust_app_channel *alloc_ust_app_channel(char *name)
388 {
389 struct ust_app_channel *ua_chan;
390
391 /* Init most of the default value by allocating and zeroing */
392 ua_chan = zmalloc(sizeof(struct ust_app_channel));
393 if (ua_chan == NULL) {
394 PERROR("malloc");
395 goto error;
396 }
397
398 strncpy(ua_chan->name, name, sizeof(ua_chan->name));
399 ua_chan->name[sizeof(ua_chan->name) - 1] = '\0';
400 ua_chan->handle = -1;
401 ua_chan->ctx = hashtable_new(0);
402 CDS_INIT_LIST_HEAD(&ua_chan->streams.head);
403 ua_chan->events = hashtable_new_str(0);
404 hashtable_node_init(&ua_chan->node, (void *) ua_chan->name,
405 strlen(ua_chan->name));
406
407 DBG3("UST app channel %s allocated", ua_chan->name);
408
409 return ua_chan;
410
411 error:
412 return NULL;
413 }
414
415 /*
416 * Alloc new UST app event.
417 */
418 static struct ust_app_event *alloc_ust_app_event(char *name)
419 {
420 struct ust_app_event *ua_event;
421
422 /* Init most of the default value by allocating and zeroing */
423 ua_event = zmalloc(sizeof(struct ust_app_event));
424 if (ua_event == NULL) {
425 PERROR("malloc");
426 goto error;
427 }
428
429 strncpy(ua_event->name, name, sizeof(ua_event->name));
430 ua_event->name[sizeof(ua_event->name) - 1] = '\0';
431 ua_event->ctx = hashtable_new(0);
432 hashtable_node_init(&ua_event->node, (void *) ua_event->name,
433 strlen(ua_event->name));
434
435 DBG3("UST app event %s allocated", ua_event->name);
436
437 return ua_event;
438
439 error:
440 return NULL;
441 }
442
443 static void shadow_copy_event(struct ust_app_event *ua_event,
444 struct ltt_ust_event *uevent)
445 {
446 strncpy(ua_event->name, uevent->attr.name, sizeof(ua_event->name));
447 ua_event->name[sizeof(ua_event->name) - 1] = '\0';
448
449 /* TODO: support copy context */
450 }
451
452 static void shadow_copy_channel(struct ust_app_channel *ua_chan,
453 struct ltt_ust_channel *uchan)
454 {
455 struct cds_lfht_iter iter;
456 struct cds_lfht_node *node, *ua_event_node;
457 struct ltt_ust_event *uevent;
458 struct ust_app_event *ua_event;
459
460 DBG2("Shadow copy of UST app channel %s", ua_chan->name);
461
462 strncpy(ua_chan->name, uchan->name, sizeof(ua_chan->name));
463 ua_chan->name[sizeof(ua_chan->name) - 1] = '\0';
464
465 /* TODO: support copy context */
466
467 /* Copy all events from ltt ust channel to ust app channel */
468 hashtable_get_first(uchan->events, &iter);
469 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
470 uevent = caa_container_of(node, struct ltt_ust_event, node);
471
472 ua_event_node = hashtable_lookup(ua_chan->events,
473 (void *) uevent->attr.name, strlen(uevent->attr.name), &iter);
474 if (ua_event_node == NULL) {
475 DBG2("UST event %s not found on shadow copy channel",
476 uevent->attr.name);
477 ua_event = alloc_ust_app_event(uevent->attr.name);
478 if (ua_event == NULL) {
479 goto next;
480 }
481 shadow_copy_event(ua_event, uevent);
482 hashtable_add_unique(ua_chan->events, &ua_event->node);
483 }
484
485 next:
486 /* Get next UST events */
487 hashtable_get_next(uchan->events, &iter);
488 }
489
490 DBG3("Shadow copy channel done");
491 }
492
493 static void shadow_copy_session(struct ust_app_session *ua_sess,
494 struct ltt_ust_session *usess)
495 {
496 struct cds_lfht_node *node, *ua_chan_node;
497 struct cds_lfht_iter iter;
498 struct ltt_ust_channel *uchan;
499 struct ust_app_channel *ua_chan;
500
501 DBG2("Shadow copy of session handle %d", ua_sess->handle);
502
503 ua_sess->uid = usess->uid;
504
505 /* TODO: support all UST domain */
506
507 /* Iterate over all channels in global domain. */
508 hashtable_get_first(usess->domain_global.channels, &iter);
509 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
510 uchan = caa_container_of(node, struct ltt_ust_channel, node);
511
512 ua_chan_node = hashtable_lookup(ua_sess->channels,
513 (void *)uchan->name, strlen(uchan->name), &iter);
514 if (ua_chan_node == NULL) {
515 DBG2("Channel %s not found on shadow session copy, creating it",
516 uchan->name);
517 ua_chan = alloc_ust_app_channel(uchan->name);
518 if (ua_chan == NULL) {
519 /* malloc failed... continuing */
520 goto next;
521 }
522
523 shadow_copy_channel(ua_chan, uchan);
524 hashtable_add_unique(ua_sess->channels, &ua_chan->node);
525 }
526
527 next:
528 /* Next item in hash table */
529 hashtable_get_next(usess->domain_global.channels, &iter);
530 }
531 }
532
533 /*
534 * Return ust app session from the app session hashtable using the UST session
535 * uid.
536 */
537 static struct ust_app_session *lookup_session_by_app(
538 struct ltt_ust_session *usess, struct ust_app *app)
539 {
540 struct cds_lfht_iter iter;
541 struct cds_lfht_node *node;
542
543 /* Get right UST app session from app */
544 node = hashtable_lookup(app->sessions,
545 (void *) ((unsigned long) usess->uid), sizeof(void *), &iter);
546 if (node == NULL) {
547 goto error;
548 }
549
550 return caa_container_of(node, struct ust_app_session, node);
551
552 error:
553 return NULL;
554 }
555
556 /*
557 * Create a UST session onto the tracer of app and add it the session
558 * hashtable.
559 *
560 * Return ust app session or NULL on error.
561 */
562 static struct ust_app_session *create_ust_app_session(
563 struct ltt_ust_session *usess, struct ust_app *app)
564 {
565 int ret;
566 struct ust_app_session *ua_sess;
567
568 ua_sess = lookup_session_by_app(usess, app);
569 if (ua_sess == NULL) {
570 DBG2("UST app pid: %d session uid %d not found, creating it",
571 app->key.pid, usess->uid);
572 ua_sess = alloc_ust_app_session();
573 if (ua_sess == NULL) {
574 /* Only malloc can failed so something is really wrong */
575 goto error;
576 }
577 shadow_copy_session(ua_sess, usess);
578 }
579
580 if (ua_sess->handle == -1) {
581 ret = ustctl_create_session(app->key.sock);
582 if (ret < 0) {
583 ERR("Error creating session for app pid %d, sock %d",
584 app->key.pid, app->key.sock);
585 /* TODO: free() ua_sess */
586 goto error;
587 }
588
589 DBG2("UST app ustctl create session handle %d", ret);
590 ua_sess->handle = ret;
591
592 /* Add ust app session to app's HT */
593 hashtable_node_init(&ua_sess->node,
594 (void *)((unsigned long) ua_sess->uid), sizeof(void *));
595 hashtable_add_unique(app->sessions, &ua_sess->node);
596
597 DBG2("UST app session created successfully with handle %d", ret);
598 }
599
600 return ua_sess;
601
602 error:
603 return NULL;
604 }
605
606 static struct ust_app_channel *create_ust_app_channel(
607 struct ust_app_session *ua_sess, struct ltt_ust_channel *uchan,
608 struct ust_app *app)
609 {
610 int ret = 0;
611 struct cds_lfht_iter iter;
612 struct cds_lfht_node *ua_chan_node;
613 struct ust_app_channel *ua_chan;
614
615 /* Lookup channel in the ust app session */
616 ua_chan_node = hashtable_lookup(ua_sess->channels,
617 (void *)uchan->name, strlen(uchan->name), &iter);
618 if (ua_chan_node == NULL) {
619 DBG2("Unable to find channel %s in ust session uid %u",
620 uchan->name, ua_sess->uid);
621 ua_chan = alloc_ust_app_channel(uchan->name);
622 if (ua_chan == NULL) {
623 goto error;
624 }
625 shadow_copy_channel(ua_chan, uchan);
626 hashtable_add_unique(ua_sess->channels, &ua_chan->node);
627 } else {
628 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
629 }
630
631 /* TODO: remove cast and use lttng-ust-abi.h */
632 ret = ustctl_create_channel(app->key.sock, ua_sess->handle,
633 (struct lttng_ust_channel_attr *)&uchan->attr, &ua_chan->obj);
634 if (ret < 0) {
635 DBG("Error creating channel %s for app (pid: %d, sock: %d) "
636 "and session handle %d with ret %d",
637 ua_chan->name, app->key.pid, app->key.sock,
638 ua_sess->handle, ret);
639 goto error;
640 }
641
642 ua_chan->handle = ua_chan->obj->handle;
643 ua_chan->attr.shm_fd = ua_chan->obj->shm_fd;
644 ua_chan->attr.wait_fd = ua_chan->obj->wait_fd;
645 ua_chan->attr.memory_map_size = ua_chan->obj->memory_map_size;
646
647 DBG2("Channel %s UST create successfully for pid:%d and sock:%d",
648 ua_chan->name, app->key.pid, app->key.sock);
649
650 return ua_chan;
651
652 error:
653 return NULL;
654 }
655
656 static struct ust_app_event *create_ust_app_event(
657 struct ust_app_session *ua_sess, struct ust_app_channel *ua_chan,
658 struct ltt_ust_event *uevent, struct ust_app *app)
659 {
660 int ret;
661 struct cds_lfht_iter iter;
662 struct cds_lfht_node *ua_event_node;
663 struct ust_app_event *ua_event;
664
665 /* Get event node */
666 ua_event_node = hashtable_lookup(ua_chan->events,
667 (void *)uevent->attr.name, strlen(uevent->attr.name), &iter);
668 if (ua_event_node == NULL) {
669 DBG2("UST app event %s not found, creating it", uevent->attr.name);
670 /* Does not exist so create one */
671 ua_event = alloc_ust_app_event(uevent->attr.name);
672 if (ua_event == NULL) {
673 /* Only malloc can failed so something is really wrong */
674 goto error;
675 }
676 shadow_copy_event(ua_event, uevent);
677
678 hashtable_add_unique(ua_chan->events, &ua_event->node);
679 } else {
680 ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
681 }
682
683 /* Create UST event on tracer */
684 ret = ustctl_create_event(app->key.sock, &uevent->attr, ua_chan->obj,
685 &ua_event->obj);
686 if (ret < 0) {
687 ERR("Error ustctl create event %s for app pid: %d with ret %d",
688 uevent->attr.name, app->key.pid, ret);
689 /* TODO: free() ua_event */
690 goto error;
691 }
692 ua_event->handle = ua_event->obj->handle;
693 ua_event->enabled = 1;
694
695
696 DBG2("Event %s UST create successfully for pid:%d", uevent->attr.name,
697 app->key.pid);
698
699 return ua_event;
700
701 error:
702 return NULL;
703 }
704
705 static int create_ust_app_metadata(struct ust_app_session *ua_sess,
706 char *pathname, struct ust_app *app)
707 {
708 int ret = 0;
709 struct lttng_ust_channel_attr uattr;
710
711 if (ua_sess->metadata == NULL) {
712 /* Allocate UST metadata */
713 ua_sess->metadata = trace_ust_create_metadata(pathname);
714 if (ua_sess->metadata == NULL) {
715 ERR("UST app session %d creating metadata failed",
716 ua_sess->handle);
717 goto error;
718 }
719
720 uattr.overwrite = ua_sess->metadata->attr.overwrite;
721 uattr.subbuf_size = ua_sess->metadata->attr.subbuf_size;
722 uattr.num_subbuf = ua_sess->metadata->attr.num_subbuf;
723 uattr.switch_timer_interval =
724 ua_sess->metadata->attr.switch_timer_interval;
725 uattr.read_timer_interval =
726 ua_sess->metadata->attr.read_timer_interval;
727 uattr.output = ua_sess->metadata->attr.output;
728
729 /* UST tracer metadata creation */
730 ret = ustctl_open_metadata(app->key.sock, ua_sess->handle, &uattr,
731 &ua_sess->metadata->obj);
732 if (ret < 0) {
733 ERR("UST app open metadata failed for app pid:%d",
734 app->key.pid);
735 goto error;
736 }
737
738 DBG2("UST metadata opened for app pid %d", app->key.pid);
739 }
740
741 /* Open UST metadata stream */
742 if (ua_sess->metadata->stream_obj == NULL) {
743 ret = ustctl_create_stream(app->key.sock, ua_sess->metadata->obj,
744 &ua_sess->metadata->stream_obj);
745 if (ret < 0) {
746 ERR("UST create metadata stream failed");
747 goto error;
748 }
749
750 ret = snprintf(ua_sess->metadata->pathname, PATH_MAX, "%s/%s-%d",
751 pathname, app->name, app->key.pid);
752 if (ret < 0) {
753 PERROR("asprintf UST create stream");
754 goto error;
755 }
756
757 ret = mkdir(ua_sess->metadata->pathname, S_IRWXU | S_IRWXG);
758 if (ret < 0) {
759 PERROR("mkdir UST metadata");
760 goto error;
761 }
762
763 ret = snprintf(ua_sess->metadata->pathname, PATH_MAX, "%s/%s-%d/metadata",
764 pathname, app->name, app->key.pid);
765 if (ret < 0) {
766 PERROR("asprintf UST create stream");
767 goto error;
768 }
769
770 DBG2("UST metadata stream object created for app pid %d",
771 app->key.pid);
772 }
773
774 return 0;
775
776 error:
777 return -1;
778 }
779
780 /*
781 * Add channel to all ust app session.
782 */
783 int ust_app_add_channel_all(struct ltt_ust_session *usess,
784 struct ltt_ust_channel *uchan)
785 {
786 int ret = 0;
787 struct cds_lfht_iter iter;
788 struct cds_lfht_node *node;
789 struct ust_app *app;
790 struct ust_app_session *ua_sess;
791 struct ust_app_channel *ua_chan;
792
793 if (usess == NULL || uchan == NULL) {
794 ERR("Adding UST global channel to NULL values");
795 ret = -1;
796 goto error;
797 }
798
799 DBG2("UST app adding channel %s to global domain for session uid %d",
800 uchan->name, usess->uid);
801
802 rcu_read_lock();
803
804 /* For every UST applications registered */
805 hashtable_get_first(ust_app_ht, &iter);
806 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
807 app = caa_container_of(node, struct ust_app, node);
808
809 /* Create session on the tracer side and add it to app session HT */
810 ua_sess = create_ust_app_session(usess, app);
811 if (ret < 0) {
812 goto next;
813 }
814
815 /* Create channel onto application */
816 ua_chan = create_ust_app_channel(ua_sess, uchan, app);
817 if (ua_chan == NULL) {
818 goto next;
819 }
820
821 next:
822 /* Next applications */
823 hashtable_get_next(ust_app_ht, &iter);
824 }
825 rcu_read_unlock();
826
827 error:
828 return ret;
829 }
830
831 int ust_app_add_event_all(struct ltt_ust_session *usess,
832 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent)
833 {
834 int ret = 0;
835 struct cds_lfht_iter iter;
836 struct cds_lfht_node *node, *ua_chan_node;
837 struct ust_app *app;
838 struct ust_app_session *ua_sess;
839 struct ust_app_channel *ua_chan;
840 struct ust_app_event *ua_event;
841
842 DBG2("UST app adding event %s to global domain for session uid %d",
843 uevent->attr.name, usess->uid);
844
845 rcu_read_lock();
846
847 /* For all registered applications */
848 hashtable_get_first(ust_app_ht, &iter);
849 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
850 app = caa_container_of(node, struct ust_app, node);
851
852 /* Create session on the tracer side and add it to app session HT */
853 ua_sess = create_ust_app_session(usess, app);
854 if (ret < 0) {
855 goto next;
856 }
857
858 /* Lookup channel in the ust app session */
859 ua_chan_node = hashtable_lookup(ua_sess->channels,
860 (void *)uchan->name, strlen(uchan->name), &iter);
861 if (ua_chan_node == NULL) {
862 ERR("Channel %s not found in session uid %d. Skipping",
863 uchan->name, usess->uid);
864 goto next;
865 }
866 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
867
868 ua_event = create_ust_app_event(ua_sess, ua_chan, uevent, app);
869 if (ua_event == NULL) {
870 goto next;
871 }
872
873 next:
874 /* Next applications */
875 hashtable_get_next(ust_app_ht, &iter);
876 }
877 rcu_read_unlock();
878
879 return ret;
880 }
881
882 int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app)
883 {
884 int ret = 0;
885 struct cds_lfht_iter iter;
886 struct cds_lfht_node *node;
887 struct ust_app_session *ua_sess;
888 struct ust_app_channel *ua_chan;
889
890 DBG("Starting tracing for ust app pid %d", app->key.pid);
891
892 ua_sess = lookup_session_by_app(usess, app);
893 if (ua_sess == NULL) {
894 /* Only malloc can failed so something is really wrong */
895 goto error;
896 }
897
898 ret = create_ust_app_metadata(ua_sess, usess->pathname, app);
899 if (ret < 0) {
900 goto error;
901 }
902
903 /* For each channel */
904 hashtable_get_first(ua_sess->channels, &iter);
905 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
906 ua_chan = caa_container_of(node, struct ust_app_channel, node);
907
908 /* Create all streams */
909 while (1) {
910 struct ltt_ust_stream *ustream;
911
912 ustream = zmalloc(sizeof(*ustream));
913 if (ustream == NULL) {
914 PERROR("zmalloc ust stream");
915 continue;
916 }
917
918 ret = ustctl_create_stream(app->key.sock, ua_chan->obj,
919 &ustream->obj);
920 if (ret < 0) {
921 /* Got all streams */
922 break;
923 }
924 ustream->handle = ustream->obj->handle;
925
926 /* Order is important */
927 cds_list_add_tail(&ustream->list, &ua_chan->streams.head);
928 ret = snprintf(ustream->pathname, PATH_MAX, "%s/%s-%d/%s_%u",
929 usess->pathname, app->name, app->key.pid,
930 ua_chan->name, ua_chan->streams.count++);
931 if (ret < 0) {
932 PERROR("asprintf UST create stream");
933 continue;
934 }
935 DBG2("UST stream %d ready at %s", ua_chan->streams.count,
936 ustream->pathname);
937 }
938
939 /* Next applications */
940 hashtable_get_next(ua_sess->channels, &iter);
941 }
942
943 /* Setup UST consumer socket and send fds to it */
944 ret = ust_consumer_send_session(usess->consumer_fd, ua_sess);
945 if (ret < 0) {
946 goto error;
947 }
948
949 /* This start the UST tracing */
950 ret = ustctl_start_session(app->key.sock, ua_sess->handle);
951 if (ret < 0) {
952 ERR("Error starting tracing for app pid: %d", app->key.pid);
953 goto error;
954 }
955
956 /* Quiescent wait after starting trace */
957 ustctl_wait_quiescent(app->key.sock);
958
959 return 0;
960
961 error:
962 return -1;
963 }
964
965 int ust_app_start_trace_all(struct ltt_ust_session *usess)
966 {
967 int ret = 0;
968 struct cds_lfht_iter iter;
969 struct cds_lfht_node *node;
970 struct ust_app *app;
971
972 DBG("Starting all UST traces");
973
974 rcu_read_lock();
975 hashtable_get_first(ust_app_ht, &iter);
976 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
977 app = caa_container_of(node, struct ust_app, node);
978
979 ret = ust_app_start_trace(usess, app);
980 if (ret < 0) {
981 goto next;
982 }
983
984 next:
985 /* Next applications */
986 hashtable_get_next(ust_app_ht, &iter);
987 }
988 rcu_read_unlock();
989
990 return 0;
991 }
992
993 void ust_app_global_update(struct ltt_ust_session *usess, int sock)
994 {
995 int ret = 0;
996 struct cds_lfht_iter iter;
997 struct cds_lfht_node *node;
998 struct ust_app *app;
999 struct ust_app_session *ua_sess;
1000 struct ust_app_channel *ua_chan;
1001 struct ust_app_event *ua_event;
1002 struct ltt_ust_channel *uchan;
1003 struct ltt_ust_event *uevent;
1004
1005 rcu_read_lock();
1006
1007 if (usess == NULL) {
1008 DBG2("No UST session on global update. Returning");
1009 goto error;
1010 }
1011
1012 DBG2("UST app global update for app sock %d for session uid %d", sock,
1013 usess->uid);
1014
1015 app = find_app_by_sock(sock);
1016 if (app == NULL) {
1017 ERR("Failed to update app sock %d", sock);
1018 goto error;
1019 }
1020
1021 ua_sess = create_ust_app_session(usess, app);
1022 if (ua_sess == NULL) {
1023 goto error;
1024 }
1025
1026 hashtable_get_first(usess->domain_global.channels, &iter);
1027 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
1028 uchan = caa_container_of(node, struct ltt_ust_channel, node);
1029
1030 ua_chan = create_ust_app_channel(ua_sess, uchan, app);
1031 if (ua_chan == NULL) {
1032 goto next_chan;
1033 }
1034
1035 hashtable_get_first(uchan->events, &iter);
1036 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
1037 uevent = caa_container_of(node, struct ltt_ust_event, node);
1038
1039 ua_event = create_ust_app_event(ua_sess, ua_chan, uevent, app);
1040 if (ua_event == NULL) {
1041 goto next_event;
1042 }
1043
1044 next_event:
1045 hashtable_get_next(uchan->events, &iter);
1046 }
1047
1048 next_chan:
1049 /* Next item in hash table */
1050 hashtable_get_next(usess->domain_global.channels, &iter);
1051 }
1052
1053 if (usess->start_trace) {
1054 ret = ust_app_start_trace(usess, app);
1055 if (ret < 0) {
1056 goto error;
1057 }
1058
1059 DBG2("UST trace started for app pid %d", app->key.pid);
1060 }
1061
1062 error:
1063 rcu_read_unlock();
1064 return;
1065 }
This page took 0.050976 seconds and 5 git commands to generate.