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