Change the UST event hash table match function
[lttng-tools.git] / src / bin / lttng-sessiond / filter.c
CommitLineData
53a80697
MD
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 * Copyright (C) 2012 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2 only,
7 * as published by the Free Software Foundation.
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 along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#define _GNU_SOURCE
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <unistd.h>
24#include <urcu/list.h>
25
26#include <common/error.h>
27#include <common/sessiond-comm/sessiond-comm.h>
28
29#include "filter.h"
30#include "kernel.h"
31#include "ust-app.h"
32#include "trace-ust.h"
33
34/*
35 * Add UST context to event.
36 */
37static int add_ufilter_to_event(struct ltt_ust_session *usess, int domain,
38 struct ltt_ust_channel *uchan, struct ltt_ust_event *uevent,
39 struct lttng_filter_bytecode *bytecode)
40{
41 int ret;
42
43 if (uevent->filter) {
44 ret = -EEXIST;
45 goto error;
46 }
47 /* Same layout. */
48 uevent->filter = (struct lttng_ust_filter_bytecode *) bytecode;
f3f0db50 49 uevent->filter->seqnum = usess->filter_seq_num;
53a80697
MD
50
51 switch (domain) {
52 case LTTNG_DOMAIN_UST:
53 ret = ust_app_set_filter_event_glb(usess, uchan, uevent,
54 bytecode);
55 if (ret < 0) {
56 goto error;
57 }
f3f0db50 58 usess->filter_seq_num++;
53a80697
MD
59 break;
60 default:
61 ret = -ENOSYS;
62 goto error;
63 }
64
65 DBG("Filter UST added to event %s",uevent->attr.name);
66
67 return 0;
68
69error:
70 free(bytecode);
71 return ret;
72}
73
74/*
75 * Add UST context to tracer.
76 */
77int filter_ust_set(struct ltt_ust_session *usess, int domain,
178191b3 78 struct lttng_filter_bytecode *bytecode, struct lttng_event *event,
53a80697
MD
79 char *channel_name)
80{
f73fabfd 81 int ret = LTTNG_OK, have_event = 0;
53a80697
MD
82 struct lttng_ht_iter iter;
83 struct lttng_ht *chan_ht;
84 struct ltt_ust_channel *uchan = NULL;
85 struct ltt_ust_event *uevent = NULL;
86
87 /*
88 * Define which channel's hashtable to use from the domain or quit if
89 * unknown domain.
90 */
91 switch (domain) {
92 case LTTNG_DOMAIN_UST:
93 chan_ht = usess->domain_global.channels;
94 break;
95#if 0
96 case LTTNG_DOMAIN_UST_EXEC_NAME:
97 case LTTNG_DOMAIN_UST_PID:
98 case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
99#endif
100 default:
f73fabfd 101 ret = LTTNG_ERR_UND;
53a80697
MD
102 goto error;
103 }
104
178191b3
DG
105 /* Do we have a valid event. */
106 if (event && event->name[0] != '\0') {
53a80697
MD
107 have_event = 1;
108 }
109
110 /* Get UST channel if defined */
111 if (strlen(channel_name) != 0) {
112 uchan = trace_ust_find_channel_by_name(chan_ht, channel_name);
113 if (uchan == NULL) {
f73fabfd 114 ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
53a80697
MD
115 goto error;
116 }
117 }
118
119 /* If UST channel specified and event name, get UST event ref */
120 if (uchan && have_event) {
18eace3b
DG
121 uevent = trace_ust_find_event(uchan->events, event->name, bytecode,
122 event->loglevel);
53a80697 123 if (uevent == NULL) {
f73fabfd 124 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
53a80697
MD
125 goto error;
126 }
127 }
128
129 /* At this point, we have 4 possibilities */
130
131 if (uchan && uevent) { /* Add filter to event in channel */
132 ret = add_ufilter_to_event(usess, domain, uchan, uevent,
133 bytecode);
134 } else if (uchan && !have_event) { /* Add filter to channel */
135 ERR("Cannot add filter to channel");
f73fabfd 136 ret = LTTNG_ERR_FATAL; /* not supported. */
53a80697
MD
137 goto error;
138 } else if (!uchan && have_event) { /* Add filter to event */
139 /* Add context to event without having the channel name */
140 cds_lfht_for_each_entry(chan_ht->ht, &iter.iter, uchan, node.node) {
18eace3b
DG
141 uevent = trace_ust_find_event(uchan->events, event->name, bytecode,
142 event->loglevel);
53a80697
MD
143 if (uevent != NULL) {
144 ret = add_ufilter_to_event(usess, domain, uchan, uevent, bytecode);
145 /*
146 * LTTng UST does not allowed the same event to be registered
147 * multiple time in different or the same channel. So, if we
148 * found our event, we stop.
149 */
150 goto end;
151 }
152 }
f73fabfd 153 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
53a80697
MD
154 goto error;
155 } else if (!uchan && !have_event) { /* Add filter all events, all channels */
156 ERR("Cannot add filter to channel");
f73fabfd 157 ret = LTTNG_ERR_FATAL; /* not supported. */
53a80697
MD
158 goto error;
159 }
160
161end:
49c336c1 162 /* Must handle both local internal error and UST code. */
53a80697
MD
163 switch (ret) {
164 case -EEXIST:
49c336c1 165 case -LTTNG_UST_ERR_EXIST:
f73fabfd 166 ret = LTTNG_ERR_FILTER_EXIST;
53a80697
MD
167 break;
168 case -ENOMEM:
f73fabfd 169 ret = LTTNG_ERR_FATAL;
53a80697
MD
170 break;
171 case -EINVAL:
49c336c1 172 case -LTTNG_UST_ERR_INVAL:
f73fabfd 173 ret = LTTNG_ERR_FILTER_INVAL;
53a80697
MD
174 break;
175 case -ENOSYS:
49c336c1 176 case -LTTNG_UST_ERR_NOSYS:
f73fabfd 177 ret = LTTNG_ERR_UNKNOWN_DOMAIN;
53a80697
MD
178 break;
179 default:
f73fabfd 180 ret = LTTNG_OK;
53a80697
MD
181 break;
182 }
183
184error:
185 return ret;
186}
This page took 0.045414 seconds and 4 git commands to generate.