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