Add lttng-error.h containing every API err. code
[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;
49
50 switch (domain) {
51 case LTTNG_DOMAIN_UST:
52 ret = ust_app_set_filter_event_glb(usess, uchan, uevent,
53 bytecode);
54 if (ret < 0) {
55 goto error;
56 }
57 break;
58 default:
59 ret = -ENOSYS;
60 goto error;
61 }
62
63 DBG("Filter UST added to event %s",uevent->attr.name);
64
65 return 0;
66
67error:
68 free(bytecode);
69 return ret;
70}
71
72/*
73 * Add UST context to tracer.
74 */
75int filter_ust_set(struct ltt_ust_session *usess, int domain,
76 struct lttng_filter_bytecode *bytecode, char *event_name,
77 char *channel_name)
78{
f73fabfd 79 int ret = LTTNG_OK, have_event = 0;
53a80697
MD
80 struct lttng_ht_iter iter;
81 struct lttng_ht *chan_ht;
82 struct ltt_ust_channel *uchan = NULL;
83 struct ltt_ust_event *uevent = NULL;
84
85 /*
86 * Define which channel's hashtable to use from the domain or quit if
87 * unknown domain.
88 */
89 switch (domain) {
90 case LTTNG_DOMAIN_UST:
91 chan_ht = usess->domain_global.channels;
92 break;
93#if 0
94 case LTTNG_DOMAIN_UST_EXEC_NAME:
95 case LTTNG_DOMAIN_UST_PID:
96 case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
97#endif
98 default:
f73fabfd 99 ret = LTTNG_ERR_UND;
53a80697
MD
100 goto error;
101 }
102
103 /* Do we have an event name */
104 if (strlen(event_name) != 0) {
105 have_event = 1;
106 }
107
108 /* Get UST channel if defined */
109 if (strlen(channel_name) != 0) {
110 uchan = trace_ust_find_channel_by_name(chan_ht, channel_name);
111 if (uchan == NULL) {
f73fabfd 112 ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
53a80697
MD
113 goto error;
114 }
115 }
116
117 /* If UST channel specified and event name, get UST event ref */
118 if (uchan && have_event) {
119 uevent = trace_ust_find_event_by_name(uchan->events, event_name);
120 if (uevent == NULL) {
f73fabfd 121 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
53a80697
MD
122 goto error;
123 }
124 }
125
126 /* At this point, we have 4 possibilities */
127
128 if (uchan && uevent) { /* Add filter to event in channel */
129 ret = add_ufilter_to_event(usess, domain, uchan, uevent,
130 bytecode);
131 } else if (uchan && !have_event) { /* Add filter to channel */
132 ERR("Cannot add filter to channel");
f73fabfd 133 ret = LTTNG_ERR_FATAL; /* not supported. */
53a80697
MD
134 goto error;
135 } else if (!uchan && have_event) { /* Add filter to event */
136 /* Add context to event without having the channel name */
137 cds_lfht_for_each_entry(chan_ht->ht, &iter.iter, uchan, node.node) {
138 uevent = trace_ust_find_event_by_name(uchan->events, event_name);
139 if (uevent != NULL) {
140 ret = add_ufilter_to_event(usess, domain, uchan, uevent, bytecode);
141 /*
142 * LTTng UST does not allowed the same event to be registered
143 * multiple time in different or the same channel. So, if we
144 * found our event, we stop.
145 */
146 goto end;
147 }
148 }
f73fabfd 149 ret = LTTNG_ERR_UST_EVENT_NOT_FOUND;
53a80697
MD
150 goto error;
151 } else if (!uchan && !have_event) { /* Add filter all events, all channels */
152 ERR("Cannot add filter to channel");
f73fabfd 153 ret = LTTNG_ERR_FATAL; /* not supported. */
53a80697
MD
154 goto error;
155 }
156
157end:
158 switch (ret) {
159 case -EEXIST:
f73fabfd 160 ret = LTTNG_ERR_FILTER_EXIST;
53a80697
MD
161 break;
162 case -ENOMEM:
f73fabfd 163 ret = LTTNG_ERR_FATAL;
53a80697
MD
164 break;
165 case -EINVAL:
f73fabfd 166 ret = LTTNG_ERR_FILTER_INVAL;
53a80697
MD
167 break;
168 case -ENOSYS:
f73fabfd 169 ret = LTTNG_ERR_UNKNOWN_DOMAIN;
53a80697
MD
170 break;
171 default:
f73fabfd 172 ret = LTTNG_OK;
53a80697
MD
173 break;
174 }
175
176error:
177 return ret;
178}
This page took 0.02982 seconds and 4 git commands to generate.