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