Fix: include loglevel type in agent event's primary key
[lttng-tools.git] / src / bin / lttng-sessiond / agent.c
CommitLineData
0475c50c
DG
1/*
2 * Copyright (C) 2013 - David Goulet <dgoulet@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18#define _GNU_SOURCE
6c1c0768 19#define _LGPL_SOURCE
0475c50c 20#include <assert.h>
f20baf8e 21#include <urcu/uatomic.h>
0475c50c
DG
22
23#include <common/common.h>
022d91ba 24#include <common/sessiond-comm/agent.h>
0475c50c 25
f263b7fd
JD
26#include <common/compat/endian.h>
27
022d91ba 28#include "agent.h"
f20baf8e 29#include "ust-app.h"
0475c50c 30#include "utils.h"
23c2bd47
JG
31#include "error.h"
32
33#define AGENT_RET_CODE_INDEX(code) (code - AGENT_RET_CODE_SUCCESS)
34
35/*
36 * Human readable agent return code.
37 */
38static const char *error_string_array[] = {
39 [ AGENT_RET_CODE_INDEX(AGENT_RET_CODE_SUCCESS) ] = "Success",
40 [ AGENT_RET_CODE_INDEX(AGENT_RET_CODE_INVALID) ] = "Invalid command",
41 [ AGENT_RET_CODE_INDEX(AGENT_RET_CODE_UNKNOWN_NAME) ] = "Unknown logger name",
42
43 /* Last element */
44 [ AGENT_RET_CODE_INDEX(AGENT_RET_CODE_NR) ] = "Unknown code",
45};
46
47static
48void log_reply_code(uint32_t in_reply_ret_code)
49{
50 int level = PRINT_DBG3;
51 /*
52 * reply_ret_code and in_reply_ret_code are kept separate to have a
53 * sanitized value (used to retrieve the human readable string) and the
54 * original value which is logged as-is.
55 */
56 uint32_t reply_ret_code = in_reply_ret_code;
57
58 if (reply_ret_code < AGENT_RET_CODE_SUCCESS ||
59 reply_ret_code >= AGENT_RET_CODE_NR) {
60 reply_ret_code = AGENT_RET_CODE_NR;
61 level = PRINT_ERR;
62 }
63
64 LOG(level, "Agent replied with retcode: %s (%"PRIu32")",
65 error_string_array[AGENT_RET_CODE_INDEX(
66 reply_ret_code)],
67 in_reply_ret_code);
68}
0475c50c 69
4a4ab2c3
DG
70/*
71 * Match function for the events hash table lookup by name.
72 */
73static int ht_match_event_by_name(struct cds_lfht_node *node,
74 const void *_key)
75{
022d91ba
DG
76 struct agent_event *event;
77 const struct agent_ht_key *key;
4a4ab2c3
DG
78
79 assert(node);
80 assert(_key);
81
022d91ba 82 event = caa_container_of(node, struct agent_event, node.node);
4a4ab2c3
DG
83 key = _key;
84
85 /* Match 1 elements of the key: name. */
86
87 /* Event name */
88 if (strncmp(event->name, key->name, sizeof(event->name)) != 0) {
89 goto no_match;
90 }
91 /* Match. */
92 return 1;
93
94no_match:
95 return 0;
96}
97
98/*
99 * Match function for the events hash table lookup by name and loglevel.
100 */
101static int ht_match_event(struct cds_lfht_node *node,
102 const void *_key)
103{
022d91ba
DG
104 struct agent_event *event;
105 const struct agent_ht_key *key;
4a4ab2c3
DG
106
107 assert(node);
108 assert(_key);
109
022d91ba 110 event = caa_container_of(node, struct agent_event, node.node);
4a4ab2c3
DG
111 key = _key;
112
113 /* Match 2 elements of the key: name and loglevel. */
114
115 /* Event name */
116 if (strncmp(event->name, key->name, sizeof(event->name)) != 0) {
117 goto no_match;
118 }
119
a9319624
PP
120 /* Event loglevel value and type. */
121 if (event->loglevel_type == key->loglevel_type) {
122 /* Same loglevel type. */
123 if (key->loglevel_type != LTTNG_EVENT_LOGLEVEL_ALL) {
124 /*
125 * Loglevel value must also match since the loglevel
126 * type is not all.
127 */
128 if (event->loglevel_value != key->loglevel_value) {
129 goto no_match;
130 }
4a4ab2c3 131 }
a9319624
PP
132 } else {
133 /* Loglevel type is different: no match. */
4a4ab2c3
DG
134 goto no_match;
135 }
a9319624 136
4a4ab2c3
DG
137 return 1;
138
139no_match:
140 return 0;
141}
142
143/*
022d91ba 144 * Add unique agent event based on the event name and loglevel.
4a4ab2c3 145 */
022d91ba
DG
146static void add_unique_agent_event(struct lttng_ht *ht,
147 struct agent_event *event)
4a4ab2c3
DG
148{
149 struct cds_lfht_node *node_ptr;
022d91ba 150 struct agent_ht_key key;
4a4ab2c3
DG
151
152 assert(ht);
153 assert(ht->ht);
154 assert(event);
155
156 key.name = event->name;
2106efa0 157 key.loglevel_value = event->loglevel_value;
a9319624 158 key.loglevel_type = event->loglevel_type;
4a4ab2c3
DG
159
160 node_ptr = cds_lfht_add_unique(ht->ht,
161 ht->hash_fct(event->node.key, lttng_ht_seed),
162 ht_match_event, &key, &event->node.node);
163 assert(node_ptr == &event->node.node);
164}
165
0475c50c 166/*
022d91ba 167 * URCU delayed agent event reclaim.
0475c50c 168 */
022d91ba 169static void destroy_event_agent_rcu(struct rcu_head *head)
0475c50c
DG
170{
171 struct lttng_ht_node_str *node =
172 caa_container_of(head, struct lttng_ht_node_str, head);
022d91ba
DG
173 struct agent_event *event =
174 caa_container_of(node, struct agent_event, node);
0475c50c 175
992febc7 176 agent_destroy_event(event);
0475c50c
DG
177}
178
f20baf8e 179/*
022d91ba 180 * URCU delayed agent app reclaim.
f20baf8e 181 */
022d91ba 182static void destroy_app_agent_rcu(struct rcu_head *head)
f20baf8e
DG
183{
184 struct lttng_ht_node_ulong *node =
185 caa_container_of(head, struct lttng_ht_node_ulong, head);
022d91ba
DG
186 struct agent_app *app =
187 caa_container_of(node, struct agent_app, node);
f20baf8e
DG
188
189 free(app);
190}
191
192/*
022d91ba
DG
193 * Communication with the agent. Send the message header to the given socket in
194 * big endian.
f20baf8e
DG
195 *
196 * Return 0 on success or else a negative errno message of sendmsg() op.
197 */
198static int send_header(struct lttcomm_sock *sock, uint64_t data_size,
199 uint32_t cmd, uint32_t cmd_version)
200{
201 int ret;
202 ssize_t size;
022d91ba 203 struct lttcomm_agent_hdr msg;
f20baf8e
DG
204
205 assert(sock);
206
53efb85a 207 memset(&msg, 0, sizeof(msg));
f20baf8e
DG
208 msg.data_size = htobe64(data_size);
209 msg.cmd = htobe32(cmd);
210 msg.cmd_version = htobe32(cmd_version);
211
212 size = sock->ops->sendmsg(sock, &msg, sizeof(msg), 0);
213 if (size < sizeof(msg)) {
214 ret = -errno;
215 goto error;
216 }
217 ret = 0;
218
219error:
220 return ret;
221}
222
223/*
022d91ba
DG
224 * Communication call with the agent. Send the payload to the given socket. The
225 * header MUST be sent prior to this call.
f20baf8e
DG
226 *
227 * Return 0 on success or else a negative errno value of sendmsg() op.
228 */
229static int send_payload(struct lttcomm_sock *sock, void *data,
230 size_t size)
231{
232 int ret;
233 ssize_t len;
234
235 assert(sock);
236 assert(data);
237
238 len = sock->ops->sendmsg(sock, data, size, 0);
239 if (len < size) {
240 ret = -errno;
241 goto error;
242 }
243 ret = 0;
244
245error:
246 return ret;
247}
248
249/*
022d91ba
DG
250 * Communication call with the agent. Receive reply from the agent using the
251 * given socket.
f20baf8e
DG
252 *
253 * Return 0 on success or else a negative errno value from recvmsg() op.
254 */
255static int recv_reply(struct lttcomm_sock *sock, void *buf, size_t size)
256{
257 int ret;
258 ssize_t len;
259
260 assert(sock);
261 assert(buf);
262
263 len = sock->ops->recvmsg(sock, buf, size, 0);
264 if (len < size) {
265 ret = -errno;
266 goto error;
267 }
268 ret = 0;
269
270error:
271 return ret;
272}
273
3c6a091f 274/*
428de77a 275 * Internal event listing for a given app. Populate events.
3c6a091f
DG
276 *
277 * Return number of element in the list or else a negative LTTNG_ERR* code.
428de77a
MD
278 * On success, the caller is responsible for freeing the memory
279 * allocated for "events".
3c6a091f 280 */
022d91ba 281static ssize_t list_events(struct agent_app *app, struct lttng_event **events)
3c6a091f
DG
282{
283 int ret, i, len = 0, offset = 0;
284 uint32_t nb_event;
285 size_t data_size;
d84af1a4 286 uint32_t reply_ret_code;
3c6a091f 287 struct lttng_event *tmp_events = NULL;
022d91ba
DG
288 struct lttcomm_agent_list_reply *reply = NULL;
289 struct lttcomm_agent_list_reply_hdr reply_hdr;
3c6a091f
DG
290
291 assert(app);
292 assert(app->sock);
293 assert(events);
294
022d91ba 295 DBG2("Agent listing events for app pid: %d and socket %d", app->pid,
3c6a091f
DG
296 app->sock->fd);
297
022d91ba 298 ret = send_header(app->sock, 0, AGENT_CMD_LIST, 0);
3c6a091f
DG
299 if (ret < 0) {
300 goto error_io;
301 }
302
303 /* Get list header so we know how much we'll receive. */
304 ret = recv_reply(app->sock, &reply_hdr, sizeof(reply_hdr));
305 if (ret < 0) {
306 goto error_io;
307 }
308
d84af1a4
JG
309 reply_ret_code = be32toh(reply_hdr.ret_code);
310 log_reply_code(reply_ret_code);
311 switch (reply_ret_code) {
022d91ba 312 case AGENT_RET_CODE_SUCCESS:
3c6a091f
DG
313 data_size = be32toh(reply_hdr.data_size) + sizeof(*reply);
314 break;
315 default:
3bd9aaeb 316 ret = LTTNG_ERR_UNK;
3c6a091f
DG
317 goto error;
318 }
319
320 reply = zmalloc(data_size);
321 if (!reply) {
322 ret = LTTNG_ERR_NOMEM;
323 goto error;
324 }
325
326 /* Get the list with the appropriate data size. */
327 ret = recv_reply(app->sock, reply, data_size);
328 if (ret < 0) {
329 goto error_io;
330 }
331
332 nb_event = be32toh(reply->nb_event);
333 tmp_events = zmalloc(sizeof(*tmp_events) * nb_event);
334 if (!tmp_events) {
335 ret = LTTNG_ERR_NOMEM;
336 goto error;
337 }
338
339 for (i = 0; i < nb_event; i++) {
340 offset += len;
341 strncpy(tmp_events[i].name, reply->payload + offset,
342 sizeof(tmp_events[i].name));
343 tmp_events[i].pid = app->pid;
344 tmp_events[i].enabled = -1;
345 len = strlen(reply->payload + offset) + 1;
346 }
347
348 *events = tmp_events;
349
350 free(reply);
351 return nb_event;
352
353error_io:
354 ret = LTTNG_ERR_UST_LIST_FAIL;
355error:
356 free(reply);
357 free(tmp_events);
358 return -ret;
359
360}
361
f20baf8e 362/*
022d91ba
DG
363 * Internal enable agent event on a agent application. This function
364 * communicates with the agent to enable a given event.
f20baf8e
DG
365 *
366 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
367 */
022d91ba 368static int enable_event(struct agent_app *app, struct agent_event *event)
f20baf8e
DG
369{
370 int ret;
371 uint64_t data_size;
f4f9d4db 372 uint32_t reply_ret_code;
022d91ba
DG
373 struct lttcomm_agent_enable msg;
374 struct lttcomm_agent_generic_reply reply;
f20baf8e
DG
375
376 assert(app);
377 assert(app->sock);
378 assert(event);
379
022d91ba 380 DBG2("Agent enabling event %s for app pid: %d and socket %d", event->name,
f20baf8e
DG
381 app->pid, app->sock->fd);
382
383 data_size = sizeof(msg);
384
022d91ba 385 ret = send_header(app->sock, data_size, AGENT_CMD_ENABLE, 0);
f20baf8e
DG
386 if (ret < 0) {
387 goto error_io;
388 }
389
53efb85a 390 memset(&msg, 0, sizeof(msg));
2106efa0 391 msg.loglevel_value = event->loglevel_value;
b2064f54 392 msg.loglevel_type = event->loglevel_type;
f20baf8e
DG
393 strncpy(msg.name, event->name, sizeof(msg.name));
394 ret = send_payload(app->sock, &msg, sizeof(msg));
395 if (ret < 0) {
396 goto error_io;
397 }
398
399 ret = recv_reply(app->sock, &reply, sizeof(reply));
400 if (ret < 0) {
401 goto error_io;
402 }
403
f4f9d4db
JG
404 reply_ret_code = be32toh(reply.ret_code);
405 log_reply_code(reply_ret_code);
406 switch (reply_ret_code) {
022d91ba 407 case AGENT_RET_CODE_SUCCESS:
f20baf8e 408 break;
022d91ba 409 case AGENT_RET_CODE_UNKNOWN_NAME:
f20baf8e
DG
410 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
411 goto error;
412 default:
3bd9aaeb 413 ret = LTTNG_ERR_UNK;
f20baf8e
DG
414 goto error;
415 }
416
417 return LTTNG_OK;
418
419error_io:
420 ret = LTTNG_ERR_UST_ENABLE_FAIL;
421error:
422 return ret;
423}
424
425/*
022d91ba
DG
426 * Internal disable agent event call on a agent application. This function
427 * communicates with the agent to disable a given event.
f20baf8e
DG
428 *
429 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
430 */
022d91ba 431static int disable_event(struct agent_app *app, struct agent_event *event)
f20baf8e
DG
432{
433 int ret;
434 uint64_t data_size;
517992f8 435 uint32_t reply_ret_code;
022d91ba
DG
436 struct lttcomm_agent_disable msg;
437 struct lttcomm_agent_generic_reply reply;
f20baf8e
DG
438
439 assert(app);
440 assert(app->sock);
441 assert(event);
442
022d91ba 443 DBG2("Agent disabling event %s for app pid: %d and socket %d", event->name,
f20baf8e
DG
444 app->pid, app->sock->fd);
445
446 data_size = sizeof(msg);
447
022d91ba 448 ret = send_header(app->sock, data_size, AGENT_CMD_DISABLE, 0);
f20baf8e
DG
449 if (ret < 0) {
450 goto error_io;
451 }
452
53efb85a 453 memset(&msg, 0, sizeof(msg));
f20baf8e
DG
454 strncpy(msg.name, event->name, sizeof(msg.name));
455 ret = send_payload(app->sock, &msg, sizeof(msg));
456 if (ret < 0) {
457 goto error_io;
458 }
459
460 ret = recv_reply(app->sock, &reply, sizeof(reply));
461 if (ret < 0) {
462 goto error_io;
463 }
464
517992f8
JG
465 reply_ret_code = be32toh(reply.ret_code);
466 log_reply_code(reply_ret_code);
467 switch (reply_ret_code) {
022d91ba
DG
468 case AGENT_RET_CODE_SUCCESS:
469 break;
470 case AGENT_RET_CODE_UNKNOWN_NAME:
471 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
472 goto error;
473 default:
3bd9aaeb 474 ret = LTTNG_ERR_UNK;
022d91ba 475 goto error;
f20baf8e
DG
476 }
477
478 return LTTNG_OK;
479
480error_io:
481 ret = LTTNG_ERR_UST_DISABLE_FAIL;
482error:
483 return ret;
484}
485
1b500e7a 486/*
022d91ba 487 * Send back the registration DONE command to a given agent application.
1b500e7a
DG
488 *
489 * Return 0 on success or else a negative value.
490 */
022d91ba 491int agent_send_registration_done(struct agent_app *app)
1b500e7a
DG
492{
493 assert(app);
494 assert(app->sock);
495
022d91ba 496 DBG("Agent sending registration done to app socket %d", app->sock->fd);
1b500e7a 497
b26d1f5c 498 return send_header(app->sock, 0, AGENT_CMD_REG_DONE, 0);
1b500e7a
DG
499}
500
f20baf8e 501/*
022d91ba 502 * Enable agent event on every agent applications registered with the session
f20baf8e
DG
503 * daemon.
504 *
505 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
506 */
fefd409b
DG
507int agent_enable_event(struct agent_event *event,
508 enum lttng_domain_type domain)
f20baf8e
DG
509{
510 int ret;
022d91ba 511 struct agent_app *app;
f20baf8e
DG
512 struct lttng_ht_iter iter;
513
514 assert(event);
515
516 rcu_read_lock();
517
022d91ba 518 cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, app,
f20baf8e 519 node.node) {
fefd409b
DG
520 if (app->domain != domain) {
521 continue;
522 }
523
022d91ba 524 /* Enable event on agent application through TCP socket. */
f20baf8e
DG
525 ret = enable_event(app, event);
526 if (ret != LTTNG_OK) {
527 goto error;
528 }
f20baf8e
DG
529 }
530
3c6a091f 531 event->enabled = 1;
f20baf8e
DG
532 ret = LTTNG_OK;
533
534error:
535 rcu_read_unlock();
536 return ret;
537}
538
539/*
022d91ba 540 * Disable agent event on every agent applications registered with the session
f20baf8e
DG
541 * daemon.
542 *
543 * Return LTTNG_OK on success or else a LTTNG_ERR* code.
544 */
fefd409b
DG
545int agent_disable_event(struct agent_event *event,
546 enum lttng_domain_type domain)
f20baf8e 547{
f1bc0129 548 int ret = LTTNG_OK;
022d91ba 549 struct agent_app *app;
f20baf8e
DG
550 struct lttng_ht_iter iter;
551
552 assert(event);
f1bc0129
JG
553 if (!event->enabled) {
554 goto end;
555 }
f20baf8e
DG
556
557 rcu_read_lock();
558
022d91ba 559 cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, app,
f20baf8e 560 node.node) {
fefd409b
DG
561 if (app->domain != domain) {
562 continue;
563 }
564
022d91ba 565 /* Enable event on agent application through TCP socket. */
f20baf8e
DG
566 ret = disable_event(app, event);
567 if (ret != LTTNG_OK) {
568 goto error;
569 }
f20baf8e
DG
570 }
571
3c6a091f 572 event->enabled = 0;
f20baf8e
DG
573
574error:
575 rcu_read_unlock();
f1bc0129 576end:
f20baf8e
DG
577 return ret;
578}
579
580/*
022d91ba
DG
581 * Ask every agent for the list of possible event. Events is allocated with the
582 * events of every agent application.
f20baf8e
DG
583 *
584 * Return the number of events or else a negative value.
585 */
f60140a1
DG
586int agent_list_events(struct lttng_event **events,
587 enum lttng_domain_type domain)
f20baf8e
DG
588{
589 int ret;
590 size_t nbmem, count = 0;
022d91ba 591 struct agent_app *app;
aae6255e 592 struct lttng_event *tmp_events = NULL;
f20baf8e
DG
593 struct lttng_ht_iter iter;
594
595 assert(events);
596
0e115563
DG
597 DBG2("Agent listing events for domain %d", domain);
598
f20baf8e
DG
599 nbmem = UST_APP_EVENT_LIST_SIZE;
600 tmp_events = zmalloc(nbmem * sizeof(*tmp_events));
601 if (!tmp_events) {
022d91ba 602 PERROR("zmalloc agent list events");
f20baf8e
DG
603 ret = -ENOMEM;
604 goto error;
605 }
606
607 rcu_read_lock();
022d91ba 608 cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, app,
f20baf8e
DG
609 node.node) {
610 ssize_t nb_ev;
022d91ba 611 struct lttng_event *agent_events;
f20baf8e 612
f60140a1
DG
613 /* Skip domain not asked by the list. */
614 if (app->domain != domain) {
615 continue;
616 }
617
022d91ba 618 nb_ev = list_events(app, &agent_events);
f20baf8e
DG
619 if (nb_ev < 0) {
620 ret = nb_ev;
428de77a 621 goto error_unlock;
f20baf8e
DG
622 }
623
53efb85a 624 if (count + nb_ev > nbmem) {
f20baf8e 625 /* In case the realloc fails, we free the memory */
53efb85a
MD
626 struct lttng_event *new_tmp_events;
627 size_t new_nbmem;
628
629 new_nbmem = max_t(size_t, count + nb_ev, nbmem << 1);
022d91ba 630 DBG2("Reallocating agent event list from %zu to %zu entries",
53efb85a
MD
631 nbmem, new_nbmem);
632 new_tmp_events = realloc(tmp_events,
633 new_nbmem * sizeof(*new_tmp_events));
634 if (!new_tmp_events) {
022d91ba 635 PERROR("realloc agent events");
f20baf8e 636 ret = -ENOMEM;
022d91ba 637 free(agent_events);
428de77a 638 goto error_unlock;
f20baf8e 639 }
53efb85a
MD
640 /* Zero the new memory */
641 memset(new_tmp_events + nbmem, 0,
642 (new_nbmem - nbmem) * sizeof(*new_tmp_events));
643 nbmem = new_nbmem;
644 tmp_events = new_tmp_events;
f20baf8e 645 }
022d91ba 646 memcpy(tmp_events + count, agent_events,
53efb85a 647 nb_ev * sizeof(*tmp_events));
022d91ba 648 free(agent_events);
f20baf8e
DG
649 count += nb_ev;
650 }
651 rcu_read_unlock();
652
653 ret = count;
654 *events = tmp_events;
aae6255e 655 return ret;
f20baf8e 656
428de77a
MD
657error_unlock:
658 rcu_read_unlock();
f20baf8e 659error:
aae6255e 660 free(tmp_events);
f20baf8e
DG
661 return ret;
662}
663
664/*
022d91ba 665 * Create a agent app object using the given PID.
f20baf8e
DG
666 *
667 * Return newly allocated object or else NULL on error.
668 */
fefd409b
DG
669struct agent_app *agent_create_app(pid_t pid, enum lttng_domain_type domain,
670 struct lttcomm_sock *sock)
f20baf8e 671{
022d91ba 672 struct agent_app *app;
f20baf8e
DG
673
674 assert(sock);
675
676 app = zmalloc(sizeof(*app));
677 if (!app) {
022d91ba 678 PERROR("zmalloc agent create");
f20baf8e
DG
679 goto error;
680 }
681
682 app->pid = pid;
fefd409b 683 app->domain = domain;
f20baf8e 684 app->sock = sock;
f20baf8e
DG
685 lttng_ht_node_init_ulong(&app->node, (unsigned long) app->sock->fd);
686
687error:
688 return app;
689}
690
691/*
022d91ba 692 * Lookup agent app by socket in the global hash table.
f20baf8e
DG
693 *
694 * RCU read side lock MUST be acquired.
695 *
696 * Return object if found else NULL.
697 */
022d91ba 698struct agent_app *agent_find_app_by_sock(int sock)
f20baf8e
DG
699{
700 struct lttng_ht_node_ulong *node;
701 struct lttng_ht_iter iter;
022d91ba 702 struct agent_app *app;
f20baf8e
DG
703
704 assert(sock >= 0);
705
022d91ba 706 lttng_ht_lookup(agent_apps_ht_by_sock, (void *)((unsigned long) sock), &iter);
f20baf8e
DG
707 node = lttng_ht_iter_get_node_ulong(&iter);
708 if (node == NULL) {
709 goto error;
710 }
022d91ba 711 app = caa_container_of(node, struct agent_app, node);
f20baf8e 712
022d91ba 713 DBG3("Agent app pid %d found by sock %d.", app->pid, sock);
f20baf8e
DG
714 return app;
715
716error:
022d91ba 717 DBG3("Agent app NOT found by sock %d.", sock);
f20baf8e
DG
718 return NULL;
719}
720
721/*
022d91ba 722 * Add agent application object to the global hash table.
f20baf8e 723 */
022d91ba 724void agent_add_app(struct agent_app *app)
f20baf8e
DG
725{
726 assert(app);
727
022d91ba 728 DBG3("Agent adding app sock: %d and pid: %d to ht", app->sock->fd, app->pid);
022d91ba 729 lttng_ht_add_unique_ulong(agent_apps_ht_by_sock, &app->node);
f20baf8e
DG
730}
731
f20baf8e 732/*
022d91ba 733 * Delete agent application from the global hash table.
d558f236
JG
734 *
735 * rcu_read_lock() must be held by the caller.
f20baf8e 736 */
022d91ba 737void agent_delete_app(struct agent_app *app)
f20baf8e
DG
738{
739 int ret;
740 struct lttng_ht_iter iter;
741
742 assert(app);
743
022d91ba 744 DBG3("Agent deleting app pid: %d and sock: %d", app->pid, app->sock->fd);
f20baf8e
DG
745
746 iter.iter.node = &app->node.node;
022d91ba 747 ret = lttng_ht_del(agent_apps_ht_by_sock, &iter);
f20baf8e
DG
748 assert(!ret);
749}
750
751/*
e785906c 752 * Destroy an agent application object by detaching it from its corresponding
022d91ba 753 * UST app if one is connected by closing the socket. Finally, perform a
428de77a 754 * delayed memory reclaim.
f20baf8e 755 */
022d91ba 756void agent_destroy_app(struct agent_app *app)
f20baf8e
DG
757{
758 assert(app);
759
760 if (app->sock) {
761 app->sock->ops->close(app->sock);
762 lttcomm_destroy_sock(app->sock);
763 }
764
022d91ba 765 call_rcu(&app->node.head, destroy_app_agent_rcu);
f20baf8e
DG
766}
767
0475c50c 768/*
022d91ba 769 * Initialize an already allocated agent object.
0475c50c
DG
770 *
771 * Return 0 on success or else a negative errno value.
772 */
022d91ba 773int agent_init(struct agent *agt)
0475c50c
DG
774{
775 int ret;
776
022d91ba 777 assert(agt);
0475c50c 778
022d91ba
DG
779 agt->events = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
780 if (!agt->events) {
0475c50c
DG
781 ret = -ENOMEM;
782 goto error;
783 }
fefd409b 784 lttng_ht_node_init_u64(&agt->node, agt->domain);
0475c50c
DG
785
786 return 0;
787
788error:
789 return ret;
790}
791
fefd409b
DG
792/*
793 * Add agent object to the given hash table.
794 */
795void agent_add(struct agent *agt, struct lttng_ht *ht)
796{
797 assert(agt);
798 assert(ht);
799
800 DBG3("Agent adding from domain %d", agt->domain);
801
fefd409b 802 lttng_ht_add_unique_u64(ht, &agt->node);
fefd409b
DG
803}
804
805/*
806 * Create an agent object for the given domain.
807 *
808 * Return the allocated agent or NULL on error.
809 */
810struct agent *agent_create(enum lttng_domain_type domain)
811{
812 int ret;
813 struct agent *agt;
814
3b5f70d4 815 agt = zmalloc(sizeof(struct agent));
fefd409b
DG
816 if (!agt) {
817 goto error;
818 }
819 agt->domain = domain;
820
821 ret = agent_init(agt);
822 if (ret < 0) {
823 free(agt);
988ae332 824 agt = NULL;
fefd409b
DG
825 goto error;
826 }
827
828error:
829 return agt;
830}
831
0475c50c 832/*
51755dc8
JG
833 * Create a newly allocated agent event data structure.
834 * Ownership of filter_expression is taken.
0475c50c
DG
835 *
836 * Return a new object else NULL on error.
837 */
022d91ba 838struct agent_event *agent_create_event(const char *name,
a9319624 839 enum lttng_loglevel_type loglevel_type, int loglevel_value,
51755dc8 840 struct lttng_filter_bytecode *filter, char *filter_expression)
0475c50c 841{
51755dc8 842 struct agent_event *event = NULL;
0475c50c 843
a9319624
PP
844 DBG3("Agent create new event with name %s, loglevel type %d and loglevel value %d",
845 name, loglevel_type, loglevel_value);
0475c50c 846
51755dc8
JG
847 if (!name) {
848 ERR("Failed to create agent event; no name provided.");
0475c50c
DG
849 goto error;
850 }
851
51755dc8
JG
852 event = zmalloc(sizeof(*event));
853 if (!event) {
854 goto error;
0475c50c
DG
855 }
856
51755dc8
JG
857 strncpy(event->name, name, sizeof(event->name));
858 event->name[sizeof(event->name) - 1] = '\0';
859 lttng_ht_node_init_str(&event->node, event->name);
be6a6276 860
2106efa0 861 event->loglevel_value = loglevel_value;
51755dc8
JG
862 event->loglevel_type = loglevel_type;
863 event->filter = filter;
864 event->filter_expression = filter_expression;
0475c50c
DG
865error:
866 return event;
867}
868
869/*
022d91ba 870 * Unique add of a agent event to an agent object.
0475c50c 871 */
022d91ba 872void agent_add_event(struct agent_event *event, struct agent *agt)
0475c50c
DG
873{
874 assert(event);
022d91ba
DG
875 assert(agt);
876 assert(agt->events);
0475c50c 877
022d91ba 878 DBG3("Agent adding event %s", event->name);
022d91ba 879 add_unique_agent_event(agt->events, event);
022d91ba 880 agt->being_used = 1;
0475c50c
DG
881}
882
883/*
022d91ba 884 * Find a agent event in the given agent using name.
4a4ab2c3
DG
885 *
886 * RCU read side lock MUST be acquired.
887 *
888 * Return object if found else NULL.
889 */
022d91ba
DG
890struct agent_event *agent_find_event_by_name(const char *name,
891 struct agent *agt)
4a4ab2c3
DG
892{
893 struct lttng_ht_node_str *node;
894 struct lttng_ht_iter iter;
895 struct lttng_ht *ht;
022d91ba 896 struct agent_ht_key key;
4a4ab2c3
DG
897
898 assert(name);
022d91ba
DG
899 assert(agt);
900 assert(agt->events);
4a4ab2c3 901
022d91ba 902 ht = agt->events;
4a4ab2c3
DG
903 key.name = name;
904
905 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
906 ht_match_event_by_name, &key, &iter.iter);
907 node = lttng_ht_iter_get_node_str(&iter);
908 if (node == NULL) {
909 goto error;
910 }
911
022d91ba
DG
912 DBG3("Agent event found %s by name.", name);
913 return caa_container_of(node, struct agent_event, node);
4a4ab2c3
DG
914
915error:
022d91ba 916 DBG3("Agent NOT found by name %s.", name);
4a4ab2c3
DG
917 return NULL;
918}
919
920/*
022d91ba 921 * Find a agent event in the given agent using name and loglevel.
0475c50c
DG
922 *
923 * RCU read side lock MUST be acquired.
924 *
925 * Return object if found else NULL.
926 */
a9319624
PP
927struct agent_event *agent_find_event(const char *name,
928 enum lttng_loglevel_type loglevel_type, int loglevel_value,
022d91ba 929 struct agent *agt)
0475c50c
DG
930{
931 struct lttng_ht_node_str *node;
932 struct lttng_ht_iter iter;
4a4ab2c3 933 struct lttng_ht *ht;
022d91ba 934 struct agent_ht_key key;
0475c50c
DG
935
936 assert(name);
022d91ba
DG
937 assert(agt);
938 assert(agt->events);
0475c50c 939
022d91ba 940 ht = agt->events;
4a4ab2c3 941 key.name = name;
2106efa0 942 key.loglevel_value = loglevel_value;
a9319624 943 key.loglevel_type = loglevel_type;
4a4ab2c3
DG
944
945 cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
946 ht_match_event, &key, &iter.iter);
0475c50c
DG
947 node = lttng_ht_iter_get_node_str(&iter);
948 if (node == NULL) {
949 goto error;
950 }
951
022d91ba
DG
952 DBG3("Agent event found %s.", name);
953 return caa_container_of(node, struct agent_event, node);
0475c50c
DG
954
955error:
a51e817b 956 DBG3("Agent event NOT found %s.", name);
0475c50c
DG
957 return NULL;
958}
959
0475c50c 960/*
022d91ba
DG
961 * Free given agent event. This event must not be globally visible at this
962 * point (only expected to be used on failure just after event creation). After
963 * this call, the pointer is not usable anymore.
0475c50c 964 */
022d91ba 965void agent_destroy_event(struct agent_event *event)
0475c50c
DG
966{
967 assert(event);
968
971da06a 969 free(event->filter);
8404118c 970 free(event->filter_expression);
51755dc8 971 free(event->exclusion);
0475c50c
DG
972 free(event);
973}
974
975/*
35ed21a5 976 * Destroy an agent completely.
0475c50c 977 */
022d91ba 978void agent_destroy(struct agent *agt)
0475c50c
DG
979{
980 struct lttng_ht_node_str *node;
981 struct lttng_ht_iter iter;
982
022d91ba 983 assert(agt);
0475c50c 984
022d91ba 985 DBG3("Agent destroy");
0475c50c 986
0475c50c 987 rcu_read_lock();
022d91ba 988 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, node, node) {
0475c50c 989 int ret;
022d91ba 990 struct agent_event *event;
29c0fd4d
DG
991
992 /*
993 * When destroying an event, we have to try to disable it on the agent
994 * side so the event stops generating data. The return value is not
995 * important since we have to continue anyway destroying the object.
996 */
022d91ba
DG
997 event = caa_container_of(node, struct agent_event, node);
998 (void) agent_disable_event(event, agt->domain);
0475c50c 999
022d91ba 1000 ret = lttng_ht_del(agt->events, &iter);
0475c50c 1001 assert(!ret);
022d91ba 1002 call_rcu(&node->head, destroy_event_agent_rcu);
0475c50c
DG
1003 }
1004 rcu_read_unlock();
1005
f8be902b 1006 ht_cleanup_push(agt->events);
35ed21a5 1007 free(agt);
f20baf8e
DG
1008}
1009
1010/*
6a4e4039 1011 * Allocate agent_apps_ht_by_sock.
f20baf8e 1012 */
6a4e4039 1013int agent_app_ht_alloc(void)
f20baf8e 1014{
6a4e4039
JG
1015 int ret = 0;
1016
022d91ba
DG
1017 agent_apps_ht_by_sock = lttng_ht_new(0, LTTNG_HT_TYPE_ULONG);
1018 if (!agent_apps_ht_by_sock) {
6a4e4039 1019 ret = -1;
f20baf8e
DG
1020 }
1021
6a4e4039
JG
1022 return ret;
1023}
1024
1025/*
1026 * Destroy a agent application by socket.
1027 */
1028void agent_destroy_app_by_sock(int sock)
1029{
1030 struct agent_app *app;
1031
1032 assert(sock >= 0);
1033
1034 /*
1035 * Not finding an application is a very important error that should NEVER
1036 * happen. The hash table deletion is ONLY done through this call when the
1037 * main sessiond thread is torn down.
1038 */
1039 rcu_read_lock();
1040 app = agent_find_app_by_sock(sock);
1041 assert(app);
1042
1043 /* RCU read side lock is assumed to be held by this function. */
1044 agent_delete_app(app);
1045
1046 /* The application is freed in a RCU call but the socket is closed here. */
1047 agent_destroy_app(app);
1048 rcu_read_unlock();
1049}
1050
1051/*
1052 * Clean-up the agent app hash table and destroy it.
1053 */
1054void agent_app_ht_clean(void)
1055{
1056 struct lttng_ht_node_ulong *node;
1057 struct lttng_ht_iter iter;
1058
a433283e
JG
1059 if (!agent_apps_ht_by_sock) {
1060 return;
1061 }
6a4e4039
JG
1062 rcu_read_lock();
1063 cds_lfht_for_each_entry(agent_apps_ht_by_sock->ht, &iter.iter, node, node) {
1064 struct agent_app *app;
1065
1066 app = caa_container_of(node, struct agent_app, node);
1067 agent_destroy_app_by_sock(app->sock->fd);
1068 }
1069 rcu_read_unlock();
1070
1071 lttng_ht_destroy(agent_apps_ht_by_sock);
f20baf8e
DG
1072}
1073
1074/*
022d91ba 1075 * Update a agent application (given socket) using the given agent.
f20baf8e
DG
1076 *
1077 * Note that this function is most likely to be used with a tracing session
1078 * thus the caller should make sure to hold the appropriate lock(s).
1079 */
022d91ba 1080void agent_update(struct agent *agt, int sock)
f20baf8e
DG
1081{
1082 int ret;
022d91ba
DG
1083 struct agent_app *app;
1084 struct agent_event *event;
f20baf8e
DG
1085 struct lttng_ht_iter iter;
1086
022d91ba 1087 assert(agt);
f20baf8e
DG
1088 assert(sock >= 0);
1089
022d91ba 1090 DBG("Agent updating app socket %d", sock);
f20baf8e
DG
1091
1092 rcu_read_lock();
022d91ba 1093 cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) {
f20baf8e
DG
1094 /* Skip event if disabled. */
1095 if (!event->enabled) {
1096 continue;
1097 }
1098
022d91ba 1099 app = agent_find_app_by_sock(sock);
f20baf8e
DG
1100 /*
1101 * We are in the registration path thus if the application is gone,
1102 * there is a serious code flow error.
1103 */
1104 assert(app);
1105
1106 ret = enable_event(app, event);
1107 if (ret != LTTNG_OK) {
022d91ba 1108 DBG2("Agent update unable to enable event %s on app pid: %d sock %d",
f20baf8e
DG
1109 event->name, app->pid, app->sock->fd);
1110 /* Let's try the others here and don't assume the app is dead. */
1111 continue;
1112 }
1113 }
1114 rcu_read_unlock();
0475c50c 1115}
This page took 0.089938 seconds and 5 git commands to generate.