Implement run_as wrappers for mkdir/mkdir_recursive/open
[lttng-tools.git] / lttng-sessiond / ust-app.c
CommitLineData
91d76f53
DG
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
82a3637f
DG
6 * as published by the Free Software Foundation; only version 2
7 * of the License.
91d76f53
DG
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>
099e26bd 24#include <string.h>
aba8e916
DG
25#include <sys/stat.h>
26#include <sys/types.h>
099e26bd 27#include <unistd.h>
91d76f53 28
0df502fd 29#include <urcu/compiler.h>
1e307fab 30#include <lttngerr.h>
48842b30 31#include <lttng-share.h>
1e307fab 32
f6a9efaa 33#include "hashtable.h"
56fff090 34#include "ust-app.h"
48842b30 35#include "ust-consumer.h"
d80a6244 36#include "ust-ctl.h"
67f747d8 37#include "utils.h"
d80a6244 38
55cc08a6
DG
39/*
40 * Delete ust context safely. RCU read lock must be held before calling
41 * this function.
42 */
43static
44void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx)
45{
46 if (ua_ctx->obj) {
47 ustctl_release_object(sock, ua_ctx->obj);
48 free(ua_ctx->obj);
49 }
50 free(ua_ctx);
51}
52
d80a6244
DG
53/*
54 * Delete ust app event safely. RCU read lock must be held before calling
55 * this function.
56 */
8b366481
DG
57static
58void delete_ust_app_event(int sock, struct ust_app_event *ua_event)
d80a6244 59{
55cc08a6
DG
60 int ret;
61 struct cds_lfht_iter iter;
62 struct ust_app_ctx *ua_ctx;
63
64 cds_lfht_for_each_entry(ua_event->ctx, &iter, ua_ctx, node) {
65 ret = hashtable_del(ua_event->ctx, &iter);
66 assert(!ret);
67 delete_ust_app_ctx(sock, ua_ctx);
68 }
69 ret = hashtable_destroy(ua_event->ctx);
70 assert(!ret);
d80a6244 71
edb67388
DG
72 if (ua_event->obj != NULL) {
73 ustctl_release_object(sock, ua_event->obj);
74 free(ua_event->obj);
75 }
d80a6244
DG
76 free(ua_event);
77}
78
79/*
80 * Delete ust app stream safely. RCU read lock must be held before calling
81 * this function.
82 */
8b366481
DG
83static
84void delete_ust_app_stream(int sock, struct ltt_ust_stream *stream)
d80a6244 85{
8b366481
DG
86 if (stream->obj) {
87 ustctl_release_object(sock, stream->obj);
88 free(stream->obj);
89 }
84cd17c6 90 free(stream);
d80a6244
DG
91}
92
93/*
94 * Delete ust app channel safely. RCU read lock must be held before calling
95 * this function.
96 */
8b366481
DG
97static
98void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan)
d80a6244
DG
99{
100 int ret;
101 struct cds_lfht_iter iter;
102 struct ust_app_event *ua_event;
55cc08a6 103 struct ust_app_ctx *ua_ctx;
d80a6244
DG
104 struct ltt_ust_stream *stream, *stmp;
105
55cc08a6 106 /* Wipe stream */
d80a6244 107 cds_list_for_each_entry_safe(stream, stmp, &ua_chan->streams.head, list) {
84cd17c6 108 cds_list_del(&stream->list);
d80a6244
DG
109 delete_ust_app_stream(sock, stream);
110 }
111
55cc08a6
DG
112 /* Wipe context */
113 cds_lfht_for_each_entry(ua_chan->ctx, &iter, ua_ctx, node) {
114 ret = hashtable_del(ua_chan->ctx, &iter);
115 assert(!ret);
116 delete_ust_app_ctx(sock, ua_ctx);
117 }
118 ret = hashtable_destroy(ua_chan->ctx);
119 assert(!ret);
d80a6244 120
55cc08a6 121 /* Wipe events */
d80a6244 122 cds_lfht_for_each_entry(ua_chan->events, &iter, ua_event, node) {
525b0740
MD
123 ret = hashtable_del(ua_chan->events, &iter);
124 assert(!ret);
d80a6244
DG
125 delete_ust_app_event(sock, ua_event);
126 }
d80a6244 127 ret = hashtable_destroy(ua_chan->events);
55cc08a6 128 assert(!ret);
edb67388
DG
129
130 if (ua_chan->obj != NULL) {
131 ustctl_release_object(sock, ua_chan->obj);
132 free(ua_chan->obj);
133 }
84cd17c6 134 free(ua_chan);
d80a6244
DG
135}
136
137/*
138 * Delete ust app session safely. RCU read lock must be held before calling
139 * this function.
140 */
8b366481
DG
141static
142void delete_ust_app_session(int sock, struct ust_app_session *ua_sess)
d80a6244
DG
143{
144 int ret;
145 struct cds_lfht_iter iter;
146 struct ust_app_channel *ua_chan;
147
148 if (ua_sess->metadata) {
8b366481
DG
149 if (ua_sess->metadata->stream_obj) {
150 ustctl_release_object(sock, ua_sess->metadata->stream_obj);
151 free(ua_sess->metadata->stream_obj);
152 }
153 if (ua_sess->metadata->obj) {
154 ustctl_release_object(sock, ua_sess->metadata->obj);
155 free(ua_sess->metadata->obj);
156 }
d80a6244
DG
157 }
158
159 cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) {
525b0740
MD
160 ret = hashtable_del(ua_sess->channels, &iter);
161 assert(!ret);
d80a6244
DG
162 delete_ust_app_channel(sock, ua_chan);
163 }
d80a6244 164 ret = hashtable_destroy(ua_sess->channels);
8b366481 165 assert(!ret);
d80a6244 166
aee6bafd
MD
167 if (ua_sess->handle != -1) {
168 ustctl_release_handle(sock, ua_sess->handle);
169 }
8b366481 170 free(ua_sess);
d80a6244 171}
91d76f53
DG
172
173/*
284d8f55
DG
174 * Delete a traceable application structure from the global list. Never call
175 * this function outside of a call_rcu call.
91d76f53 176 */
8b366481
DG
177static
178void delete_ust_app(struct ust_app *app)
91d76f53 179{
8b366481 180 int ret, sock;
f6a9efaa
DG
181 struct cds_lfht_node *node;
182 struct cds_lfht_iter iter;
284d8f55 183 struct ust_app_session *ua_sess;
44d3bd01 184
f6a9efaa 185 rcu_read_lock();
44d3bd01 186
f6a9efaa
DG
187 /* Remove from key hash table */
188 node = hashtable_lookup(ust_app_sock_key_map,
284d8f55 189 (void *) ((unsigned long) app->key.sock), sizeof(void *), &iter);
f6a9efaa 190 if (node == NULL) {
284d8f55
DG
191 /* Not suppose to happen */
192 ERR("UST app key %d not found in key hash table", app->key.sock);
d80a6244 193 goto end;
284d8f55
DG
194 }
195
196 ret = hashtable_del(ust_app_sock_key_map, &iter);
197 if (ret) {
198 ERR("UST app unable to delete app sock %d from key hash table",
199 app->key.sock);
f6a9efaa 200 } else {
284d8f55
DG
201 DBG2("UST app pair sock %d key %d deleted",
202 app->key.sock, app->key.pid);
f6a9efaa
DG
203 }
204
d80a6244
DG
205 /* Socket is already closed at this point */
206
207 /* Delete ust app sessions info */
6414a713
MD
208 sock = app->key.sock;
209 app->key.sock = -1;
d80a6244 210
8b366481 211 /* Wipe sessions */
284d8f55 212 cds_lfht_for_each_entry(app->sessions, &iter, ua_sess, node) {
525b0740
MD
213 ret = hashtable_del(app->sessions, &iter);
214 assert(!ret);
284d8f55 215 delete_ust_app_session(app->key.sock, ua_sess);
d80a6244 216 }
284d8f55 217 ret = hashtable_destroy(app->sessions);
8b366481 218 assert(!ret);
d80a6244 219
6414a713
MD
220 /*
221 * Wait until we have removed the key from the sock hash table
222 * before closing this socket, otherwise an application could
223 * re-use the socket ID and race with the teardown, using the
224 * same hash table entry.
225 */
226 close(sock);
d80a6244 227
284d8f55
DG
228 DBG2("UST app pid %d deleted", app->key.pid);
229 free(app);
d80a6244 230end:
f6a9efaa 231 rcu_read_unlock();
099e26bd
DG
232}
233
234/*
f6a9efaa 235 * URCU intermediate call to delete an UST app.
099e26bd 236 */
8b366481
DG
237static
238void delete_ust_app_rcu(struct rcu_head *head)
099e26bd 239{
f6a9efaa
DG
240 struct cds_lfht_node *node =
241 caa_container_of(head, struct cds_lfht_node, head);
242 struct ust_app *app =
243 caa_container_of(node, struct ust_app, node);
244
245 delete_ust_app(app);
099e26bd
DG
246}
247
8b366481
DG
248/*
249 * Alloc new UST app session.
250 */
251static
252struct ust_app_session *alloc_ust_app_session(void)
253{
254 struct ust_app_session *ua_sess;
255
256 /* Init most of the default value by allocating and zeroing */
257 ua_sess = zmalloc(sizeof(struct ust_app_session));
258 if (ua_sess == NULL) {
259 PERROR("malloc");
260 goto error;
261 }
262
263 ua_sess->handle = -1;
264 ua_sess->channels = hashtable_new_str(0);
265
266 return ua_sess;
267
268error:
269 return NULL;
270}
271
272/*
273 * Alloc new UST app channel.
274 */
275static
276struct ust_app_channel *alloc_ust_app_channel(char *name,
277 struct lttng_ust_channel *attr)
278{
279 struct ust_app_channel *ua_chan;
280
281 /* Init most of the default value by allocating and zeroing */
282 ua_chan = zmalloc(sizeof(struct ust_app_channel));
283 if (ua_chan == NULL) {
284 PERROR("malloc");
285 goto error;
286 }
287
288 /* Setup channel name */
289 strncpy(ua_chan->name, name, sizeof(ua_chan->name));
290 ua_chan->name[sizeof(ua_chan->name) - 1] = '\0';
291
292 ua_chan->enabled = 1;
293 ua_chan->handle = -1;
294 ua_chan->ctx = hashtable_new(0);
295 ua_chan->events = hashtable_new_str(0);
296 hashtable_node_init(&ua_chan->node, (void *) ua_chan->name,
297 strlen(ua_chan->name));
298
299 CDS_INIT_LIST_HEAD(&ua_chan->streams.head);
300
301 /* Copy attributes */
302 if (attr) {
303 memcpy(&ua_chan->attr, attr, sizeof(ua_chan->attr));
304 }
305
306 DBG3("UST app channel %s allocated", ua_chan->name);
307
308 return ua_chan;
309
310error:
311 return NULL;
312}
313
314/*
315 * Alloc new UST app event.
316 */
317static
318struct ust_app_event *alloc_ust_app_event(char *name,
319 struct lttng_ust_event *attr)
320{
321 struct ust_app_event *ua_event;
322
323 /* Init most of the default value by allocating and zeroing */
324 ua_event = zmalloc(sizeof(struct ust_app_event));
325 if (ua_event == NULL) {
326 PERROR("malloc");
327 goto error;
328 }
329
330 ua_event->enabled = 1;
331 strncpy(ua_event->name, name, sizeof(ua_event->name));
332 ua_event->name[sizeof(ua_event->name) - 1] = '\0';
333 ua_event->ctx = hashtable_new(0);
334 hashtable_node_init(&ua_event->node, (void *) ua_event->name,
335 strlen(ua_event->name));
336
337 /* Copy attributes */
338 if (attr) {
339 memcpy(&ua_event->attr, attr, sizeof(ua_event->attr));
340 }
341
342 DBG3("UST app event %s allocated", ua_event->name);
343
344 return ua_event;
345
346error:
347 return NULL;
348}
349
350/*
351 * Alloc new UST app context.
352 */
353static
354struct ust_app_ctx *alloc_ust_app_ctx(struct lttng_ust_context *uctx)
355{
356 struct ust_app_ctx *ua_ctx;
357
358 ua_ctx = zmalloc(sizeof(struct ust_app_ctx));
359 if (ua_ctx == NULL) {
360 goto error;
361 }
362
363 if (uctx) {
364 memcpy(&ua_ctx->ctx, uctx, sizeof(ua_ctx->ctx));
365 }
366
367 DBG3("UST app context %d allocated", ua_ctx->ctx.ctx);
368
369error:
370 return ua_ctx;
371}
372
099e26bd 373/*
421cb601
DG
374 * Find an ust_app using the sock and return it. RCU read side lock must be
375 * held before calling this helper function.
099e26bd 376 */
8b366481
DG
377static
378struct ust_app *find_app_by_sock(int sock)
099e26bd 379{
f6a9efaa
DG
380 struct cds_lfht_node *node;
381 struct ust_app_key *key;
382 struct cds_lfht_iter iter;
f6a9efaa 383
f6a9efaa
DG
384 node = hashtable_lookup(ust_app_sock_key_map,
385 (void *)((unsigned long) sock), sizeof(void *), &iter);
386 if (node == NULL) {
387 DBG2("UST app find by sock %d key not found", sock);
f6a9efaa
DG
388 goto error;
389 }
390
391 key = caa_container_of(node, struct ust_app_key, node);
392
393 node = hashtable_lookup(ust_app_ht,
394 (void *)((unsigned long) key->pid), sizeof(void *), &iter);
395 if (node == NULL) {
396 DBG2("UST app find by sock %d not found", sock);
f6a9efaa
DG
397 goto error;
398 }
f6a9efaa
DG
399 return caa_container_of(node, struct ust_app, node);
400
401error:
402 return NULL;
099e26bd
DG
403}
404
55cc08a6
DG
405/*
406 * Create the channel context on the tracer.
407 */
408static
409int create_ust_channel_context(struct ust_app_channel *ua_chan,
410 struct ust_app_ctx *ua_ctx, struct ust_app *app)
411{
412 int ret;
413
414 ret = ustctl_add_context(app->key.sock, &ua_ctx->ctx,
415 ua_chan->obj, &ua_ctx->obj);
416 if (ret < 0) {
417 goto error;
418 }
419
420 ua_ctx->handle = ua_ctx->obj->handle;
421
422 DBG2("UST app context added to channel %s successfully", ua_chan->name);
423
424error:
425 return ret;
426}
427
428/*
429 * Create the event context on the tracer.
430 */
431static
432int create_ust_event_context(struct ust_app_event *ua_event,
433 struct ust_app_ctx *ua_ctx, struct ust_app *app)
434{
435 int ret;
436
437 ret = ustctl_add_context(app->key.sock, &ua_ctx->ctx,
438 ua_event->obj, &ua_ctx->obj);
439 if (ret < 0) {
440 goto error;
441 }
442
443 ua_ctx->handle = ua_ctx->obj->handle;
444
445 DBG2("UST app context added to event %s successfully", ua_event->name);
446
447error:
448 return ret;
449}
450
9730260e
DG
451/*
452 * Disable the specified event on to UST tracer for the UST session.
453 */
454static int disable_ust_event(struct ust_app *app,
455 struct ust_app_session *ua_sess, struct ust_app_event *ua_event)
456{
457 int ret;
458
459 ret = ustctl_disable(app->key.sock, ua_event->obj);
460 if (ret < 0) {
461 ERR("UST app event %s disable failed for app (pid: %d) "
462 "and session handle %d with ret %d",
463 ua_event->attr.name, app->key.pid, ua_sess->handle, ret);
464 goto error;
465 }
466
467 DBG2("UST app event %s disabled successfully for app (pid: %d)",
468 ua_event->attr.name, app->key.pid);
469
470error:
471 return ret;
472}
473
78f0bacd
DG
474/*
475 * Disable the specified channel on to UST tracer for the UST session.
476 */
477static int disable_ust_channel(struct ust_app *app,
478 struct ust_app_session *ua_sess, struct ust_app_channel *ua_chan)
479{
480 int ret;
481
482 ret = ustctl_disable(app->key.sock, ua_chan->obj);
483 if (ret < 0) {
484 ERR("UST app channel %s disable failed for app (pid: %d) "
485 "and session handle %d with ret %d",
486 ua_chan->name, app->key.pid, ua_sess->handle, ret);
487 goto error;
488 }
489
78f0bacd
DG
490 DBG2("UST app channel %s disabled successfully for app (pid: %d)",
491 ua_chan->name, app->key.pid);
492
493error:
494 return ret;
495}
496
497/*
498 * Enable the specified channel on to UST tracer for the UST session.
499 */
500static int enable_ust_channel(struct ust_app *app,
501 struct ust_app_session *ua_sess, struct ust_app_channel *ua_chan)
502{
503 int ret;
504
505 ret = ustctl_enable(app->key.sock, ua_chan->obj);
506 if (ret < 0) {
507 ERR("UST app channel %s enable failed for app (pid: %d) "
508 "and session handle %d with ret %d",
509 ua_chan->name, app->key.pid, ua_sess->handle, ret);
510 goto error;
511 }
512
513 ua_chan->enabled = 1;
514
515 DBG2("UST app channel %s enabled successfully for app (pid: %d)",
516 ua_chan->name, app->key.pid);
517
518error:
519 return ret;
520}
521
edb67388
DG
522/*
523 * Enable the specified event on to UST tracer for the UST session.
524 */
525static int enable_ust_event(struct ust_app *app,
526 struct ust_app_session *ua_sess, struct ust_app_event *ua_event)
527{
528 int ret;
529
530 ret = ustctl_enable(app->key.sock, ua_event->obj);
531 if (ret < 0) {
532 ERR("UST app event %s enable failed for app (pid: %d) "
533 "and session handle %d with ret %d",
534 ua_event->attr.name, app->key.pid, ua_sess->handle, ret);
535 goto error;
536 }
537
538 DBG2("UST app event %s enabled successfully for app (pid: %d)",
539 ua_event->attr.name, app->key.pid);
540
541error:
542 return ret;
543}
544
099e26bd 545/*
5b4a0ec0 546 * Open metadata onto the UST tracer for a UST session.
0177d773 547 */
5b4a0ec0
DG
548static int open_ust_metadata(struct ust_app *app,
549 struct ust_app_session *ua_sess)
0177d773 550{
5b4a0ec0
DG
551 int ret;
552 struct lttng_ust_channel_attr uattr;
0177d773 553
5b4a0ec0
DG
554 uattr.overwrite = ua_sess->metadata->attr.overwrite;
555 uattr.subbuf_size = ua_sess->metadata->attr.subbuf_size;
556 uattr.num_subbuf = ua_sess->metadata->attr.num_subbuf;
557 uattr.switch_timer_interval =
558 ua_sess->metadata->attr.switch_timer_interval;
559 uattr.read_timer_interval =
560 ua_sess->metadata->attr.read_timer_interval;
561 uattr.output = ua_sess->metadata->attr.output;
562
563 /* UST tracer metadata creation */
564 ret = ustctl_open_metadata(app->key.sock, ua_sess->handle, &uattr,
565 &ua_sess->metadata->obj);
566 if (ret < 0) {
567 ERR("UST app open metadata failed for app pid:%d",
568 app->key.pid);
f6a9efaa 569 goto error;
0177d773 570 }
f6a9efaa 571
6d3686da
DG
572 ua_sess->metadata->handle = ua_sess->metadata->obj->handle;
573
f6a9efaa 574error:
5b4a0ec0 575 return ret;
91d76f53
DG
576}
577
578/*
5b4a0ec0 579 * Create stream onto the UST tracer for a UST session.
91d76f53 580 */
5b4a0ec0
DG
581static int create_ust_stream(struct ust_app *app,
582 struct ust_app_session *ua_sess)
91d76f53 583{
5b4a0ec0 584 int ret;
421cb601 585
5b4a0ec0
DG
586 ret = ustctl_create_stream(app->key.sock, ua_sess->metadata->obj,
587 &ua_sess->metadata->stream_obj);
588 if (ret < 0) {
589 ERR("UST create metadata stream failed");
421cb601 590 goto error;
91d76f53 591 }
421cb601 592
421cb601 593error:
5b4a0ec0 594 return ret;
91d76f53
DG
595}
596
b551a063 597/*
5b4a0ec0 598 * Create the specified channel onto the UST tracer for a UST session.
b551a063 599 */
5b4a0ec0
DG
600static int create_ust_channel(struct ust_app *app,
601 struct ust_app_session *ua_sess, struct ust_app_channel *ua_chan)
b551a063 602{
5b4a0ec0 603 int ret;
b551a063 604
5b4a0ec0
DG
605 /* TODO: remove cast and use lttng-ust-abi.h */
606 ret = ustctl_create_channel(app->key.sock, ua_sess->handle,
607 (struct lttng_ust_channel_attr *)&ua_chan->attr, &ua_chan->obj);
608 if (ret < 0) {
609 DBG("Error creating channel %s for app (pid: %d, sock: %d) "
610 "and session handle %d with ret %d",
611 ua_chan->name, app->key.pid, app->key.sock,
612 ua_sess->handle, ret);
b551a063
DG
613 goto error;
614 }
615
5b4a0ec0
DG
616 ua_chan->handle = ua_chan->obj->handle;
617 ua_chan->attr.shm_fd = ua_chan->obj->shm_fd;
618 ua_chan->attr.wait_fd = ua_chan->obj->wait_fd;
619 ua_chan->attr.memory_map_size = ua_chan->obj->memory_map_size;
b551a063 620
5b4a0ec0
DG
621 DBG2("UST app channel %s created successfully for pid:%d and sock:%d",
622 ua_chan->name, app->key.pid, app->key.sock);
b551a063 623
8535a6d9
DG
624 /* If channel is not enabled, disable it on the tracer */
625 if (!ua_chan->enabled) {
626 ret = disable_ust_channel(app, ua_sess, ua_chan);
627 if (ret < 0) {
628 goto error;
629 }
630 }
631
b551a063
DG
632error:
633 return ret;
634}
635
91d76f53 636/*
5b4a0ec0 637 * Create the specified event onto the UST tracer for a UST session.
91d76f53 638 */
edb67388
DG
639static
640int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess,
641 struct ust_app_channel *ua_chan, struct ust_app_event *ua_event)
91d76f53 642{
5b4a0ec0 643 int ret = 0;
284d8f55 644
5b4a0ec0
DG
645 /* Create UST event on tracer */
646 ret = ustctl_create_event(app->key.sock, &ua_event->attr, ua_chan->obj,
647 &ua_event->obj);
648 if (ret < 0) {
649 ERR("Error ustctl create event %s for app pid: %d with ret %d",
650 ua_event->attr.name, app->key.pid, ret);
651 goto error;
91d76f53 652 }
f6a9efaa 653
5b4a0ec0 654 ua_event->handle = ua_event->obj->handle;
284d8f55 655
5b4a0ec0
DG
656 DBG2("UST app event %s created successfully for pid:%d",
657 ua_event->attr.name, app->key.pid);
f6a9efaa 658
8535a6d9
DG
659 /* If event not enabled, disable it on the tracer */
660 if (!ua_event->enabled) {
661 ret = disable_ust_event(app, ua_sess, ua_event);
662 if (ret < 0) {
663 goto error;
664 }
665 }
666
5b4a0ec0
DG
667error:
668 return ret;
91d76f53 669}
48842b30 670
5b4a0ec0
DG
671/*
672 * Copy data between an UST app event and a LTT event.
673 */
421cb601 674static void shadow_copy_event(struct ust_app_event *ua_event,
48842b30
DG
675 struct ltt_ust_event *uevent)
676{
55cc08a6
DG
677 struct cds_lfht_iter iter;
678 struct ltt_ust_context *uctx;
679 struct ust_app_ctx *ua_ctx;
680
48842b30
DG
681 strncpy(ua_event->name, uevent->attr.name, sizeof(ua_event->name));
682 ua_event->name[sizeof(ua_event->name) - 1] = '\0';
683
5b4a0ec0
DG
684 /* Copy event attributes */
685 memcpy(&ua_event->attr, &uevent->attr, sizeof(ua_event->attr));
686
55cc08a6
DG
687 cds_lfht_for_each_entry(uevent->ctx, &iter, uctx, node) {
688 ua_ctx = alloc_ust_app_ctx(&uctx->ctx);
689 if (ua_ctx == NULL) {
690 continue;
691 }
692 hashtable_node_init(&ua_ctx->node,
693 (void *)((unsigned long) ua_ctx->ctx.ctx), sizeof(void *));
694 hashtable_add_unique(ua_event->ctx, &ua_ctx->node);
695 }
48842b30
DG
696}
697
5b4a0ec0
DG
698/*
699 * Copy data between an UST app channel and a LTT channel.
700 */
421cb601 701static void shadow_copy_channel(struct ust_app_channel *ua_chan,
48842b30
DG
702 struct ltt_ust_channel *uchan)
703{
704 struct cds_lfht_iter iter;
5b4a0ec0 705 struct cds_lfht_node *ua_event_node;
48842b30 706 struct ltt_ust_event *uevent;
55cc08a6 707 struct ltt_ust_context *uctx;
48842b30 708 struct ust_app_event *ua_event;
55cc08a6 709 struct ust_app_ctx *ua_ctx;
48842b30 710
421cb601 711 DBG2("Shadow copy of UST app channel %s", ua_chan->name);
48842b30
DG
712
713 strncpy(ua_chan->name, uchan->name, sizeof(ua_chan->name));
714 ua_chan->name[sizeof(ua_chan->name) - 1] = '\0';
5b4a0ec0
DG
715 /* Copy event attributes */
716 memcpy(&ua_chan->attr, &uchan->attr, sizeof(ua_chan->attr));
48842b30 717
55cc08a6
DG
718 cds_lfht_for_each_entry(uchan->ctx, &iter, uctx, node) {
719 ua_ctx = alloc_ust_app_ctx(&uctx->ctx);
720 if (ua_ctx == NULL) {
721 continue;
722 }
723 hashtable_node_init(&ua_ctx->node,
724 (void *)((unsigned long) ua_ctx->ctx.ctx), sizeof(void *));
725 hashtable_add_unique(ua_chan->ctx, &ua_ctx->node);
726 }
48842b30 727
421cb601 728 /* Copy all events from ltt ust channel to ust app channel */
5b4a0ec0 729 cds_lfht_for_each_entry(uchan->events, &iter, uevent, node) {
ba767faf
MD
730 struct cds_lfht_iter uiter;
731
48842b30 732 ua_event_node = hashtable_lookup(ua_chan->events,
ba767faf
MD
733 (void *) uevent->attr.name, strlen(uevent->attr.name),
734 &uiter);
48842b30 735 if (ua_event_node == NULL) {
421cb601 736 DBG2("UST event %s not found on shadow copy channel",
48842b30 737 uevent->attr.name);
284d8f55 738 ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr);
48842b30 739 if (ua_event == NULL) {
5b4a0ec0 740 continue;
48842b30 741 }
421cb601 742 shadow_copy_event(ua_event, uevent);
48842b30 743 hashtable_add_unique(ua_chan->events, &ua_event->node);
48842b30 744 }
48842b30
DG
745 }
746
421cb601 747 DBG3("Shadow copy channel done");
48842b30
DG
748}
749
5b4a0ec0
DG
750/*
751 * Copy data between a UST app session and a regular LTT session.
752 */
421cb601 753static void shadow_copy_session(struct ust_app_session *ua_sess,
477d7741
MD
754 struct ltt_ust_session *usess,
755 struct ust_app *app)
48842b30 756{
5b4a0ec0 757 struct cds_lfht_node *ua_chan_node;
48842b30
DG
758 struct cds_lfht_iter iter;
759 struct ltt_ust_channel *uchan;
760 struct ust_app_channel *ua_chan;
477d7741
MD
761 time_t rawtime;
762 struct tm *timeinfo;
763 char datetime[16];
764 int ret;
765
766 /* Get date and time for unique app path */
767 time(&rawtime);
768 timeinfo = localtime(&rawtime);
769 strftime(datetime, sizeof(datetime), "%Y%m%d-%H%M%S", timeinfo);
48842b30 770
421cb601 771 DBG2("Shadow copy of session handle %d", ua_sess->handle);
48842b30 772
a991f516 773 ua_sess->id = usess->id;
6df2e2c9
MD
774 ua_sess->uid = usess->uid;
775 ua_sess->gid = usess->gid;
48842b30 776
477d7741
MD
777 ret = snprintf(ua_sess->path, PATH_MAX,
778 "%s/%s-%d-%s",
779 usess->pathname, app->name, app->key.pid,
780 datetime);
781 if (ret < 0) {
782 PERROR("asprintf UST shadow copy session");
783 /* TODO: We cannot return an error from here.. */
784 assert(0);
785 }
786
48842b30
DG
787 /* TODO: support all UST domain */
788
789 /* Iterate over all channels in global domain. */
5b4a0ec0
DG
790 cds_lfht_for_each_entry(usess->domain_global.channels, &iter,
791 uchan, node) {
ba767faf
MD
792 struct cds_lfht_iter uiter;
793
48842b30 794 ua_chan_node = hashtable_lookup(ua_sess->channels,
ba767faf
MD
795 (void *)uchan->name, strlen(uchan->name),
796 &uiter);
5b4a0ec0
DG
797 if (ua_chan_node != NULL) {
798 continue;
799 }
421cb601 800
5b4a0ec0
DG
801 DBG2("Channel %s not found on shadow session copy, creating it",
802 uchan->name);
803 ua_chan = alloc_ust_app_channel(uchan->name, &uchan->attr);
804 if (ua_chan == NULL) {
805 /* malloc failed... continuing */
806 continue;
48842b30
DG
807 }
808
5b4a0ec0
DG
809 shadow_copy_channel(ua_chan, uchan);
810 hashtable_add_unique(ua_sess->channels, &ua_chan->node);
48842b30
DG
811 }
812}
813
78f0bacd
DG
814/*
815 * Lookup sesison wrapper.
816 */
84cd17c6
MD
817static
818void __lookup_session_by_app(struct ltt_ust_session *usess,
819 struct ust_app *app, struct cds_lfht_iter *iter)
820{
821 /* Get right UST app session from app */
822 (void) hashtable_lookup(app->sessions,
a991f516 823 (void *) ((unsigned long) usess->id), sizeof(void *),
84cd17c6
MD
824 iter);
825}
826
421cb601
DG
827/*
828 * Return ust app session from the app session hashtable using the UST session
a991f516 829 * id.
421cb601 830 */
48842b30
DG
831static struct ust_app_session *lookup_session_by_app(
832 struct ltt_ust_session *usess, struct ust_app *app)
833{
834 struct cds_lfht_iter iter;
835 struct cds_lfht_node *node;
836
84cd17c6
MD
837 __lookup_session_by_app(usess, app, &iter);
838 node = hashtable_iter_get_node(&iter);
48842b30
DG
839 if (node == NULL) {
840 goto error;
841 }
842
843 return caa_container_of(node, struct ust_app_session, node);
844
845error:
846 return NULL;
847}
848
421cb601
DG
849/*
850 * Create a UST session onto the tracer of app and add it the session
851 * hashtable.
852 *
853 * Return ust app session or NULL on error.
854 */
855static struct ust_app_session *create_ust_app_session(
856 struct ltt_ust_session *usess, struct ust_app *app)
857{
858 int ret;
859 struct ust_app_session *ua_sess;
860
861 ua_sess = lookup_session_by_app(usess, app);
862 if (ua_sess == NULL) {
a991f516
MD
863 DBG2("UST app pid: %d session id %d not found, creating it",
864 app->key.pid, usess->id);
421cb601
DG
865 ua_sess = alloc_ust_app_session();
866 if (ua_sess == NULL) {
867 /* Only malloc can failed so something is really wrong */
868 goto error;
869 }
477d7741 870 shadow_copy_session(ua_sess, usess, app);
421cb601
DG
871 }
872
873 if (ua_sess->handle == -1) {
874 ret = ustctl_create_session(app->key.sock);
875 if (ret < 0) {
876 ERR("Error creating session for app pid %d, sock %d",
877 app->key.pid, app->key.sock);
878 /* TODO: free() ua_sess */
879 goto error;
880 }
881
882 DBG2("UST app ustctl create session handle %d", ret);
883 ua_sess->handle = ret;
884
885 /* Add ust app session to app's HT */
886 hashtable_node_init(&ua_sess->node,
a991f516 887 (void *)((unsigned long) ua_sess->id), sizeof(void *));
421cb601
DG
888 hashtable_add_unique(app->sessions, &ua_sess->node);
889
890 DBG2("UST app session created successfully with handle %d", ret);
891 }
892
893 return ua_sess;
894
895error:
896 return NULL;
897}
898
55cc08a6
DG
899/*
900 * Create a context for the channel on the tracer.
901 */
902static
903int create_ust_app_channel_context(struct ust_app_session *ua_sess,
904 struct ust_app_channel *ua_chan, struct lttng_ust_context *uctx,
905 struct ust_app *app)
906{
907 int ret = 0;
908 struct cds_lfht_iter iter;
909 struct cds_lfht_node *node;
910 struct ust_app_ctx *ua_ctx;
911
912 DBG2("UST app adding context to channel %s", ua_chan->name);
913
914 node = hashtable_lookup(ua_chan->ctx, (void *)((unsigned long)uctx->ctx),
915 sizeof(void *), &iter);
916 if (node != NULL) {
917 ret = -EEXIST;
918 goto error;
919 }
920
921 ua_ctx = alloc_ust_app_ctx(uctx);
922 if (ua_ctx == NULL) {
923 /* malloc failed */
924 ret = -1;
925 goto error;
926 }
927
928 hashtable_node_init(&ua_ctx->node,
929 (void *)((unsigned long) ua_ctx->ctx.ctx), sizeof(void *));
930 hashtable_add_unique(ua_chan->ctx, &ua_ctx->node);
931
932 ret = create_ust_channel_context(ua_chan, ua_ctx, app);
933 if (ret < 0) {
934 goto error;
935 }
936
937error:
938 return ret;
939}
940
941/*
942 * Create an UST context and enable it for the event on the tracer.
943 */
944static
945int create_ust_app_event_context(struct ust_app_session *ua_sess,
946 struct ust_app_event *ua_event, struct lttng_ust_context *uctx,
947 struct ust_app *app)
948{
949 int ret = 0;
950 struct cds_lfht_iter iter;
951 struct cds_lfht_node *node;
952 struct ust_app_ctx *ua_ctx;
953
954 DBG2("UST app adding context to event %s", ua_event->name);
955
956 node = hashtable_lookup(ua_event->ctx, (void *)((unsigned long)uctx->ctx),
957 sizeof(void *), &iter);
958 if (node != NULL) {
959 ret = -EEXIST;
960 goto error;
961 }
962
963 ua_ctx = alloc_ust_app_ctx(uctx);
964 if (ua_ctx == NULL) {
965 /* malloc failed */
966 ret = -1;
967 goto error;
968 }
969
970 hashtable_node_init(&ua_ctx->node,
971 (void *)((unsigned long) ua_ctx->ctx.ctx), sizeof(void *));
972 hashtable_add_unique(ua_event->ctx, &ua_ctx->node);
973
974 ret = create_ust_event_context(ua_event, ua_ctx, app);
975 if (ret < 0) {
976 goto error;
977 }
978
979error:
980 return ret;
981}
982
edb67388
DG
983/*
984 * Enable on the tracer side a ust app event for the session and channel.
985 */
986static
987int enable_ust_app_event(struct ust_app_session *ua_sess,
35a9059d 988 struct ust_app_event *ua_event, struct ust_app *app)
edb67388
DG
989{
990 int ret;
991
992 ret = enable_ust_event(app, ua_sess, ua_event);
993 if (ret < 0) {
994 goto error;
995 }
996
997 ua_event->enabled = 1;
998
999error:
1000 return ret;
1001}
1002
9730260e
DG
1003/*
1004 * Disable on the tracer side a ust app event for the session and channel.
1005 */
1006static int disable_ust_app_event(struct ust_app_session *ua_sess,
7f79d3a1 1007 struct ust_app_event *ua_event, struct ust_app *app)
9730260e
DG
1008{
1009 int ret;
1010
1011 ret = disable_ust_event(app, ua_sess, ua_event);
1012 if (ret < 0) {
1013 goto error;
1014 }
1015
1016 ua_event->enabled = 0;
1017
1018error:
1019 return ret;
1020}
1021
78f0bacd
DG
1022/*
1023 * Lookup ust app channel for session and disable it on the tracer side.
1024 */
8535a6d9
DG
1025static
1026int disable_ust_app_channel(struct ust_app_session *ua_sess,
1027 struct ust_app_channel *ua_chan, struct ust_app *app)
78f0bacd 1028{
8535a6d9 1029 int ret;
78f0bacd
DG
1030
1031 ret = disable_ust_channel(app, ua_sess, ua_chan);
1032 if (ret < 0) {
1033 goto error;
1034 }
1035
8535a6d9
DG
1036 ua_chan->enabled = 0;
1037
78f0bacd
DG
1038error:
1039 return ret;
1040}
1041
1042/*
1043 * Lookup ust app channel for session and enable it on the tracer side.
1044 */
1045static int enable_ust_app_channel(struct ust_app_session *ua_sess,
1046 struct ltt_ust_channel *uchan, struct ust_app *app)
1047{
1048 int ret = 0;
1049 struct cds_lfht_iter iter;
1050 struct cds_lfht_node *ua_chan_node;
1051 struct ust_app_channel *ua_chan;
1052
1053 ua_chan_node = hashtable_lookup(ua_sess->channels,
1054 (void *)uchan->name, strlen(uchan->name), &iter);
1055 if (ua_chan_node == NULL) {
a991f516
MD
1056 DBG2("Unable to find channel %s in ust session id %u",
1057 uchan->name, ua_sess->id);
78f0bacd
DG
1058 goto error;
1059 }
1060
1061 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1062
1063 ret = enable_ust_channel(app, ua_sess, ua_chan);
1064 if (ret < 0) {
1065 goto error;
1066 }
1067
1068error:
1069 return ret;
1070}
1071
284d8f55 1072/*
5b4a0ec0 1073 * Create UST app channel and create it on the tracer.
284d8f55 1074 */
5b4a0ec0
DG
1075static struct ust_app_channel *create_ust_app_channel(
1076 struct ust_app_session *ua_sess, struct ltt_ust_channel *uchan,
1077 struct ust_app *app)
1078{
1079 int ret = 0;
1080 struct cds_lfht_iter iter;
1081 struct cds_lfht_node *ua_chan_node;
1082 struct ust_app_channel *ua_chan;
1083
1084 /* Lookup channel in the ust app session */
1085 ua_chan_node = hashtable_lookup(ua_sess->channels,
1086 (void *)uchan->name, strlen(uchan->name), &iter);
1087 if (ua_chan_node == NULL) {
a991f516
MD
1088 DBG2("Unable to find channel %s in ust session id %u",
1089 uchan->name, ua_sess->id);
5b4a0ec0
DG
1090 ua_chan = alloc_ust_app_channel(uchan->name, &uchan->attr);
1091 if (ua_chan == NULL) {
1092 goto error;
1093 }
1094 shadow_copy_channel(ua_chan, uchan);
1095
1096 hashtable_add_unique(ua_sess->channels, &ua_chan->node);
1097 } else {
1098 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1099 }
1100
1101 ret = create_ust_channel(app, ua_sess, ua_chan);
1102 if (ret < 0) {
1103 goto error;
1104 }
1105
1106 return ua_chan;
1107
1108error:
1109 return NULL;
1110}
1111
1112/*
1113 * Create UST app event and create it on the tracer side.
1114 */
edb67388
DG
1115static
1116int create_ust_app_event(struct ust_app_session *ua_sess,
1117 struct ust_app_channel *ua_chan, struct ltt_ust_event *uevent,
1118 struct ust_app *app)
284d8f55 1119{
edb67388 1120 int ret = 0;
5b4a0ec0
DG
1121 struct cds_lfht_iter iter;
1122 struct cds_lfht_node *ua_event_node;
1123 struct ust_app_event *ua_event;
284d8f55 1124
5b4a0ec0
DG
1125 /* Get event node */
1126 ua_event_node = hashtable_lookup(ua_chan->events,
1127 (void *)uevent->attr.name, strlen(uevent->attr.name), &iter);
edb67388
DG
1128 if (ua_event_node != NULL) {
1129 ERR("UST app event %s already exist. Stopping creation.",
1130 uevent->attr.name);
1131 goto end;
1132 }
5b4a0ec0 1133
edb67388
DG
1134 /* Does not exist so create one */
1135 ua_event = alloc_ust_app_event(uevent->attr.name, &uevent->attr);
1136 if (ua_event == NULL) {
1137 /* Only malloc can failed so something is really wrong */
1138 ret = -ENOMEM;
1139 goto error;
5b4a0ec0 1140 }
edb67388 1141 shadow_copy_event(ua_event, uevent);
5b4a0ec0 1142
edb67388 1143 /* Create it on the tracer side */
5b4a0ec0 1144 ret = create_ust_event(app, ua_sess, ua_chan, ua_event);
284d8f55 1145 if (ret < 0) {
e5abf1bf 1146 rcu_read_lock();
edb67388 1147 delete_ust_app_event(app->key.sock, ua_event);
e5abf1bf 1148 rcu_read_unlock();
284d8f55
DG
1149 goto error;
1150 }
1151
8535a6d9
DG
1152 ua_event->enabled = 1;
1153
edb67388 1154 hashtable_add_unique(ua_chan->events, &ua_event->node);
284d8f55 1155
7f79d3a1
DG
1156 DBG2("UST app create event %s for PID %d completed",
1157 ua_event->name, app->key.pid);
1158
edb67388 1159end:
5b4a0ec0 1160error:
edb67388 1161 return ret;
5b4a0ec0
DG
1162}
1163
1164/*
1165 * Create UST metadata and open it on the tracer side.
1166 */
1167static int create_ust_app_metadata(struct ust_app_session *ua_sess,
1168 char *pathname, struct ust_app *app)
1169{
1170 int ret = 0;
1171
1172 if (ua_sess->metadata == NULL) {
1173 /* Allocate UST metadata */
1174 ua_sess->metadata = trace_ust_create_metadata(pathname);
1175 if (ua_sess->metadata == NULL) {
1176 ERR("UST app session %d creating metadata failed",
1177 ua_sess->handle);
1178 goto error;
1179 }
1180
1181 ret = open_ust_metadata(app, ua_sess);
1182 if (ret < 0) {
1183 goto error;
1184 }
1185
1186 DBG2("UST metadata opened for app pid %d", app->key.pid);
1187 }
1188
1189 /* Open UST metadata stream */
1190 if (ua_sess->metadata->stream_obj == NULL) {
1191 ret = create_ust_stream(app, ua_sess);
1192 if (ret < 0) {
1193 goto error;
1194 }
1195
67f747d8
MD
1196 ret = mkdir_run_as(ua_sess->path, S_IRWXU | S_IRWXG,
1197 ua_sess->uid, ua_sess->gid);
5b4a0ec0
DG
1198 if (ret < 0) {
1199 PERROR("mkdir UST metadata");
1200 goto error;
1201 }
1202
477d7741
MD
1203 ret = snprintf(ua_sess->metadata->pathname, PATH_MAX,
1204 "%s/metadata", ua_sess->path);
5b4a0ec0
DG
1205 if (ret < 0) {
1206 PERROR("asprintf UST create stream");
1207 goto error;
1208 }
1209
1210 DBG2("UST metadata stream object created for app pid %d",
1211 app->key.pid);
1212 } else {
1213 ERR("Attempting to create stream without metadata opened");
1214 goto error;
1215 }
1216
1217 return 0;
1218
1219error:
1220 return -1;
1221}
1222
1223/*
1224 * Return pointer to traceable apps list.
1225 */
1226struct cds_lfht *ust_app_get_ht(void)
1227{
1228 return ust_app_ht;
1229}
1230
1231/*
1232 * Return ust app pointer or NULL if not found.
1233 */
1234struct ust_app *ust_app_find_by_pid(pid_t pid)
1235{
1236 struct cds_lfht_node *node;
1237 struct cds_lfht_iter iter;
1238
1239 rcu_read_lock();
1240 node = hashtable_lookup(ust_app_ht,
1241 (void *)((unsigned long) pid), sizeof(void *), &iter);
1242 if (node == NULL) {
1243 DBG2("UST app no found with pid %d", pid);
1244 goto error;
1245 }
1246 rcu_read_unlock();
1247
1248 DBG2("Found UST app by pid %d", pid);
1249
1250 return caa_container_of(node, struct ust_app, node);
1251
1252error:
1253 rcu_read_unlock();
1254 return NULL;
1255}
1256
1257/*
1258 * Using pid and uid (of the app), allocate a new ust_app struct and
1259 * add it to the global traceable app list.
1260 *
0df502fd
MD
1261 * On success, return 0, else return malloc -ENOMEM, or -EINVAL if app
1262 * bitness is not supported.
5b4a0ec0
DG
1263 */
1264int ust_app_register(struct ust_register_msg *msg, int sock)
1265{
1266 struct ust_app *lta;
1267
7753dea8
MD
1268 if ((msg->bits_per_long == 64 && ust_consumerd64_fd == -EINVAL)
1269 || (msg->bits_per_long == 32 && ust_consumerd32_fd == -EINVAL)) {
f943b0fb 1270 ERR("Registration failed: application \"%s\" (pid: %d) has "
7753dea8
MD
1271 "%d-bit long, but no consumerd for this long size is available.\n",
1272 msg->name, msg->pid, msg->bits_per_long);
88ff5b7f 1273 close(sock);
0df502fd
MD
1274 return -EINVAL;
1275 }
5b4a0ec0
DG
1276 lta = zmalloc(sizeof(struct ust_app));
1277 if (lta == NULL) {
1278 PERROR("malloc");
1279 return -ENOMEM;
1280 }
1281
1282 lta->ppid = msg->ppid;
1283 lta->uid = msg->uid;
1284 lta->gid = msg->gid;
7753dea8 1285 lta->bits_per_long = msg->bits_per_long;
5b4a0ec0
DG
1286 lta->v_major = msg->major;
1287 lta->v_minor = msg->minor;
1288 strncpy(lta->name, msg->name, sizeof(lta->name));
1289 lta->name[16] = '\0';
1290 lta->sessions = hashtable_new(0);
1291
1292 /* Set key map */
1293 lta->key.pid = msg->pid;
1294 hashtable_node_init(&lta->node, (void *)((unsigned long)lta->key.pid),
1295 sizeof(void *));
1296 lta->key.sock = sock;
1297 hashtable_node_init(&lta->key.node, (void *)((unsigned long)lta->key.sock),
1298 sizeof(void *));
1299
1300 rcu_read_lock();
1301 hashtable_add_unique(ust_app_sock_key_map, &lta->key.node);
1302 hashtable_add_unique(ust_app_ht, &lta->node);
1303 rcu_read_unlock();
1304
1305 DBG("App registered with pid:%d ppid:%d uid:%d gid:%d sock:%d name:%s"
1306 " (version %d.%d)", lta->key.pid, lta->ppid, lta->uid, lta->gid,
1307 lta->key.sock, lta->name, lta->v_major, lta->v_minor);
1308
1309 return 0;
1310}
1311
1312/*
1313 * Unregister app by removing it from the global traceable app list and freeing
1314 * the data struct.
1315 *
1316 * The socket is already closed at this point so no close to sock.
1317 */
1318void ust_app_unregister(int sock)
1319{
1320 struct ust_app *lta;
1321 struct cds_lfht_node *node;
1322 struct cds_lfht_iter iter;
525b0740 1323 int ret;
5b4a0ec0
DG
1324
1325 rcu_read_lock();
1326 lta = find_app_by_sock(sock);
1327 if (lta == NULL) {
1328 ERR("Unregister app sock %d not found!", sock);
1329 goto error;
1330 }
1331
1332 DBG("PID %d unregistering with sock %d", lta->key.pid, sock);
1333
1334 /* Get the node reference for a call_rcu */
1335 node = hashtable_lookup(ust_app_ht,
1336 (void *)((unsigned long) lta->key.pid), sizeof(void *), &iter);
1337 if (node == NULL) {
1338 ERR("Unable to find app sock %d by pid %d", sock, lta->key.pid);
1339 goto error;
1340 }
284d8f55 1341
525b0740
MD
1342 ret = hashtable_del(ust_app_ht, &iter);
1343 assert(!ret);
5b4a0ec0 1344 call_rcu(&node->head, delete_ust_app_rcu);
284d8f55 1345error:
5b4a0ec0
DG
1346 rcu_read_unlock();
1347 return;
284d8f55
DG
1348}
1349
1350/*
5b4a0ec0 1351 * Return traceable_app_count
284d8f55 1352 */
5b4a0ec0 1353unsigned long ust_app_list_count(void)
284d8f55 1354{
5b4a0ec0 1355 unsigned long count;
284d8f55 1356
5b4a0ec0
DG
1357 rcu_read_lock();
1358 count = hashtable_get_count(ust_app_ht);
1359 rcu_read_unlock();
284d8f55 1360
5b4a0ec0 1361 return count;
284d8f55
DG
1362}
1363
5b4a0ec0
DG
1364/*
1365 * Fill events array with all events name of all registered apps.
1366 */
1367int ust_app_list_events(struct lttng_event **events)
421cb601 1368{
5b4a0ec0
DG
1369 int ret, handle;
1370 size_t nbmem, count = 0;
421cb601 1371 struct cds_lfht_iter iter;
5b4a0ec0
DG
1372 struct ust_app *app;
1373 struct lttng_event *tmp;
421cb601 1374
5b4a0ec0
DG
1375 nbmem = UST_APP_EVENT_LIST_SIZE;
1376 tmp = zmalloc(nbmem * sizeof(struct lttng_event));
1377 if (tmp == NULL) {
1378 PERROR("zmalloc ust app events");
1379 ret = -ENOMEM;
421cb601
DG
1380 goto error;
1381 }
1382
5b4a0ec0 1383 rcu_read_lock();
421cb601 1384
5b4a0ec0 1385 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
90eaa0d2 1386 struct lttng_ust_tracepoint_iter uiter;
ac3bd9c0 1387
5b4a0ec0
DG
1388 handle = ustctl_tracepoint_list(app->key.sock);
1389 if (handle < 0) {
1390 ERR("UST app list events getting handle failed for app pid %d",
1391 app->key.pid);
1392 continue;
1393 }
421cb601 1394
5b4a0ec0 1395 while ((ret = ustctl_tracepoint_list_get(app->key.sock, handle,
90eaa0d2 1396 &uiter)) != -ENOENT) {
815564d8
MD
1397 if (count >= nbmem) {
1398 DBG2("Reallocating event list from %zu to %zu entries", nbmem,
1399 2 * nbmem);
1400 nbmem *= 2;
2f221590 1401 tmp = realloc(tmp, nbmem * sizeof(struct lttng_event));
5b4a0ec0
DG
1402 if (tmp == NULL) {
1403 PERROR("realloc ust app events");
1404 ret = -ENOMEM;
1405 goto rcu_error;
1406 }
1407 }
90eaa0d2
DG
1408 memcpy(tmp[count].name, uiter.name, LTTNG_UST_SYM_NAME_LEN);
1409 memcpy(tmp[count].loglevel, uiter.loglevel, LTTNG_UST_SYM_NAME_LEN);
1410 tmp[count].loglevel_value = uiter.loglevel_value;
5b4a0ec0
DG
1411 tmp[count].type = LTTNG_UST_TRACEPOINT;
1412 tmp[count].pid = app->key.pid;
1413 tmp[count].enabled = -1;
1414 count++;
421cb601 1415 }
421cb601
DG
1416 }
1417
5b4a0ec0
DG
1418 ret = count;
1419 *events = tmp;
421cb601 1420
5b4a0ec0 1421 DBG2("UST app list events done (%zu events)", count);
421cb601 1422
5b4a0ec0
DG
1423rcu_error:
1424 rcu_read_unlock();
421cb601 1425error:
5b4a0ec0 1426 return ret;
421cb601
DG
1427}
1428
5b4a0ec0
DG
1429/*
1430 * Free and clean all traceable apps of the global list.
1431 */
1432void ust_app_clean_list(void)
421cb601 1433{
5b4a0ec0 1434 int ret;
5b4a0ec0
DG
1435 struct cds_lfht_iter iter;
1436 struct ust_app *app;
421cb601 1437
5b4a0ec0 1438 DBG2("UST app cleaning registered apps hash table");
421cb601 1439
5b4a0ec0 1440 rcu_read_lock();
421cb601 1441
778ca3dd 1442 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
5b4a0ec0 1443 ret = hashtable_del(ust_app_ht, &iter);
525b0740 1444 assert(!ret);
0d5d001d 1445 call_rcu(&iter.node->head, delete_ust_app_rcu);
421cb601
DG
1446 }
1447
5b4a0ec0
DG
1448 hashtable_destroy(ust_app_ht);
1449 hashtable_destroy(ust_app_sock_key_map);
421cb601 1450
5b4a0ec0
DG
1451 rcu_read_unlock();
1452}
1453
1454/*
1455 * Init UST app hash table.
1456 */
1457void ust_app_ht_alloc(void)
1458{
1459 ust_app_ht = hashtable_new(0);
1460 ust_app_sock_key_map = hashtable_new(0);
421cb601
DG
1461}
1462
78f0bacd
DG
1463/*
1464 * For a specific UST session, disable the channel for all registered apps.
1465 */
35a9059d 1466int ust_app_disable_channel_glb(struct ltt_ust_session *usess,
78f0bacd
DG
1467 struct ltt_ust_channel *uchan)
1468{
1469 int ret = 0;
1470 struct cds_lfht_iter iter;
8535a6d9 1471 struct cds_lfht_node *ua_chan_node;
78f0bacd
DG
1472 struct ust_app *app;
1473 struct ust_app_session *ua_sess;
8535a6d9 1474 struct ust_app_channel *ua_chan;
78f0bacd
DG
1475
1476 if (usess == NULL || uchan == NULL) {
1477 ERR("Disabling UST global channel with NULL values");
1478 ret = -1;
1479 goto error;
1480 }
1481
a991f516
MD
1482 DBG2("UST app disabling channel %s from global domain for session id %d",
1483 uchan->name, usess->id);
78f0bacd
DG
1484
1485 rcu_read_lock();
1486
1487 /* For every registered applications */
1488 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
90eaa0d2
DG
1489 struct cds_lfht_iter uiter;
1490
78f0bacd
DG
1491 ua_sess = lookup_session_by_app(usess, app);
1492 if (ua_sess == NULL) {
1493 continue;
1494 }
1495
8535a6d9
DG
1496 /* Get channel */
1497 ua_chan_node = hashtable_lookup(ua_sess->channels,
90eaa0d2 1498 (void *)uchan->name, strlen(uchan->name), &uiter);
8535a6d9
DG
1499 /* If the session if found for the app, the channel must be there */
1500 assert(ua_chan_node);
1501
1502 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1503 /* The channel must not be already disabled */
1504 assert(ua_chan->enabled == 1);
1505
1506 /* Disable channel onto application */
1507 ret = disable_ust_app_channel(ua_sess, ua_chan, app);
78f0bacd
DG
1508 if (ret < 0) {
1509 /* XXX: We might want to report this error at some point... */
1510 continue;
1511 }
1512 }
1513
1514 rcu_read_unlock();
1515
1516error:
1517 return ret;
1518}
1519
1520/*
1521 * For a specific UST session, enable the channel for all registered apps.
1522 */
35a9059d 1523int ust_app_enable_channel_glb(struct ltt_ust_session *usess,
78f0bacd
DG
1524 struct ltt_ust_channel *uchan)
1525{
1526 int ret = 0;
1527 struct cds_lfht_iter iter;
1528 struct ust_app *app;
1529 struct ust_app_session *ua_sess;
1530
1531 if (usess == NULL || uchan == NULL) {
1532 ERR("Adding UST global channel to NULL values");
1533 ret = -1;
1534 goto error;
1535 }
1536
a991f516
MD
1537 DBG2("UST app enabling channel %s to global domain for session id %d",
1538 uchan->name, usess->id);
78f0bacd
DG
1539
1540 rcu_read_lock();
1541
1542 /* For every registered applications */
1543 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
1544 ua_sess = lookup_session_by_app(usess, app);
1545 if (ua_sess == NULL) {
1546 continue;
1547 }
1548
1549 /* Enable channel onto application */
1550 ret = enable_ust_app_channel(ua_sess, uchan, app);
1551 if (ret < 0) {
1552 /* XXX: We might want to report this error at some point... */
1553 continue;
1554 }
1555 }
1556
1557 rcu_read_unlock();
1558
1559error:
1560 return ret;
1561}
1562
b0a40d28
DG
1563/*
1564 * Disable an event in a channel and for a specific session.
1565 */
35a9059d
DG
1566int ust_app_disable_event_glb(struct ltt_ust_session *usess,
1567 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent)
b0a40d28
DG
1568{
1569 int ret = 0;
90eaa0d2 1570 struct cds_lfht_iter iter;
b0a40d28
DG
1571 struct cds_lfht_node *ua_chan_node, *ua_event_node;
1572 struct ust_app *app;
1573 struct ust_app_session *ua_sess;
1574 struct ust_app_channel *ua_chan;
1575 struct ust_app_event *ua_event;
1576
1577 DBG("UST app disabling event %s for all apps in channel "
a991f516 1578 "%s for session id %d", uevent->attr.name, uchan->name, usess->id);
b0a40d28
DG
1579
1580 rcu_read_lock();
1581
1582 /* For all registered applications */
1583 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
90eaa0d2
DG
1584 struct cds_lfht_iter uiter;
1585
b0a40d28
DG
1586 ua_sess = lookup_session_by_app(usess, app);
1587 if (ua_sess == NULL) {
1588 /* Next app */
1589 continue;
1590 }
1591
1592 /* Lookup channel in the ust app session */
1593 ua_chan_node = hashtable_lookup(ua_sess->channels,
1594 (void *)uchan->name, strlen(uchan->name), &uiter);
1595 if (ua_chan_node == NULL) {
a991f516
MD
1596 DBG2("Channel %s not found in session id %d for app pid %d."
1597 "Skipping", uchan->name, usess->id, app->key.pid);
b0a40d28
DG
1598 continue;
1599 }
1600 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1601
1602 ua_event_node = hashtable_lookup(ua_chan->events,
35a9059d 1603 (void *)uevent->attr.name, strlen(uevent->attr.name), &uiter);
b0a40d28
DG
1604 if (ua_event_node == NULL) {
1605 DBG2("Event %s not found in channel %s for app pid %d."
35a9059d 1606 "Skipping", uevent->attr.name, uchan->name, app->key.pid);
b0a40d28
DG
1607 continue;
1608 }
1609 ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
1610
7f79d3a1 1611 ret = disable_ust_app_event(ua_sess, ua_event, app);
b0a40d28
DG
1612 if (ret < 0) {
1613 /* XXX: Report error someday... */
1614 continue;
1615 }
1616 }
1617
1618 rcu_read_unlock();
1619
1620 return ret;
1621}
1622
9730260e 1623/*
edb67388 1624 * For a specific UST session and UST channel, the event for all
9730260e
DG
1625 * registered apps.
1626 */
35a9059d 1627int ust_app_disable_all_event_glb(struct ltt_ust_session *usess,
9730260e
DG
1628 struct ltt_ust_channel *uchan)
1629{
1630 int ret = 0;
90eaa0d2 1631 struct cds_lfht_iter iter;
9730260e
DG
1632 struct cds_lfht_node *ua_chan_node;
1633 struct ust_app *app;
1634 struct ust_app_session *ua_sess;
1635 struct ust_app_channel *ua_chan;
1636 struct ust_app_event *ua_event;
1637
1638 DBG("UST app disabling all event for all apps in channel "
a991f516 1639 "%s for session id %d", uchan->name, usess->id);
9730260e
DG
1640
1641 rcu_read_lock();
1642
1643 /* For all registered applications */
1644 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
90eaa0d2
DG
1645 struct cds_lfht_iter uiter;
1646
9730260e 1647 ua_sess = lookup_session_by_app(usess, app);
edb67388
DG
1648 /* If ua_sess is NULL, there is a code flow error */
1649 assert(ua_sess);
9730260e
DG
1650
1651 /* Lookup channel in the ust app session */
edb67388
DG
1652 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
1653 strlen(uchan->name), &uiter);
1654 /* If the channel is not found, there is a code flow error */
1655 assert(ua_chan_node);
1656
9730260e
DG
1657 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1658
1659 /* Disable each events of channel */
1660 cds_lfht_for_each_entry(ua_chan->events, &uiter, ua_event, node) {
7f79d3a1 1661 ret = disable_ust_app_event(ua_sess, ua_event, app);
9730260e
DG
1662 if (ret < 0) {
1663 /* XXX: Report error someday... */
1664 continue;
1665 }
1666 }
1667 }
1668
1669 rcu_read_unlock();
1670
1671 return ret;
1672}
1673
421cb601 1674/*
5b4a0ec0 1675 * For a specific UST session, create the channel for all registered apps.
421cb601 1676 */
35a9059d 1677int ust_app_create_channel_glb(struct ltt_ust_session *usess,
48842b30
DG
1678 struct ltt_ust_channel *uchan)
1679{
1680 int ret = 0;
1681 struct cds_lfht_iter iter;
48842b30
DG
1682 struct ust_app *app;
1683 struct ust_app_session *ua_sess;
1684 struct ust_app_channel *ua_chan;
1685
421cb601
DG
1686 if (usess == NULL || uchan == NULL) {
1687 ERR("Adding UST global channel to NULL values");
1688 ret = -1;
1689 goto error;
1690 }
1691
a991f516
MD
1692 DBG2("UST app adding channel %s to global domain for session id %d",
1693 uchan->name, usess->id);
48842b30
DG
1694
1695 rcu_read_lock();
421cb601 1696
5b4a0ec0
DG
1697 /* For every registered applications */
1698 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
edb67388
DG
1699 /*
1700 * Create session on the tracer side and add it to app session HT. Note
1701 * that if session exist, it will simply return a pointer to the ust
1702 * app session.
1703 */
421cb601 1704 ua_sess = create_ust_app_session(usess, app);
509cbaf8 1705 if (ua_sess == NULL) {
5b4a0ec0 1706 continue;
48842b30
DG
1707 }
1708
421cb601
DG
1709 /* Create channel onto application */
1710 ua_chan = create_ust_app_channel(ua_sess, uchan, app);
1711 if (ua_chan == NULL) {
5b4a0ec0 1712 continue;
48842b30 1713 }
48842b30 1714 }
5b4a0ec0 1715
48842b30
DG
1716 rcu_read_unlock();
1717
421cb601 1718error:
48842b30
DG
1719 return ret;
1720}
1721
5b4a0ec0 1722/*
edb67388 1723 * Enable event for a specific session and channel on the tracer.
5b4a0ec0 1724 */
35a9059d 1725int ust_app_enable_event_glb(struct ltt_ust_session *usess,
48842b30
DG
1726 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent)
1727{
1728 int ret = 0;
90eaa0d2 1729 struct cds_lfht_iter iter;
35a9059d 1730 struct cds_lfht_node *ua_chan_node, *ua_event_node;
48842b30
DG
1731 struct ust_app *app;
1732 struct ust_app_session *ua_sess;
1733 struct ust_app_channel *ua_chan;
1734 struct ust_app_event *ua_event;
48842b30 1735
a991f516
MD
1736 DBG("UST app enabling event %s for all apps for session id %d",
1737 uevent->attr.name, usess->id);
48842b30 1738
edb67388
DG
1739 /*
1740 * NOTE: At this point, this function is called only if the session and
1741 * channel passed are already created for all apps. and enabled on the
1742 * tracer also.
1743 */
1744
48842b30 1745 rcu_read_lock();
421cb601
DG
1746
1747 /* For all registered applications */
5b4a0ec0 1748 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
90eaa0d2
DG
1749 struct cds_lfht_iter uiter;
1750
edb67388
DG
1751 ua_sess = lookup_session_by_app(usess, app);
1752 /* If ua_sess is NULL, there is a code flow error */
1753 assert(ua_sess);
ba767faf 1754
edb67388
DG
1755 /* Lookup channel in the ust app session */
1756 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
1757 strlen(uchan->name), &uiter);
1758 /* If the channel is not found, there is a code flow error */
1759 assert(ua_chan_node);
1760
1761 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1762
7f79d3a1 1763 ua_event_node = hashtable_lookup(ua_chan->events,
35a9059d
DG
1764 (void*)uevent->attr.name, strlen(uevent->attr.name), &uiter);
1765 if (ua_event_node == NULL) {
7f79d3a1
DG
1766 DBG3("UST app enable event %s not found for app PID %d."
1767 "Skipping app", uevent->attr.name, app->key.pid);
35a9059d
DG
1768 continue;
1769 }
1770 ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
1771
1772 ret = enable_ust_app_event(ua_sess, ua_event, app);
1773 if (ret < 0) {
7f79d3a1 1774 goto error;
48842b30 1775 }
edb67388
DG
1776 }
1777
7f79d3a1 1778error:
edb67388 1779 rcu_read_unlock();
edb67388
DG
1780 return ret;
1781}
1782
1783/*
1784 * For a specific existing UST session and UST channel, creates the event for
1785 * all registered apps.
1786 */
35a9059d 1787int ust_app_create_event_glb(struct ltt_ust_session *usess,
edb67388
DG
1788 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent)
1789{
1790 int ret = 0;
90eaa0d2 1791 struct cds_lfht_iter iter;
edb67388
DG
1792 struct cds_lfht_node *ua_chan_node;
1793 struct ust_app *app;
1794 struct ust_app_session *ua_sess;
1795 struct ust_app_channel *ua_chan;
1796
a991f516
MD
1797 DBG("UST app creating event %s for all apps for session id %d",
1798 uevent->attr.name, usess->id);
edb67388
DG
1799
1800 /*
1801 * NOTE: At this point, this function is called only if the session and
1802 * channel passed are already created for all apps. and enabled on the
1803 * tracer also.
1804 */
1805
1806 rcu_read_lock();
1807
1808 /* For all registered applications */
1809 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
90eaa0d2
DG
1810 struct cds_lfht_iter uiter;
1811
edb67388
DG
1812 ua_sess = lookup_session_by_app(usess, app);
1813 /* If ua_sess is NULL, there is a code flow error */
1814 assert(ua_sess);
48842b30
DG
1815
1816 /* Lookup channel in the ust app session */
edb67388
DG
1817 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
1818 strlen(uchan->name), &uiter);
1819 /* If the channel is not found, there is a code flow error */
1820 assert(ua_chan_node);
1821
48842b30
DG
1822 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
1823
edb67388
DG
1824 ret = create_ust_app_event(ua_sess, ua_chan, uevent, app);
1825 if (ret < 0) {
5b4a0ec0 1826 continue;
48842b30 1827 }
48842b30 1828 }
5b4a0ec0 1829
48842b30
DG
1830 rcu_read_unlock();
1831
1832 return ret;
1833}
1834
5b4a0ec0
DG
1835/*
1836 * Start tracing for a specific UST session and app.
1837 */
421cb601 1838int ust_app_start_trace(struct ltt_ust_session *usess, struct ust_app *app)
48842b30
DG
1839{
1840 int ret = 0;
1841 struct cds_lfht_iter iter;
48842b30
DG
1842 struct ust_app_session *ua_sess;
1843 struct ust_app_channel *ua_chan;
5b4a0ec0 1844 struct ltt_ust_stream *ustream;
7753dea8 1845 int consumerd_fd;
48842b30 1846
421cb601 1847 DBG("Starting tracing for ust app pid %d", app->key.pid);
5cf5d0e7 1848
509cbaf8
MD
1849 rcu_read_lock();
1850
421cb601
DG
1851 ua_sess = lookup_session_by_app(usess, app);
1852 if (ua_sess == NULL) {
509cbaf8 1853 goto error_rcu_unlock;
421cb601 1854 }
48842b30 1855
aea829b3
DG
1856 /* Upon restart, we skip the setup, already done */
1857 if (ua_sess->started) {
8be98f9a 1858 goto skip_setup;
aea829b3 1859 }
8be98f9a 1860
421cb601
DG
1861 ret = create_ust_app_metadata(ua_sess, usess->pathname, app);
1862 if (ret < 0) {
509cbaf8 1863 goto error_rcu_unlock;
421cb601 1864 }
48842b30 1865
421cb601 1866 /* For each channel */
5b4a0ec0 1867 cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) {
421cb601
DG
1868 /* Create all streams */
1869 while (1) {
5b4a0ec0 1870 /* Create UST stream */
421cb601
DG
1871 ustream = zmalloc(sizeof(*ustream));
1872 if (ustream == NULL) {
1873 PERROR("zmalloc ust stream");
509cbaf8 1874 goto error_rcu_unlock;
421cb601 1875 }
48842b30 1876
421cb601
DG
1877 ret = ustctl_create_stream(app->key.sock, ua_chan->obj,
1878 &ustream->obj);
48842b30 1879 if (ret < 0) {
421cb601
DG
1880 /* Got all streams */
1881 break;
48842b30 1882 }
421cb601 1883 ustream->handle = ustream->obj->handle;
48842b30 1884
421cb601
DG
1885 /* Order is important */
1886 cds_list_add_tail(&ustream->list, &ua_chan->streams.head);
477d7741
MD
1887 ret = snprintf(ustream->pathname, PATH_MAX, "%s/%s_%u",
1888 ua_sess->path, ua_chan->name,
1889 ua_chan->streams.count++);
aba8e916
DG
1890 if (ret < 0) {
1891 PERROR("asprintf UST create stream");
421cb601 1892 continue;
aba8e916 1893 }
421cb601
DG
1894 DBG2("UST stream %d ready at %s", ua_chan->streams.count,
1895 ustream->pathname);
1896 }
421cb601 1897 }
aba8e916 1898
7753dea8
MD
1899 switch (app->bits_per_long) {
1900 case 64:
1901 consumerd_fd = ust_consumerd64_fd;
1902 break;
1903 case 32:
1904 consumerd_fd = ust_consumerd32_fd;
1905 break;
1906 default:
1907 ret = -EINVAL;
1908 goto error_rcu_unlock;
1909 }
aea829b3 1910
421cb601 1911 /* Setup UST consumer socket and send fds to it */
7753dea8 1912 ret = ust_consumer_send_session(consumerd_fd, ua_sess);
421cb601 1913 if (ret < 0) {
509cbaf8 1914 goto error_rcu_unlock;
421cb601 1915 }
8be98f9a 1916 ua_sess->started = 1;
48842b30 1917
8be98f9a 1918skip_setup:
421cb601
DG
1919 /* This start the UST tracing */
1920 ret = ustctl_start_session(app->key.sock, ua_sess->handle);
1921 if (ret < 0) {
1922 ERR("Error starting tracing for app pid: %d", app->key.pid);
509cbaf8 1923 goto error_rcu_unlock;
421cb601 1924 }
5b4a0ec0 1925
509cbaf8 1926 rcu_read_unlock();
48842b30 1927
421cb601
DG
1928 /* Quiescent wait after starting trace */
1929 ustctl_wait_quiescent(app->key.sock);
48842b30 1930
421cb601 1931 return 0;
48842b30 1932
509cbaf8
MD
1933error_rcu_unlock:
1934 rcu_read_unlock();
421cb601
DG
1935 return -1;
1936}
48842b30 1937
8be98f9a
MD
1938/*
1939 * Stop tracing for a specific UST session and app.
1940 */
1941int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app)
1942{
1943 int ret = 0;
6d3686da 1944 struct cds_lfht_iter iter;
8be98f9a 1945 struct ust_app_session *ua_sess;
6d3686da 1946 struct ust_app_channel *ua_chan;
8be98f9a
MD
1947
1948 DBG("Stopping tracing for ust app pid %d", app->key.pid);
1949
1950 rcu_read_lock();
1951
1952 ua_sess = lookup_session_by_app(usess, app);
1953 if (ua_sess == NULL) {
1954 /* Only malloc can failed so something is really wrong */
1955 goto error_rcu_unlock;
1956 }
1957
9d6c7d3f
DG
1958 /* This inhibits UST tracing */
1959 ret = ustctl_stop_session(app->key.sock, ua_sess->handle);
1960 if (ret < 0) {
1961 ERR("Error stopping tracing for app pid: %d", app->key.pid);
1962 goto error_rcu_unlock;
1963 }
1964
1965 /* Quiescent wait after stopping trace */
1966 ustctl_wait_quiescent(app->key.sock);
1967
1968 /* Flushing buffers */
6d3686da
DG
1969 cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) {
1970 ret = ustctl_sock_flush_buffer(app->key.sock, ua_chan->obj);
8be98f9a 1971 if (ret < 0) {
6d3686da
DG
1972 ERR("UST app PID %d channel %s flush failed",
1973 app->key.pid, ua_chan->name);
1974 ERR("Ended with ret %d", ret);
1975 /* Continuing flushing all buffers */
1976 continue;
8be98f9a
MD
1977 }
1978 }
8be98f9a 1979
90d97d10
DG
1980 /* Flush all buffers before stopping */
1981 ret = ustctl_sock_flush_buffer(app->key.sock, ua_sess->metadata->obj);
1982 if (ret < 0) {
1983 ERR("UST app PID %d metadata flush failed", app->key.pid);
1984 ERR("Ended with ret %d", ret);
1985 }
1986
9d6c7d3f
DG
1987 rcu_read_unlock();
1988
8be98f9a
MD
1989 return 0;
1990
1991error_rcu_unlock:
1992 rcu_read_unlock();
1993 return -1;
1994}
1995
84cd17c6
MD
1996/*
1997 * Destroy a specific UST session in apps.
1998 */
1999int ust_app_destroy_trace(struct ltt_ust_session *usess, struct ust_app *app)
2000{
2001 struct ust_app_session *ua_sess;
2002 struct lttng_ust_object_data obj;
2003 struct cds_lfht_iter iter;
2004 struct cds_lfht_node *node;
525b0740 2005 int ret;
84cd17c6
MD
2006
2007 DBG("Destroy tracing for ust app pid %d", app->key.pid);
2008
2009 rcu_read_lock();
2010
2011 __lookup_session_by_app(usess, app, &iter);
2012 node = hashtable_iter_get_node(&iter);
2013 if (node == NULL) {
2014 /* Only malloc can failed so something is really wrong */
2015 goto error_rcu_unlock;
2016 }
2017 ua_sess = caa_container_of(node, struct ust_app_session, node);
525b0740
MD
2018 ret = hashtable_del(app->sessions, &iter);
2019 assert(!ret);
84cd17c6
MD
2020 delete_ust_app_session(app->key.sock, ua_sess);
2021 obj.handle = ua_sess->handle;
2022 obj.shm_fd = -1;
2023 obj.wait_fd = -1;
2024 obj.memory_map_size = 0;
2025 ustctl_release_object(app->key.sock, &obj);
2026
2027 rcu_read_unlock();
2028
2029 /* Quiescent wait after stopping trace */
2030 ustctl_wait_quiescent(app->key.sock);
2031
2032 return 0;
2033
2034error_rcu_unlock:
2035 rcu_read_unlock();
2036 return -1;
2037}
2038
5b4a0ec0
DG
2039/*
2040 * Start tracing for the UST session.
2041 */
421cb601
DG
2042int ust_app_start_trace_all(struct ltt_ust_session *usess)
2043{
2044 int ret = 0;
2045 struct cds_lfht_iter iter;
421cb601 2046 struct ust_app *app;
48842b30 2047
421cb601
DG
2048 DBG("Starting all UST traces");
2049
2050 rcu_read_lock();
421cb601 2051
5b4a0ec0 2052 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
421cb601 2053 ret = ust_app_start_trace(usess, app);
48842b30 2054 if (ret < 0) {
5b4a0ec0
DG
2055 /* Continue to next apps even on error */
2056 continue;
48842b30 2057 }
48842b30 2058 }
5b4a0ec0 2059
48842b30
DG
2060 rcu_read_unlock();
2061
2062 return 0;
2063}
487cf67c 2064
8be98f9a
MD
2065/*
2066 * Start tracing for the UST session.
2067 */
2068int ust_app_stop_trace_all(struct ltt_ust_session *usess)
2069{
2070 int ret = 0;
2071 struct cds_lfht_iter iter;
2072 struct ust_app *app;
2073
2074 DBG("Stopping all UST traces");
2075
2076 rcu_read_lock();
2077
2078 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
2079 ret = ust_app_stop_trace(usess, app);
2080 if (ret < 0) {
2081 /* Continue to next apps even on error */
2082 continue;
2083 }
2084 }
2085
2086 rcu_read_unlock();
2087
2088 return 0;
2089}
2090
84cd17c6
MD
2091/*
2092 * Destroy app UST session.
2093 */
2094int ust_app_destroy_trace_all(struct ltt_ust_session *usess)
2095{
2096 int ret = 0;
2097 struct cds_lfht_iter iter;
2098 struct ust_app *app;
2099
2100 DBG("Destroy all UST traces");
2101
2102 rcu_read_lock();
2103
2104 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
2105 ret = ust_app_destroy_trace(usess, app);
2106 if (ret < 0) {
2107 /* Continue to next apps even on error */
2108 continue;
2109 }
2110 }
2111
2112 rcu_read_unlock();
2113
2114 return 0;
2115}
2116
5b4a0ec0
DG
2117/*
2118 * Add channels/events from UST global domain to registered apps at sock.
2119 */
487cf67c
DG
2120void ust_app_global_update(struct ltt_ust_session *usess, int sock)
2121{
2122 int ret = 0;
487cf67c 2123 struct cds_lfht_iter iter;
487cf67c
DG
2124 struct ust_app *app;
2125 struct ust_app_session *ua_sess;
2126 struct ust_app_channel *ua_chan;
2127 struct ust_app_event *ua_event;
1f3580c7
DG
2128
2129 if (usess == NULL) {
5b4a0ec0 2130 ERR("No UST session on global update. Returning");
1f3580c7
DG
2131 goto error;
2132 }
2133
a991f516
MD
2134 DBG2("UST app global update for app sock %d for session id %d", sock,
2135 usess->id);
487cf67c 2136
284d8f55
DG
2137 rcu_read_lock();
2138
487cf67c
DG
2139 app = find_app_by_sock(sock);
2140 if (app == NULL) {
2141 ERR("Failed to update app sock %d", sock);
2142 goto error;
2143 }
2144
421cb601 2145 ua_sess = create_ust_app_session(usess, app);
487cf67c 2146 if (ua_sess == NULL) {
487cf67c
DG
2147 goto error;
2148 }
2149
284d8f55
DG
2150 /*
2151 * We can iterate safely here over all UST app session sicne the create ust
2152 * app session above made a shadow copy of the UST global domain from the
2153 * ltt ust session.
2154 */
2155 cds_lfht_for_each_entry(ua_sess->channels, &iter, ua_chan, node) {
90eaa0d2
DG
2156 struct cds_lfht_iter uiter;
2157
284d8f55
DG
2158 ret = create_ust_channel(app, ua_sess, ua_chan);
2159 if (ret < 0) {
2160 /* FIXME: Should we quit here or continue... */
2161 continue;
487cf67c
DG
2162 }
2163
284d8f55 2164 /* For each events */
90eaa0d2 2165 cds_lfht_for_each_entry(ua_chan->events, &uiter, ua_event, node) {
284d8f55
DG
2166 ret = create_ust_event(app, ua_sess, ua_chan, ua_event);
2167 if (ret < 0) {
2168 /* FIXME: Should we quit here or continue... */
2169 continue;
487cf67c 2170 }
36dc12cc 2171 }
487cf67c
DG
2172 }
2173
36dc12cc 2174 if (usess->start_trace) {
421cb601 2175 ret = ust_app_start_trace(usess, app);
36dc12cc 2176 if (ret < 0) {
36dc12cc
DG
2177 goto error;
2178 }
2179
36dc12cc
DG
2180 DBG2("UST trace started for app pid %d", app->key.pid);
2181 }
2182
487cf67c
DG
2183error:
2184 rcu_read_unlock();
2185 return;
2186}
55cc08a6
DG
2187
2188/*
2189 * Add context to a specific channel for global UST domain.
2190 */
2191int ust_app_add_ctx_channel_glb(struct ltt_ust_session *usess,
2192 struct ltt_ust_channel *uchan, struct ltt_ust_context *uctx)
2193{
2194 int ret = 0;
2195 struct cds_lfht_node *ua_chan_node;
90eaa0d2 2196 struct cds_lfht_iter iter;
55cc08a6
DG
2197 struct ust_app_channel *ua_chan = NULL;
2198 struct ust_app_session *ua_sess;
2199 struct ust_app *app;
2200
2201 rcu_read_lock();
2202
2203 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
90eaa0d2
DG
2204 struct cds_lfht_iter uiter;
2205
55cc08a6
DG
2206 ua_sess = lookup_session_by_app(usess, app);
2207 if (ua_sess == NULL) {
2208 continue;
2209 }
2210
2211 /* Lookup channel in the ust app session */
2212 ua_chan_node = hashtable_lookup(ua_sess->channels,
2213 (void *)uchan->name, strlen(uchan->name), &uiter);
2214 if (ua_chan_node == NULL) {
2215 continue;
2216 }
2217 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel,
2218 node);
2219
2220 ret = create_ust_app_channel_context(ua_sess, ua_chan, &uctx->ctx, app);
2221 if (ret < 0) {
2222 continue;
2223 }
2224 }
2225
55cc08a6
DG
2226 rcu_read_unlock();
2227 return ret;
2228}
2229
2230/*
2231 * Add context to a specific event in a channel for global UST domain.
2232 */
2233int ust_app_add_ctx_event_glb(struct ltt_ust_session *usess,
2234 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent,
2235 struct ltt_ust_context *uctx)
2236{
2237 int ret = 0;
2238 struct cds_lfht_node *ua_chan_node, *ua_event_node;
90eaa0d2 2239 struct cds_lfht_iter iter;
55cc08a6
DG
2240 struct ust_app_session *ua_sess;
2241 struct ust_app_event *ua_event;
2242 struct ust_app_channel *ua_chan = NULL;
2243 struct ust_app *app;
2244
2245 rcu_read_lock();
2246
2247 cds_lfht_for_each_entry(ust_app_ht, &iter, app, node) {
90eaa0d2
DG
2248 struct cds_lfht_iter uiter;
2249
55cc08a6
DG
2250 ua_sess = lookup_session_by_app(usess, app);
2251 if (ua_sess == NULL) {
2252 continue;
2253 }
2254
2255 /* Lookup channel in the ust app session */
2256 ua_chan_node = hashtable_lookup(ua_sess->channels,
2257 (void *)uchan->name, strlen(uchan->name), &uiter);
2258 if (ua_chan_node == NULL) {
2259 continue;
2260 }
2261 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel,
2262 node);
2263
2264 ua_event_node = hashtable_lookup(ua_chan->events,
2265 (void *)uevent->attr.name, strlen(uevent->attr.name), &uiter);
2266 if (ua_event_node == NULL) {
2267 continue;
2268 }
2269 ua_event = caa_container_of(ua_event_node, struct ust_app_event,
2270 node);
2271
2272 ret = create_ust_app_event_context(ua_sess, ua_event, &uctx->ctx, app);
2273 if (ret < 0) {
2274 continue;
2275 }
2276 }
2277
55cc08a6
DG
2278 rcu_read_unlock();
2279 return ret;
2280}
76d45b40
DG
2281
2282/*
2283 * Enable event for a channel from a UST session for a specific PID.
2284 */
2285int ust_app_enable_event_pid(struct ltt_ust_session *usess,
2286 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, pid_t pid)
2287{
2288 int ret = 0;
2289 struct cds_lfht_iter iter;
2290 struct cds_lfht_node *ua_chan_node, *ua_event_node;
2291 struct ust_app *app;
2292 struct ust_app_session *ua_sess;
2293 struct ust_app_channel *ua_chan;
2294 struct ust_app_event *ua_event;
2295
2296 DBG("UST app enabling event %s for PID %d", uevent->attr.name, pid);
2297
2298 rcu_read_lock();
2299
2300 app = ust_app_find_by_pid(pid);
2301 if (app == NULL) {
2302 ERR("UST app enable event per PID %d not found", pid);
2303 ret = -1;
2304 goto error;
2305 }
2306
2307 ua_sess = lookup_session_by_app(usess, app);
2308 /* If ua_sess is NULL, there is a code flow error */
2309 assert(ua_sess);
2310
2311 /* Lookup channel in the ust app session */
2312 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
2313 strlen(uchan->name), &iter);
2314 /* If the channel is not found, there is a code flow error */
2315 assert(ua_chan_node);
2316
2317 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
2318
7f79d3a1 2319 ua_event_node = hashtable_lookup(ua_chan->events,
76d45b40
DG
2320 (void*)uevent->attr.name, strlen(uevent->attr.name), &iter);
2321 if (ua_event_node == NULL) {
2322 ret = create_ust_app_event(ua_sess, ua_chan, uevent, app);
2323 if (ret < 0) {
2324 goto error;
2325 }
2326 } else {
2327 ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
2328
2329 ret = enable_ust_app_event(ua_sess, ua_event, app);
2330 if (ret < 0) {
2331 goto error;
2332 }
2333 }
2334
2335error:
2336 rcu_read_unlock();
2337 return ret;
2338}
7f79d3a1
DG
2339
2340/*
2341 * Disable event for a channel from a UST session for a specific PID.
2342 */
2343int ust_app_disable_event_pid(struct ltt_ust_session *usess,
2344 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent, pid_t pid)
2345{
2346 int ret = 0;
2347 struct cds_lfht_iter iter;
2348 struct cds_lfht_node *ua_chan_node, *ua_event_node;
2349 struct ust_app *app;
2350 struct ust_app_session *ua_sess;
2351 struct ust_app_channel *ua_chan;
2352 struct ust_app_event *ua_event;
2353
2354 DBG("UST app disabling event %s for PID %d", uevent->attr.name, pid);
2355
2356 rcu_read_lock();
2357
2358 app = ust_app_find_by_pid(pid);
2359 if (app == NULL) {
2360 ERR("UST app disable event per PID %d not found", pid);
2361 ret = -1;
2362 goto error;
2363 }
2364
2365 ua_sess = lookup_session_by_app(usess, app);
2366 /* If ua_sess is NULL, there is a code flow error */
2367 assert(ua_sess);
2368
2369 /* Lookup channel in the ust app session */
2370 ua_chan_node = hashtable_lookup(ua_sess->channels, (void *)uchan->name,
2371 strlen(uchan->name), &iter);
2372 if (ua_chan_node == NULL) {
2373 /* Channel does not exist, skip disabling */
2374 goto error;
2375 }
2376 ua_chan = caa_container_of(ua_chan_node, struct ust_app_channel, node);
2377
2378 ua_event_node = hashtable_lookup(ua_chan->events,
2379 (void*)uevent->attr.name, strlen(uevent->attr.name), &iter);
2380 if (ua_event_node == NULL) {
2381 /* Event does not exist, skip disabling */
2382 goto error;
2383 }
2384 ua_event = caa_container_of(ua_event_node, struct ust_app_event, node);
2385
2386 ret = disable_ust_app_event(ua_sess, ua_event, app);
2387 if (ret < 0) {
2388 goto error;
2389 }
2390
2391error:
2392 rcu_read_unlock();
2393 return ret;
2394}
This page took 0.140475 seconds and 4 git commands to generate.