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