Pass lttng_event struct to the set_filter API call
[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) {
178191b3 121 uevent = trace_ust_find_event_by_name(uchan->events, event->name);
53a80697 122 if (uevent == NULL) {
f73fabfd 123 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
53a80697
MD
124 goto error;
125 }
126 }
127
128 /* At this point, we have 4 possibilities */
129
130 if (uchan && uevent) { /* Add filter to event in channel */
131 ret = add_ufilter_to_event(usess, domain, uchan, uevent,
132 bytecode);
133 } else if (uchan && !have_event) { /* Add filter to channel */
134 ERR("Cannot add filter to channel");
f73fabfd 135 ret = LTTNG_ERR_FATAL; /* not supported. */
53a80697
MD
136 goto error;
137 } else if (!uchan && have_event) { /* Add filter to event */
138 /* Add context to event without having the channel name */
139 cds_lfht_for_each_entry(chan_ht->ht, &iter.iter, uchan, node.node) {
178191b3 140 uevent = trace_ust_find_event_by_name(uchan->events, event->name);
53a80697
MD
141 if (uevent != NULL) {
142 ret = add_ufilter_to_event(usess, domain, uchan, uevent, bytecode);
143 /*
144 * LTTng UST does not allowed the same event to be registered
145 * multiple time in different or the same channel. So, if we
146 * found our event, we stop.
147 */
148 goto end;
149 }
150 }
f73fabfd 151 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
53a80697
MD
152 goto error;
153 } else if (!uchan && !have_event) { /* Add filter all events, all channels */
154 ERR("Cannot add filter to channel");
f73fabfd 155 ret = LTTNG_ERR_FATAL; /* not supported. */
53a80697
MD
156 goto error;
157 }
158
159end:
49c336c1 160 /* Must handle both local internal error and UST code. */
53a80697
MD
161 switch (ret) {
162 case -EEXIST:
49c336c1 163 case -LTTNG_UST_ERR_EXIST:
f73fabfd 164 ret = LTTNG_ERR_FILTER_EXIST;
53a80697
MD
165 break;
166 case -ENOMEM:
f73fabfd 167 ret = LTTNG_ERR_FATAL;
53a80697
MD
168 break;
169 case -EINVAL:
49c336c1 170 case -LTTNG_UST_ERR_INVAL:
f73fabfd 171 ret = LTTNG_ERR_FILTER_INVAL;
53a80697
MD
172 break;
173 case -ENOSYS:
49c336c1 174 case -LTTNG_UST_ERR_NOSYS:
f73fabfd 175 ret = LTTNG_ERR_UNKNOWN_DOMAIN;
53a80697
MD
176 break;
177 default:
f73fabfd 178 ret = LTTNG_OK;
53a80697
MD
179 break;
180 }
181
182error:
183 return ret;
184}
This page took 0.031281 seconds and 4 git commands to generate.