Fix useless context hashtable size and segfault on destroy
[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 DBG("Starting all UST traces");
696
697 rcu_read_lock();
698 hashtable_get_first(ust_app_ht, &iter);
699 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
700 app = caa_container_of(node, struct ust_app, node);
701
702 ua_sess = lookup_session_by_app(usess, app);
703 if (ua_sess == NULL) {
704 /* Only malloc can failed so something is really wrong */
705 goto next;
706 }
707
708 if (ua_sess->metadata == NULL) {
709 /* Allocate UST metadata */
710 ua_sess->metadata = trace_ust_create_metadata(usess->pathname);
711 if (ua_sess->metadata == NULL) {
712 ERR("UST app session %d creating metadata failed",
713 ua_sess->handle);
714 goto next;
715 }
716
717 uattr.overwrite = ua_sess->metadata->attr.overwrite;
718 uattr.subbuf_size = ua_sess->metadata->attr.subbuf_size;
719 uattr.num_subbuf = ua_sess->metadata->attr.num_subbuf;
720 uattr.switch_timer_interval =
721 ua_sess->metadata->attr.switch_timer_interval;
722 uattr.read_timer_interval =
723 ua_sess->metadata->attr.read_timer_interval;
724 uattr.output = ua_sess->metadata->attr.output;
725
726 /* UST tracer metadata creation */
727 ret = ustctl_open_metadata(app->key.sock, ua_sess->handle, &uattr,
728 &ua_sess->metadata->obj);
729 if (ret < 0) {
730 ERR("UST app open metadata failed for app pid:%d",
731 app->key.pid);
732 goto next;
733 }
734
735 DBG2("UST metadata opened for app pid %d", app->key.pid);
736 }
737
738 /* Open UST metadata stream */
739 if (ua_sess->metadata->stream_obj == NULL) {
740 ret = ustctl_create_stream(app->key.sock, ua_sess->metadata->obj,
741 &ua_sess->metadata->stream_obj);
742 if (ret < 0) {
743 ERR("UST create metadata stream failed");
744 goto next;
745 }
746
747 ret = snprintf(ua_sess->metadata->pathname, PATH_MAX, "%s/%s",
748 usess->pathname, "metadata");
749 if (ret < 0) {
750 PERROR("asprintf UST create stream");
751 goto next;
752 }
753
754 DBG2("UST metadata stream object created for app pid %d",
755 app->key.pid);
756 }
757
758 /* For each channel */
759 hashtable_get_first(usess->domain_global.channels, &iter);
760 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
761 uchan = caa_container_of(node, struct ltt_ust_channel, node);
762
763 /* Lookup channel in the ust app session */
764 ua_chan_node = hashtable_lookup(ua_sess->channels,
765 (void *) uchan->name, strlen(uchan->name), &iter);
766 if (ua_chan_node == NULL) {
767 ERR("Channel suppose to be present with the above shallow "
768 "session copy. Continuing...");
769 goto next;
770 }
771
772 ua_chan = caa_container_of(ua_chan_node,
773 struct ust_app_channel, node);
774
775 for (;;) {
776 struct lttng_ust_object_data *obj;
777 struct ltt_ust_stream *ustream;
778
779 ret = ustctl_create_stream(app->key.sock, ua_chan->obj,
780 &obj);
781 if (ret < 0) {
782 /* Got all streams */
783 goto next_chan;
784 }
785
786 ustream = malloc(sizeof(*ustream));
787 if (ustream == NULL) {
788 goto next_chan;
789 }
790 memset(ustream, 0, sizeof(struct ltt_ust_stream));
791 ustream->obj = obj;
792 ustream->handle = ustream->obj->handle;
793 /* Order is important */
794 cds_list_add_tail(&ustream->list, &ua_chan->streams.head);
795 ret = snprintf(ustream->pathname, PATH_MAX, "%s/%s_%u",
796 uchan->pathname, uchan->name,
797 ua_chan->streams.count++);
798 if (ret < 0) {
799 PERROR("asprintf UST create stream");
800 goto next_chan;
801 }
802 }
803
804 next_chan:
805 /* Next applications */
806 hashtable_get_next(ua_sess->channels, &iter);
807 }
808
809 /* Setup UST consumer socket and send fds to it */
810 ret = ust_consumer_send_session(usess->consumer_fd, ua_sess);
811 if (ret < 0) {
812 goto next;
813 }
814
815 /* This start the UST tracing */
816 ret = ustctl_start_session(app->key.sock, ua_sess->handle);
817 if (ret < 0) {
818 ERR("Error starting tracing for app pid: %d", app->key.pid);
819 goto next;
820 }
821
822 /* Quiescent wait after starting trace */
823 ustctl_wait_quiescent(app->key.sock);
824 next:
825 /* Next applications */
826 hashtable_get_next(ust_app_ht, &iter);
827 }
828 rcu_read_unlock();
829
830 return 0;
831 }
832
833 void ust_app_global_update(struct ltt_ust_session *usess, int sock)
834 {
835 int ret = 0;
836 int session_existed = 1;
837 struct cds_lfht_iter iter;
838 struct cds_lfht_node *node, *ua_chan_node;
839 struct ust_app *app;
840 struct ust_app_session *ua_sess;
841 struct ust_app_channel *ua_chan;
842 struct ust_app_event *ua_event;
843 struct lttng_ust_event ltt_uevent;
844 struct ltt_ust_channel *uchan;
845 struct lttng_ust_object_data *obj_event;
846 struct lttng_ust_channel_attr uattr;
847
848 DBG2("UST app global update for app sock %d for session uid %d", sock,
849 usess->uid);
850
851 rcu_read_lock();
852 app = find_app_by_sock(sock);
853 if (app == NULL) {
854 ERR("Failed to update app sock %d", sock);
855 goto error;
856 }
857
858 ua_sess = lookup_session_by_app(usess, app);
859 if (ua_sess == NULL) {
860 DBG2("UST app pid: %d session uid %d not found, creating one",
861 app->key.pid, usess->uid);
862 ua_sess = alloc_app_session();
863 if (ua_sess == NULL) {
864 /* Only malloc can failed so something is really wrong */
865 goto error;
866 }
867 shallow_copy_session(ua_sess, usess);
868 session_existed= 0;
869 }
870
871 if (ua_sess->handle == -1) {
872 ret = ustctl_create_session(app->key.sock);
873 if (ret < 0) {
874 DBG("Error creating session for app pid %d, sock %d",
875 app->key.pid, app->key.sock);
876 /* TODO: free() ua_sess */
877 goto error;
878 }
879
880 DBG2("UST app ustctl create session handle %d", ret);
881 ua_sess->handle = ret;
882
883 /* Add ust app session to app's HT */
884 hashtable_node_init(&ua_sess->node,
885 (void *)((unsigned long) ua_sess->uid), sizeof(void *));
886 hashtable_add_unique(app->sessions, &ua_sess->node);
887 }
888
889 if (session_existed) {
890 goto error;
891 }
892
893 /* Iterate over all channels */
894 hashtable_get_first(usess->domain_global.channels, &iter);
895 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
896 uchan = caa_container_of(node, struct ltt_ust_channel, node);
897
898 /* Lookup channel in the ust app session */
899 ua_chan_node = hashtable_lookup(ua_sess->channels,
900 (void *) uchan->name, strlen(uchan->name), &iter);
901 if (ua_chan_node == NULL) {
902 ERR("UST app channel not found for uchan %s", uchan->name);
903 goto next_chan;
904 }
905
906 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
907
908 /* TODO: remove cast and use lttng-ust-abi.h */
909 ret = ustctl_create_channel(app->key.sock, ua_sess->handle,
910 (struct lttng_ust_channel_attr *)&uchan->attr, &ua_chan->obj);
911 if (ret < 0) {
912 DBG("Error creating channel %s for app (pid: %d, sock: %d) "
913 "and session handle %d with ret %d",
914 uchan->name, app->key.pid, app->key.sock,
915 ua_sess->handle, ret);
916 goto next_chan;
917 }
918
919 ua_chan->handle = ua_chan->obj->handle;
920 ua_chan->attr.shm_fd = ua_chan->obj->shm_fd;
921 ua_chan->attr.wait_fd = ua_chan->obj->wait_fd;
922 ua_chan->attr.memory_map_size = ua_chan->obj->memory_map_size;
923
924 DBG2("Channel %s UST create successfully for pid:%d and sock:%d",
925 uchan->name, app->key.pid, app->key.sock);
926
927 /* For each event(s) of that channel */
928 hashtable_get_first(ua_chan->events, &iter);
929 while ((node = hashtable_iter_get_node(&iter)) != NULL) {
930 ua_event = caa_container_of(node, struct ust_app_event, node);
931
932 /* Prepare lttng ust event */
933 memset(&ltt_uevent, 0, sizeof(ltt_uevent));
934 strncpy(ltt_uevent.name, ua_event->name, sizeof(ltt_uevent.name));
935 ltt_uevent.name[sizeof(ltt_uevent.name) - 1] = '\0';
936
937 /* TODO: adjust to other instrumentation types */
938 ltt_uevent.instrumentation = LTTNG_UST_TRACEPOINT;
939
940 /* Create UST event on tracer */
941 ret = ustctl_create_event(app->key.sock, &ltt_uevent, ua_chan->obj,
942 &obj_event);
943 if (ret < 0) {
944 ERR("Error ustctl create event %s for app pid: %d with ret %d",
945 ua_event->name, app->key.pid, ret);
946 /* TODO: free() ua_event and obj_event */
947 goto next_event;
948 }
949
950 ua_event->obj = obj_event;
951 ua_event->handle = obj_event->handle;
952 ua_event->enabled = 1;
953
954 DBG2("Event %s UST create successfully for pid:%d",
955 ua_event->name, app->key.pid);
956
957 next_event:
958 hashtable_get_next(ua_chan->events, &iter);
959 }
960
961 for (;;) {
962 struct lttng_ust_object_data *obj;
963 struct ltt_ust_stream *ustream;
964
965 ret = ustctl_create_stream(app->key.sock, ua_chan->obj, &obj);
966 if (ret < 0) {
967 /* Got all streams */
968 break;
969 }
970
971 ustream = zmalloc(sizeof(*ustream));
972 if (ustream == NULL) {
973 PERROR("zmalloc ust stream");
974 goto error;
975 }
976
977 ustream->obj = obj;
978 ustream->handle = ustream->obj->handle;
979 /* Order is important */
980 cds_list_add_tail(&ustream->list, &ua_chan->streams.head);
981
982 ret = snprintf(ustream->pathname, PATH_MAX, "%s/%s_%u",
983 uchan->pathname, uchan->name, ua_chan->streams.count++);
984 if (ret < 0) {
985 PERROR("asprintf UST create stream");
986 goto error;
987 }
988 }
989
990 next_chan:
991 /* Next applications */
992 hashtable_get_next(ua_sess->channels, &iter);
993 }
994
995 if (ua_sess->metadata == NULL) {
996 /* Allocate UST metadata */
997 ua_sess->metadata = trace_ust_create_metadata(usess->pathname);
998 if (ua_sess->metadata == NULL) {
999 ERR("UST app session %d creating metadata failed",
1000 ua_sess->handle);
1001 goto error;
1002 }
1003
1004 uattr.overwrite = ua_sess->metadata->attr.overwrite;
1005 uattr.subbuf_size = ua_sess->metadata->attr.subbuf_size;
1006 uattr.num_subbuf = ua_sess->metadata->attr.num_subbuf;
1007 uattr.switch_timer_interval =
1008 ua_sess->metadata->attr.switch_timer_interval;
1009 uattr.read_timer_interval =
1010 ua_sess->metadata->attr.read_timer_interval;
1011 uattr.output = ua_sess->metadata->attr.output;
1012
1013 /* UST tracer metadata creation */
1014 ret = ustctl_open_metadata(app->key.sock, ua_sess->handle, &uattr,
1015 &ua_sess->metadata->obj);
1016 if (ret < 0) {
1017 ERR("UST app open metadata failed for app pid:%d",
1018 app->key.pid);
1019 goto error;
1020 }
1021
1022 DBG2("UST metadata opened for app pid %d", app->key.pid);
1023 }
1024
1025 /* Open UST metadata stream */
1026 if (ua_sess->metadata->stream_obj == NULL) {
1027 ret = ustctl_create_stream(app->key.sock, ua_sess->metadata->obj,
1028 &ua_sess->metadata->stream_obj);
1029 if (ret < 0) {
1030 ERR("UST create metadata stream failed");
1031 goto error;
1032 }
1033
1034 ret = snprintf(ua_sess->metadata->pathname, PATH_MAX, "%s/%s",
1035 usess->pathname, "metadata");
1036 if (ret < 0) {
1037 PERROR("asprintf UST create stream");
1038 goto error;
1039 }
1040
1041 DBG2("UST metadata stream object created for app pid %d",
1042 app->key.pid);
1043 }
1044
1045 if (usess->start_trace) {
1046 /* Setup UST consumer socket and send fds to it */
1047 ret = ust_consumer_send_session(usess->consumer_fd, ua_sess);
1048 if (ret < 0) {
1049 ERR("UST consumer send session failed");
1050 goto error;
1051 }
1052
1053 /* This start the UST tracing */
1054 ret = ustctl_start_session(app->key.sock, ua_sess->handle);
1055 if (ret < 0) {
1056 ERR("Error starting tracing for app pid: %d", app->key.pid);
1057 goto error;
1058 }
1059
1060 /* Quiescent wait after starting trace */
1061 ustctl_wait_quiescent(app->key.sock);
1062
1063 DBG2("UST trace started for app pid %d", app->key.pid);
1064 }
1065
1066 error:
1067 rcu_read_unlock();
1068 return;
1069 }
This page took 0.051426 seconds and 4 git commands to generate.