2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
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
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.
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.
26 #include <sys/types.h>
30 #include <lttng-share.h>
32 #include "hashtable.h"
34 #include "../hashtable/hash.h"
36 #include "ust-consumer.h"
39 * Delete a traceable application structure from the global list.
41 static void delete_ust_app(struct ust_app
*lta
)
44 struct cds_lfht_node
*node
;
45 struct cds_lfht_iter iter
;
52 /* Remove from apps hash table */
53 node
= hashtable_lookup(ust_app_ht
,
54 (void *) ((unsigned long) lta
->key
.pid
), sizeof(void *), &iter
);
56 ERR("UST app pid %d not found in hash table", lta
->key
.pid
);
58 ret
= hashtable_del(ust_app_ht
, &iter
);
60 ERR("UST app unable to delete app %d from hash table",
63 DBG2("UST app pid %d deleted", lta
->key
.pid
);
67 /* Remove from key hash table */
68 node
= hashtable_lookup(ust_app_sock_key_map
,
69 (void *) ((unsigned long) lta
->key
.sock
), sizeof(void *), &iter
);
71 ERR("UST app key %d not found in key hash table", lta
->key
.sock
);
73 ret
= hashtable_del(ust_app_sock_key_map
, &iter
);
75 ERR("UST app unable to delete app sock %d from key hash table",
78 DBG2("UST app pair sock %d key %d deleted",
79 lta
->key
.sock
, lta
->key
.pid
);
89 * URCU intermediate call to delete an UST app.
91 static void delete_ust_app_rcu(struct rcu_head
*head
)
93 struct cds_lfht_node
*node
=
94 caa_container_of(head
, struct cds_lfht_node
, head
);
96 caa_container_of(node
, struct ust_app
, node
);
102 * Find an ust_app using the sock and return it.
104 static struct ust_app
*find_app_by_sock(int sock
)
106 struct cds_lfht_node
*node
;
107 struct ust_app_key
*key
;
108 struct cds_lfht_iter iter
;
112 node
= hashtable_lookup(ust_app_sock_key_map
,
113 (void *)((unsigned long) sock
), sizeof(void *), &iter
);
115 DBG2("UST app find by sock %d key not found", sock
);
120 key
= caa_container_of(node
, struct ust_app_key
, node
);
122 node
= hashtable_lookup(ust_app_ht
,
123 (void *)((unsigned long) key
->pid
), sizeof(void *), &iter
);
125 DBG2("UST app find by sock %d not found", sock
);
131 return caa_container_of(node
, struct ust_app
, node
);
138 * Return pointer to traceable apps list.
140 struct cds_lfht
*ust_app_get_ht(void)
146 * Return ust app pointer or NULL if not found.
148 struct ust_app
*ust_app_find_by_pid(pid_t pid
)
150 struct cds_lfht_node
*node
;
151 struct cds_lfht_iter iter
;
154 node
= hashtable_lookup(ust_app_ht
,
155 (void *)((unsigned long) pid
), sizeof(void *), &iter
);
158 DBG2("UST app no found with pid %d", pid
);
163 DBG2("Found UST app by pid %d", pid
);
165 return caa_container_of(node
, struct ust_app
, node
);
172 * Using pid and uid (of the app), allocate a new ust_app struct and
173 * add it to the global traceable app list.
175 * On success, return 0, else return malloc ENOMEM.
177 int ust_app_register(struct ust_register_msg
*msg
, int sock
)
181 lta
= malloc(sizeof(struct ust_app
));
189 lta
->key
.pid
= msg
->pid
;
190 lta
->ppid
= msg
->ppid
;
191 lta
->v_major
= msg
->major
;
192 lta
->v_minor
= msg
->minor
;
193 lta
->key
.sock
= sock
;
194 strncpy(lta
->name
, msg
->name
, sizeof(lta
->name
));
195 lta
->name
[16] = '\0';
196 hashtable_node_init(<a
->node
, (void *)((unsigned long)lta
->key
.pid
),
199 /* Session hashtable */
200 lta
->sessions
= hashtable_new(0);
202 /* Set sock key map */
203 hashtable_node_init(<a
->key
.node
, (void *)((unsigned long)lta
->key
.sock
),
207 hashtable_add_unique(ust_app_ht
, <a
->node
);
208 hashtable_add_unique(ust_app_sock_key_map
, <a
->key
.node
);
211 DBG("App registered with pid:%d ppid:%d uid:%d gid:%d sock:%d name:%s"
212 " (version %d.%d)", lta
->key
.pid
, lta
->ppid
, lta
->uid
, lta
->gid
,
213 lta
->key
.sock
, lta
->name
, lta
->v_major
, lta
->v_minor
);
219 * Unregister app by removing it from the global traceable app list and freeing
222 * The socket is already closed at this point so no close to sock.
224 void ust_app_unregister(int sock
)
228 DBG2("UST app unregistering sock %d", sock
);
230 lta
= find_app_by_sock(sock
);
232 DBG("PID %d unregistering with sock %d", lta
->key
.pid
, sock
);
233 /* FIXME: Better use a call_rcu here ? */
239 * Return traceable_app_count
241 unsigned long ust_app_list_count(void)
246 count
= hashtable_get_count(ust_app_ht
);
253 * Free and clean all traceable apps of the global list.
255 void ust_app_clean_list(void)
258 struct cds_lfht_node
*node
;
259 struct cds_lfht_iter iter
;
261 DBG2("UST app clean hash table");
265 hashtable_get_first(ust_app_ht
, &iter
);
266 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
267 ret
= hashtable_del(ust_app_ht
, &iter
);
269 call_rcu(&node
->head
, delete_ust_app_rcu
);
271 hashtable_get_next(ust_app_ht
, &iter
);
278 * Init UST app hash table.
280 void ust_app_ht_alloc(void)
282 ust_app_ht
= hashtable_new(0);
283 ust_app_sock_key_map
= hashtable_new(0);
287 * Alloc new UST app session.
289 static struct ust_app_session
*alloc_app_session(void)
291 struct ust_app_session
*ua_sess
;
293 ua_sess
= zmalloc(sizeof(struct ust_app_session
));
294 if (ua_sess
== NULL
) {
299 ua_sess
->enabled
= 0;
300 ua_sess
->handle
= -1;
301 ua_sess
->channels
= hashtable_new_str(0);
302 ua_sess
->metadata
= NULL
;
311 static struct ust_app_channel
*alloc_app_channel(char *name
)
313 struct ust_app_channel
*ua_chan
;
315 ua_chan
= zmalloc(sizeof(struct ust_app_channel
));
316 if (ua_chan
== NULL
) {
321 strncpy(ua_chan
->name
, name
, sizeof(ua_chan
->name
));
322 ua_chan
->name
[sizeof(ua_chan
->name
) - 1] = '\0';
323 ua_chan
->enabled
= 0;
324 ua_chan
->handle
= -1;
326 ua_chan
->ctx
= hashtable_new(0);
327 CDS_INIT_LIST_HEAD(&ua_chan
->streams
.head
);
328 ua_chan
->events
= hashtable_new_str(0);
329 hashtable_node_init(&ua_chan
->node
, (void *) ua_chan
->name
,
330 strlen(ua_chan
->name
));
332 DBG3("UST app channel %s allocated", ua_chan
->name
);
340 static struct ust_app_event
*alloc_app_event(char *name
)
342 struct ust_app_event
*ua_event
;
344 ua_event
= zmalloc(sizeof(struct ust_app_event
));
345 if (ua_event
== NULL
) {
350 strncpy(ua_event
->name
, name
, sizeof(ua_event
->name
));
351 ua_event
->name
[sizeof(ua_event
->name
) - 1] = '\0';
352 ua_event
->ctx
= hashtable_new(0);
353 hashtable_node_init(&ua_event
->node
, (void *) ua_event
->name
,
354 strlen(ua_event
->name
));
356 DBG3("UST app event %s allocated", ua_event
->name
);
364 static void shallow_copy_event(struct ust_app_event
*ua_event
,
365 struct ltt_ust_event
*uevent
)
367 strncpy(ua_event
->name
, uevent
->attr
.name
, sizeof(ua_event
->name
));
368 ua_event
->name
[sizeof(ua_event
->name
) - 1] = '\0';
370 /* TODO: support copy context */
373 static void shallow_copy_channel(struct ust_app_channel
*ua_chan
,
374 struct ltt_ust_channel
*uchan
)
376 struct cds_lfht_iter iter
;
377 struct cds_lfht_node
*node
, *ua_event_node
;
378 struct ltt_ust_event
*uevent
;
379 struct ust_app_event
*ua_event
;
381 DBG2("Shallow copy of UST app channel %s", ua_chan
->name
);
383 strncpy(ua_chan
->name
, uchan
->name
, sizeof(ua_chan
->name
));
384 ua_chan
->name
[sizeof(ua_chan
->name
) - 1] = '\0';
386 /* TODO: support copy context */
388 hashtable_get_first(uchan
->events
, &iter
);
389 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
390 uevent
= caa_container_of(node
, struct ltt_ust_event
, node
);
392 ua_event_node
= hashtable_lookup(ua_chan
->events
,
393 (void *) uevent
->attr
.name
, strlen(uevent
->attr
.name
), &iter
);
394 if (ua_event_node
== NULL
) {
395 DBG2("UST event %s not found on shallow copy channel",
397 ua_event
= alloc_app_event(uevent
->attr
.name
);
398 if (ua_event
== NULL
) {
401 hashtable_add_unique(ua_chan
->events
, &ua_event
->node
);
403 ua_event
= caa_container_of(node
, struct ust_app_event
, node
);
406 shallow_copy_event(ua_event
, uevent
);
408 /* Get next UST events */
409 hashtable_get_next(uchan
->events
, &iter
);
412 DBG3("Shallow copy channel done");
415 static void shallow_copy_session(struct ust_app_session
*ua_sess
,
416 struct ltt_ust_session
*usess
)
418 struct cds_lfht_node
*node
, *ua_chan_node
;
419 struct cds_lfht_iter iter
;
420 struct ltt_ust_channel
*uchan
;
421 struct ust_app_channel
*ua_chan
;
423 DBG2("Shallow copy of session handle");
425 ua_sess
->uid
= usess
->uid
;
427 /* TODO: support all UST domain */
429 /* Iterate over all channels in global domain. */
430 hashtable_get_first(usess
->domain_global
.channels
, &iter
);
431 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
432 uchan
= caa_container_of(node
, struct ltt_ust_channel
, node
);
434 ua_chan_node
= hashtable_lookup(ua_sess
->channels
,
435 (void *) uchan
->name
, strlen(uchan
->name
), &iter
);
436 if (ua_chan_node
== NULL
) {
437 DBG2("Channel %s not found on shallow session copy, creating it",
439 ua_chan
= alloc_app_channel(uchan
->name
);
440 if (ua_chan
== NULL
) {
441 /* malloc failed... continuing */
444 hashtable_add_unique(ua_sess
->channels
, &ua_chan
->node
);
446 ua_chan
= caa_container_of(node
, struct ust_app_channel
, node
);
449 shallow_copy_channel(ua_chan
, uchan
);
451 /* Next item in hash table */
452 hashtable_get_next(usess
->domain_global
.channels
, &iter
);
456 static struct ust_app_session
*lookup_session_by_app(
457 struct ltt_ust_session
*usess
, struct ust_app
*app
)
459 struct cds_lfht_iter iter
;
460 struct cds_lfht_node
*node
;
462 /* Get right UST app session from app */
463 node
= hashtable_lookup(app
->sessions
,
464 (void *) ((unsigned long) usess
->uid
),
465 sizeof(void *), &iter
);
470 return caa_container_of(node
, struct ust_app_session
, node
);
476 int ust_app_add_channel(struct ltt_ust_session
*usess
,
477 struct ltt_ust_channel
*uchan
)
480 struct cds_lfht_iter iter
;
481 struct cds_lfht_node
*node
, *ua_chan_node
;
483 struct ust_app_session
*ua_sess
;
484 struct ust_app_channel
*ua_chan
;
486 DBG2("UST app adding channel %s to global domain for session uid %d",
487 uchan
->name
, usess
->uid
);
490 hashtable_get_first(ust_app_ht
, &iter
);
491 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
492 app
= caa_container_of(node
, struct ust_app
, node
);
494 ua_sess
= lookup_session_by_app(usess
, app
);
495 if (ua_sess
== NULL
) {
496 DBG2("UST app pid: %d session uid %d not found, creating one",
497 app
->key
.pid
, usess
->uid
);
498 ua_sess
= alloc_app_session();
499 if (ua_sess
== NULL
) {
500 /* Only malloc can failed so something is really wrong */
503 shallow_copy_session(ua_sess
, usess
);
506 if (ua_sess
->handle
== -1) {
507 ret
= ustctl_create_session(app
->key
.sock
);
509 DBG("Error creating session for app pid %d, sock %d",
510 app
->key
.pid
, app
->key
.sock
);
511 /* TODO: free() ua_sess */
515 DBG2("UST app ustctl create session handle %d", ret
);
516 ua_sess
->handle
= ret
;
518 /* Add ust app session to app's HT */
519 hashtable_node_init(&ua_sess
->node
,
520 (void *)((unsigned long) ua_sess
->uid
), sizeof(void *));
521 hashtable_add_unique(app
->sessions
, &ua_sess
->node
);
524 /* Lookup channel in the ust app session */
525 ua_chan_node
= hashtable_lookup(ua_sess
->channels
,
526 (void *) uchan
->name
, strlen(uchan
->name
), &iter
);
527 if (ua_chan_node
== NULL
) {
528 ERR("Channel suppose to be present with the above shallow "
529 "session copy. Continuing...");
533 ua_chan
= caa_container_of(ua_chan_node
, struct ust_app_channel
, node
);
535 /* TODO: remove cast and use lttng-ust-abi.h */
536 ret
= ustctl_create_channel(app
->key
.sock
, ua_sess
->handle
,
537 (struct lttng_ust_channel_attr
*)&uchan
->attr
, &ua_chan
->obj
);
539 DBG("Error creating channel %s for app (pid: %d, sock: %d) "
540 "and session handle %d with ret %d",
541 uchan
->name
, app
->key
.pid
, app
->key
.sock
,
542 ua_sess
->handle
, ret
);
546 ua_chan
->handle
= ua_chan
->obj
->handle
;
547 ua_chan
->attr
.shm_fd
= ua_chan
->obj
->shm_fd
;
548 ua_chan
->attr
.wait_fd
= ua_chan
->obj
->wait_fd
;
549 ua_chan
->attr
.memory_map_size
= ua_chan
->obj
->memory_map_size
;
551 DBG2("Channel %s UST create successfully for pid:%d and sock:%d",
552 uchan
->name
, app
->key
.pid
, app
->key
.sock
);
555 /* Next applications */
556 hashtable_get_next(ust_app_ht
, &iter
);
563 int ust_app_add_event(struct ltt_ust_session
*usess
,
564 struct ltt_ust_channel
*uchan
, struct ltt_ust_event
*uevent
)
567 struct cds_lfht_iter iter
;
568 struct cds_lfht_node
*node
, *ua_chan_node
, *ua_event_node
;
570 struct ust_app_session
*ua_sess
;
571 struct ust_app_channel
*ua_chan
;
572 struct ust_app_event
*ua_event
;
573 struct lttng_ust_event ltt_uevent
;
574 struct lttng_ust_object_data
*obj_event
;
576 DBG2("UST app adding event %s to global domain for session uid %d",
577 uevent
->attr
.name
, usess
->uid
);
580 hashtable_get_first(ust_app_ht
, &iter
);
581 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
582 app
= caa_container_of(node
, struct ust_app
, node
);
584 ua_sess
= lookup_session_by_app(usess
, app
);
585 if (ua_sess
== NULL
) {
586 DBG2("UST app (pid: %d, sock: %d) session not found, creating one",
587 app
->key
.pid
, app
->key
.sock
);
588 ua_sess
= alloc_app_session();
589 if (ua_sess
== NULL
) {
590 /* Only malloc can failed so something is really wrong */
593 shallow_copy_session(ua_sess
, usess
);
596 if (ua_sess
->handle
== -1) {
597 ret
= ustctl_create_session(app
->key
.sock
);
599 DBG("Error creating session for app pid %d, sock %d",
600 app
->key
.pid
, app
->key
.sock
);
601 /* TODO: free() ua_sess */
605 DBG2("UST app ustctl create session handle %d", ret
);
606 ua_sess
->handle
= ret
;
607 /* Add ust app session to app's HT */
608 hashtable_node_init(&ua_sess
->node
,
609 (void *)((unsigned long) ua_sess
->uid
), sizeof(void *));
610 hashtable_add_unique(app
->sessions
, &ua_sess
->node
);
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 ERR("Channel suppose to be present with the above shallow "
618 "session copy. Continuing...");
622 ua_chan
= caa_container_of(ua_chan_node
, struct ust_app_channel
, node
);
624 /* Prepare lttng ust event */
625 strncpy(ltt_uevent
.name
, uevent
->attr
.name
, sizeof(ltt_uevent
.name
));
626 ltt_uevent
.name
[sizeof(ltt_uevent
.name
) - 1] = '\0';
627 /* TODO: adjust to other instrumentation types */
628 ltt_uevent
.instrumentation
= LTTNG_UST_TRACEPOINT
;
631 ua_event_node
= hashtable_lookup(ua_chan
->events
,
632 (void *) uevent
->attr
.name
, strlen(uevent
->attr
.name
), &iter
);
633 if (ua_event_node
== NULL
) {
634 DBG2("UST app event %s not found, creating one", uevent
->attr
.name
);
635 /* Does not exist so create one */
636 ua_event
= alloc_app_event(uevent
->attr
.name
);
637 if (ua_event
== NULL
) {
638 /* Only malloc can failed so something is really wrong */
642 shallow_copy_event(ua_event
, uevent
);
644 /* Create UST event on tracer */
645 ret
= ustctl_create_event(app
->key
.sock
, <t_uevent
, ua_chan
->obj
,
648 ERR("Error ustctl create event %s for app pid: %d with ret %d",
649 uevent
->attr
.name
, app
->key
.pid
, ret
);
650 /* TODO: free() ua_event and obj_event */
653 ua_event
->obj
= obj_event
;
654 ua_event
->handle
= obj_event
->handle
;
655 ua_event
->enabled
= 1;
657 ua_event
= caa_container_of(ua_event_node
,
658 struct ust_app_event
, node
);
660 if (ua_event
->enabled
== 0) {
661 ret
= ustctl_enable(app
->key
.sock
, ua_event
->obj
);
663 ERR("Error ustctl enable event %s for app "
664 "pid: %d with ret %d", uevent
->attr
.name
,
668 ua_event
->enabled
= 1;
672 hashtable_add_unique(ua_chan
->events
, &ua_event
->node
);
674 DBG2("Event %s UST create successfully for pid:%d", uevent
->attr
.name
,
678 /* Next applications */
679 hashtable_get_next(ust_app_ht
, &iter
);
686 int ust_app_start_trace(struct ltt_ust_session
*usess
)
689 struct cds_lfht_iter iter
;
690 struct cds_lfht_node
*node
, *ua_chan_node
;
692 struct ust_app_session
*ua_sess
;
693 struct ust_app_channel
*ua_chan
;
694 struct lttng_ust_channel_attr uattr
;
695 struct ltt_ust_channel
*uchan
;
697 DBG("Starting all UST traces");
700 hashtable_get_first(ust_app_ht
, &iter
);
701 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
702 app
= caa_container_of(node
, struct ust_app
, node
);
704 ua_sess
= lookup_session_by_app(usess
, app
);
705 if (ua_sess
== NULL
) {
706 /* Only malloc can failed so something is really wrong */
710 if (ua_sess
->metadata
== NULL
) {
711 /* Allocate UST metadata */
712 ua_sess
->metadata
= trace_ust_create_metadata(usess
->pathname
);
713 if (ua_sess
->metadata
== NULL
) {
714 ERR("UST app session %d creating metadata failed",
719 uattr
.overwrite
= ua_sess
->metadata
->attr
.overwrite
;
720 uattr
.subbuf_size
= ua_sess
->metadata
->attr
.subbuf_size
;
721 uattr
.num_subbuf
= ua_sess
->metadata
->attr
.num_subbuf
;
722 uattr
.switch_timer_interval
=
723 ua_sess
->metadata
->attr
.switch_timer_interval
;
724 uattr
.read_timer_interval
=
725 ua_sess
->metadata
->attr
.read_timer_interval
;
726 uattr
.output
= ua_sess
->metadata
->attr
.output
;
728 /* UST tracer metadata creation */
729 ret
= ustctl_open_metadata(app
->key
.sock
, ua_sess
->handle
, &uattr
,
730 &ua_sess
->metadata
->obj
);
732 ERR("UST app open metadata failed for app pid:%d",
737 DBG2("UST metadata opened for app pid %d", app
->key
.pid
);
740 /* Open UST metadata stream */
741 if (ua_sess
->metadata
->stream_obj
== NULL
) {
742 ret
= ustctl_create_stream(app
->key
.sock
, ua_sess
->metadata
->obj
,
743 &ua_sess
->metadata
->stream_obj
);
745 ERR("UST create metadata stream failed");
749 ret
= snprintf(ua_sess
->metadata
->pathname
, PATH_MAX
, "%s/%s-%d",
750 usess
->pathname
, app
->name
, app
->key
.pid
);
752 PERROR("asprintf UST create stream");
756 ret
= mkdir(ua_sess
->metadata
->pathname
, S_IRWXU
| S_IRWXG
);
761 ret
= snprintf(ua_sess
->metadata
->pathname
, PATH_MAX
, "%s/%s-%d/metadata",
762 usess
->pathname
, app
->name
, app
->key
.pid
);
764 PERROR("asprintf UST create stream");
768 DBG2("UST metadata stream object created for app pid %d",
772 /* For each channel */
773 hashtable_get_first(usess
->domain_global
.channels
, &iter
);
774 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
775 uchan
= caa_container_of(node
, struct ltt_ust_channel
, node
);
777 /* Lookup channel in the ust app session */
778 ua_chan_node
= hashtable_lookup(ua_sess
->channels
,
779 (void *) uchan
->name
, strlen(uchan
->name
), &iter
);
780 if (ua_chan_node
== NULL
) {
781 ERR("Channel suppose to be present with the above shallow "
782 "session copy. Continuing...");
786 ua_chan
= caa_container_of(ua_chan_node
,
787 struct ust_app_channel
, node
);
790 struct lttng_ust_object_data
*obj
;
791 struct ltt_ust_stream
*ustream
;
793 ret
= ustctl_create_stream(app
->key
.sock
, ua_chan
->obj
,
796 /* Got all streams */
800 ustream
= malloc(sizeof(*ustream
));
801 if (ustream
== NULL
) {
804 memset(ustream
, 0, sizeof(struct ltt_ust_stream
));
806 ustream
->handle
= ustream
->obj
->handle
;
807 /* Order is important */
808 cds_list_add_tail(&ustream
->list
, &ua_chan
->streams
.head
);
809 ret
= snprintf(ustream
->pathname
, PATH_MAX
, "%s/%s-%d/%s_%u",
810 usess
->pathname
, app
->name
, app
->key
.pid
,
811 uchan
->name
, ua_chan
->streams
.count
++);
813 PERROR("asprintf UST create stream");
819 /* Next applications */
820 hashtable_get_next(ua_sess
->channels
, &iter
);
823 /* Setup UST consumer socket and send fds to it */
824 ret
= ust_consumer_send_session(usess
->consumer_fd
, ua_sess
);
829 /* This start the UST tracing */
830 ret
= ustctl_start_session(app
->key
.sock
, ua_sess
->handle
);
832 ERR("Error starting tracing for app pid: %d", app
->key
.pid
);
836 /* Quiescent wait after starting trace */
837 ustctl_wait_quiescent(app
->key
.sock
);
839 /* Next applications */
840 hashtable_get_next(ust_app_ht
, &iter
);
847 void ust_app_global_update(struct ltt_ust_session
*usess
, int sock
)
850 int session_existed
= 1;
851 struct cds_lfht_iter iter
;
852 struct cds_lfht_node
*node
, *ua_chan_node
;
854 struct ust_app_session
*ua_sess
;
855 struct ust_app_channel
*ua_chan
;
856 struct ust_app_event
*ua_event
;
857 struct lttng_ust_event ltt_uevent
;
858 struct ltt_ust_channel
*uchan
;
859 struct lttng_ust_object_data
*obj_event
;
860 struct lttng_ust_channel_attr uattr
;
862 DBG2("UST app global update for app sock %d for session uid %d", sock
,
866 app
= find_app_by_sock(sock
);
868 ERR("Failed to update app sock %d", sock
);
872 ua_sess
= lookup_session_by_app(usess
, app
);
873 if (ua_sess
== NULL
) {
874 DBG2("UST app pid: %d session uid %d not found, creating one",
875 app
->key
.pid
, usess
->uid
);
876 ua_sess
= alloc_app_session();
877 if (ua_sess
== NULL
) {
878 /* Only malloc can failed so something is really wrong */
881 shallow_copy_session(ua_sess
, usess
);
885 if (ua_sess
->handle
== -1) {
886 ret
= ustctl_create_session(app
->key
.sock
);
888 DBG("Error creating session for app pid %d, sock %d",
889 app
->key
.pid
, app
->key
.sock
);
890 /* TODO: free() ua_sess */
894 DBG2("UST app ustctl create session handle %d", ret
);
895 ua_sess
->handle
= ret
;
897 /* Add ust app session to app's HT */
898 hashtable_node_init(&ua_sess
->node
,
899 (void *)((unsigned long) ua_sess
->uid
), sizeof(void *));
900 hashtable_add_unique(app
->sessions
, &ua_sess
->node
);
903 if (session_existed
) {
907 if (ua_sess
->metadata
== NULL
) {
908 /* Allocate UST metadata */
909 ua_sess
->metadata
= trace_ust_create_metadata(usess
->pathname
);
910 if (ua_sess
->metadata
== NULL
) {
911 ERR("UST app session %d creating metadata failed",
916 uattr
.overwrite
= ua_sess
->metadata
->attr
.overwrite
;
917 uattr
.subbuf_size
= ua_sess
->metadata
->attr
.subbuf_size
;
918 uattr
.num_subbuf
= ua_sess
->metadata
->attr
.num_subbuf
;
919 uattr
.switch_timer_interval
=
920 ua_sess
->metadata
->attr
.switch_timer_interval
;
921 uattr
.read_timer_interval
=
922 ua_sess
->metadata
->attr
.read_timer_interval
;
923 uattr
.output
= ua_sess
->metadata
->attr
.output
;
925 /* UST tracer metadata creation */
926 ret
= ustctl_open_metadata(app
->key
.sock
, ua_sess
->handle
, &uattr
,
927 &ua_sess
->metadata
->obj
);
929 ERR("UST app open metadata failed for app pid:%d",
934 DBG2("UST metadata opened for app pid %d", app
->key
.pid
);
937 /* Open UST metadata stream */
938 if (ua_sess
->metadata
->stream_obj
== NULL
) {
939 ret
= ustctl_create_stream(app
->key
.sock
, ua_sess
->metadata
->obj
,
940 &ua_sess
->metadata
->stream_obj
);
942 ERR("UST create metadata stream failed");
946 ret
= snprintf(ua_sess
->metadata
->pathname
, PATH_MAX
, "%s/%s-%d",
947 usess
->pathname
, app
->name
, app
->key
.pid
);
949 PERROR("asprintf UST create stream");
953 ret
= mkdir(ua_sess
->metadata
->pathname
, S_IRWXU
| S_IRWXG
);
955 PERROR("mkdir UST metadata");
959 ret
= snprintf(ua_sess
->metadata
->pathname
, PATH_MAX
, "%s/%s-%d/metadata",
960 usess
->pathname
, app
->name
, app
->key
.pid
);
962 PERROR("asprintf UST create stream");
966 DBG2("UST metadata stream object created for app pid %d",
971 /* Iterate over all channels */
972 hashtable_get_first(usess
->domain_global
.channels
, &iter
);
973 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
974 uchan
= caa_container_of(node
, struct ltt_ust_channel
, node
);
976 /* Lookup channel in the ust app session */
977 ua_chan_node
= hashtable_lookup(ua_sess
->channels
,
978 (void *) uchan
->name
, strlen(uchan
->name
), &iter
);
979 if (ua_chan_node
== NULL
) {
980 ERR("UST app channel not found for uchan %s", uchan
->name
);
984 ua_chan
= caa_container_of(ua_chan_node
, struct ust_app_channel
, node
);
986 /* TODO: remove cast and use lttng-ust-abi.h */
987 ret
= ustctl_create_channel(app
->key
.sock
, ua_sess
->handle
,
988 (struct lttng_ust_channel_attr
*)&uchan
->attr
, &ua_chan
->obj
);
990 DBG("Error creating channel %s for app (pid: %d, sock: %d) "
991 "and session handle %d with ret %d",
992 uchan
->name
, app
->key
.pid
, app
->key
.sock
,
993 ua_sess
->handle
, ret
);
997 ua_chan
->handle
= ua_chan
->obj
->handle
;
998 ua_chan
->attr
.shm_fd
= ua_chan
->obj
->shm_fd
;
999 ua_chan
->attr
.wait_fd
= ua_chan
->obj
->wait_fd
;
1000 ua_chan
->attr
.memory_map_size
= ua_chan
->obj
->memory_map_size
;
1002 DBG2("Channel %s UST create successfully for pid:%d and sock:%d",
1003 uchan
->name
, app
->key
.pid
, app
->key
.sock
);
1005 /* For each event(s) of that channel */
1006 hashtable_get_first(ua_chan
->events
, &iter
);
1007 while ((node
= hashtable_iter_get_node(&iter
)) != NULL
) {
1008 ua_event
= caa_container_of(node
, struct ust_app_event
, node
);
1010 /* Prepare lttng ust event */
1011 memset(<t_uevent
, 0, sizeof(ltt_uevent
));
1012 strncpy(ltt_uevent
.name
, ua_event
->name
, sizeof(ltt_uevent
.name
));
1013 ltt_uevent
.name
[sizeof(ltt_uevent
.name
) - 1] = '\0';
1015 /* TODO: adjust to other instrumentation types */
1016 ltt_uevent
.instrumentation
= LTTNG_UST_TRACEPOINT
;
1018 /* Create UST event on tracer */
1019 ret
= ustctl_create_event(app
->key
.sock
, <t_uevent
, ua_chan
->obj
,
1022 ERR("Error ustctl create event %s for app pid: %d with ret %d",
1023 ua_event
->name
, app
->key
.pid
, ret
);
1024 /* TODO: free() ua_event and obj_event */
1028 ua_event
->obj
= obj_event
;
1029 ua_event
->handle
= obj_event
->handle
;
1030 ua_event
->enabled
= 1;
1032 DBG2("Event %s UST create successfully for pid:%d",
1033 ua_event
->name
, app
->key
.pid
);
1036 hashtable_get_next(ua_chan
->events
, &iter
);
1040 struct lttng_ust_object_data
*obj
;
1041 struct ltt_ust_stream
*ustream
;
1043 ret
= ustctl_create_stream(app
->key
.sock
, ua_chan
->obj
, &obj
);
1045 /* Got all streams */
1049 ustream
= zmalloc(sizeof(*ustream
));
1050 if (ustream
== NULL
) {
1051 PERROR("zmalloc ust stream");
1056 ustream
->handle
= ustream
->obj
->handle
;
1057 /* Order is important */
1058 cds_list_add_tail(&ustream
->list
, &ua_chan
->streams
.head
);
1060 ret
= snprintf(ustream
->pathname
, PATH_MAX
, "%s/%s-%d/%s_%u",
1061 usess
->pathname
, app
->name
, app
->key
.pid
,
1062 uchan
->name
, ua_chan
->streams
.count
++);
1064 PERROR("asprintf UST create stream");
1070 /* Next applications */
1071 hashtable_get_next(ua_sess
->channels
, &iter
);
1074 if (usess
->start_trace
) {
1075 /* Setup UST consumer socket and send fds to it */
1076 ret
= ust_consumer_send_session(usess
->consumer_fd
, ua_sess
);
1078 ERR("UST consumer send session failed");
1082 /* This start the UST tracing */
1083 ret
= ustctl_start_session(app
->key
.sock
, ua_sess
->handle
);
1085 ERR("Error starting tracing for app pid: %d", app
->key
.pid
);
1089 /* Quiescent wait after starting trace */
1090 ustctl_wait_quiescent(app
->key
.sock
);
1092 DBG2("UST trace started for app pid %d", app
->key
.pid
);