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