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