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