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