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