lttng-ctl: Implement the buffer usage condition interface
[lttng-tools.git] / src / lib / lttng-ctl / buffer-usage.c
1 /*
2 * Copyright (C) 2017 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License, version 2.1 only,
6 * as published by the Free Software Foundation.
7 *
8 * This library 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 Lesser General Public License
11 * for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18 #include <lttng/condition/condition-internal.h>
19 #include <lttng/condition/buffer-usage-internal.h>
20 #include <common/macros.h>
21 #include <assert.h>
22
23 static
24 bool is_usage_condition(struct lttng_condition *condition)
25 {
26 enum lttng_condition_type type = lttng_condition_get_type(condition);
27
28 return type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW ||
29 type == LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH;
30 }
31
32 static
33 bool is_usage_condition(struct lttng_condition *condition)
34 {
35 return is_low_usage_condition(condition) ||
36 is_high_usage_condition(condition);
37 }
38
39 static
40 void lttng_condition_buffer_usage_destroy(struct lttng_condition *condition)
41 {
42 struct lttng_condition_buffer_usage *usage;
43
44 usage = container_of(condition, struct lttng_condition_buffer_usage,
45 parent);
46
47 free(usage->session_name);
48 free(usage->channel_name);
49 free(usage);
50 }
51
52 static
53 bool lttng_condition_buffer_usage_validate(struct lttng_condition *condition)
54 {
55 bool valid = false;
56 struct lttng_condition_buffer_usage *usage;
57
58 if (!condition) {
59 goto end;
60 }
61
62 usage = container_of(condition, struct lttng_condition_buffer_usage,
63 parent);
64 if (!usage->session_name) {
65 goto end;
66 }
67 if (!usage->channel_name) {
68 goto end;
69 }
70 if (!usage->threshold_percent.set && !usage->threshold_bytes.set) {
71 goto end;
72 }
73
74 valid = true;
75 end:
76 return valid;
77 }
78
79 static
80 struct lttng_condition *lttng_condition_buffer_usage_create(
81 enum lttng_condition_type type)
82 {
83 struct lttng_condition_buffer_usage *condition;
84
85 condition = zmalloc(sizeof(struct lttng_condition_buffer_usage));
86 if (!condition) {
87 goto end;
88 }
89
90 condition->parent.type = type;
91 condition->parent.validate = lttng_condition_buffer_usage_validate;
92 condition->parent.destroy = lttng_condition_buffer_usage_destroy;
93 end:
94 return &condition->parent;
95 }
96
97 struct lttng_condition *lttng_condition_buffer_usage_low_create(void)
98 {
99 return lttng_condition_buffer_usage_create(
100 LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW);
101 }
102
103 struct lttng_condition *lttng_condition_buffer_usage_high_create(void)
104 {
105 return lttng_condition_buffer_usage_create(
106 LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH);
107 }
108
109 enum lttng_condition_status
110 lttng_condition_buffer_usage_get_threshold_percentage(
111 struct lttng_condition *condition, double *threshold_percent)
112 {
113 struct lttng_condition_buffer_usage *usage;
114 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
115
116 if (!condition || !is_usage_condition(condition) ||
117 !threshold_percent) {
118 status = LTTNG_CONDITION_STATUS_INVALID;
119 goto end;
120 }
121
122 usage = container_of(condition, struct lttng_condition_buffer_usage,
123 parent);
124 if (!usage->threshold_percent.set) {
125 status = LTTNG_CONDITION_STATUS_UNSET;
126 goto end;
127 }
128 *threshold_percent = usage->threshold_percent.value;
129 end:
130 return status;
131 }
132
133 /* threshold_percent expressed as [0.0, 1.0]. */
134 enum lttng_condition_status
135 lttng_condition_buffer_usage_set_threshold_percentage(
136 struct lttng_condition *condition, double threshold_percent)
137 {
138 struct lttng_condition_buffer_usage *usage;
139 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
140
141 if (!condition || !is_usage_condition(condition) ||
142 threshold_percent < 0.0 || threshold_percent > 1.0) {
143 status = LTTNG_CONDITION_STATUS_INVALID;
144 goto end;
145 }
146
147 usage = container_of(condition, struct lttng_condition_buffer_usage,
148 parent);
149 usage->threshold_percent.set = true;
150 usage->threshold_bytes.set = false;
151 usage->threshold_percent.value = threshold_percent;
152 end:
153 return status;
154 }
155
156 enum lttng_condition_status
157 lttng_condition_buffer_usage_get_threshold(
158 struct lttng_condition *condition, uint64_t *threshold_bytes)
159 {
160 struct lttng_condition_buffer_usage *usage;
161 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
162
163 if (!condition || !is_usage_condition(condition) || !threshold_bytes) {
164 status = LTTNG_CONDITION_STATUS_INVALID;
165 goto end;
166 }
167
168 usage = container_of(condition, struct lttng_condition_buffer_usage,
169 parent);
170 if (!usage->threshold_bytes.set) {
171 status = LTTNG_CONDITION_STATUS_UNSET;
172 goto end;
173 }
174 *threshold_bytes = usage->threshold_bytes.value;
175 end:
176 return status;
177 }
178
179 enum lttng_condition_status
180 lttng_condition_buffer_usage_set_threshold(
181 struct lttng_condition *condition, uint64_t threshold_bytes)
182 {
183 struct lttng_condition_buffer_usage *usage;
184 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
185
186 if (!condition || !is_usage_condition(condition)) {
187 status = LTTNG_CONDITION_STATUS_INVALID;
188 goto end;
189 }
190
191 usage = container_of(condition, struct lttng_condition_buffer_usage,
192 parent);
193 usage->threshold_percent.set = false;
194 usage->threshold_bytes.set = true;
195 usage->threshold_bytes.value = threshold_bytes;
196 end:
197 return status;
198 }
199
200 enum lttng_condition_status
201 lttng_condition_buffer_usage_get_session_name(
202 struct lttng_condition *condition, const char **session_name)
203 {
204 struct lttng_condition_buffer_usage *usage;
205 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
206
207 if (!condition || !is_usage_condition(condition) || !session_name) {
208 status = LTTNG_CONDITION_STATUS_INVALID;
209 goto end;
210 }
211
212 usage = container_of(condition, struct lttng_condition_buffer_usage,
213 parent);
214 if (!usage->session_name) {
215 status = LTTNG_CONDITION_STATUS_UNSET;
216 goto end;
217 }
218 *session_name = usage->session_name;
219 end:
220 return status;
221 }
222
223 extern enum lttng_condition_status
224 lttng_condition_buffer_usage_set_session_name(
225 struct lttng_condition *condition, const char *session_name)
226 {
227 struct lttng_condition_buffer_usage *usage;
228 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
229
230 if (!condition || !is_usage_condition(condition) || !session_name ||
231 strlen(session_name) == 0) {
232 status = LTTNG_CONDITION_STATUS_INVALID;
233 goto end;
234 }
235
236 usage = container_of(condition, struct lttng_condition_buffer_usage,
237 parent);
238 usage->session_name = strdup(session_name);
239 if (!usage->session_name) {
240 status = LTTNG_CONDITION_STATUS_ERROR;
241 goto end;
242 }
243 end:
244 return status;
245 }
246
247 enum lttng_condition_status
248 lttng_condition_buffer_usage_get_channel_name(
249 struct lttng_condition *condition, const char **channel_name)
250 {
251 struct lttng_condition_buffer_usage *usage;
252 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
253
254 if (!condition || !is_usage_condition(condition) || !channel_name) {
255 status = LTTNG_CONDITION_STATUS_INVALID;
256 goto end;
257 }
258
259 usage = container_of(condition, struct lttng_condition_buffer_usage,
260 parent);
261 if (!usage->channel_name) {
262 status = LTTNG_CONDITION_STATUS_UNSET;
263 goto end;
264 }
265 *channel_name = usage->channel_name;
266 end:
267 return status;
268 }
269
270 extern enum lttng_condition_status
271 lttng_condition_buffer_usage_set_channel_name(
272 struct lttng_condition *condition, const char *channel_name)
273 {
274 struct lttng_condition_buffer_usage *usage;
275 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
276
277 if (!condition || !is_usage_condition(condition) || !channel_name ||
278 strlen(channel_name) == 0) {
279 status = LTTNG_CONDITION_STATUS_INVALID;
280 goto end;
281 }
282
283 usage = container_of(condition, struct lttng_condition_buffer_usage,
284 parent);
285 usage->channel_name = strdup(channel_name);
286 if (!usage->channel_name) {
287 status = LTTNG_CONDITION_STATUS_ERROR;
288 goto end;
289 }
290 end:
291 return status;
292 }
293
294 extern enum lttng_condition_status
295 lttng_condition_buffer_usage_get_domain_type(
296 struct lttng_condition *condition, enum lttng_domain_type *type)
297 {
298 struct lttng_condition_buffer_usage *usage;
299 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
300
301 if (!condition || !is_usage_condition(condition) || !type) {
302 status = LTTNG_CONDITION_STATUS_INVALID;
303 goto end;
304 }
305
306 usage = container_of(condition, struct lttng_condition_buffer_usage,
307 parent);
308 if (!usage->domain.set) {
309 status = LTTNG_CONDITION_STATUS_UNSET;
310 goto end;
311 }
312 *type = usage->domain.type;
313 end:
314 return status;
315 }
316
317 extern enum lttng_condition_status
318 lttng_condition_buffer_usage_set_domain_type(
319 struct lttng_condition *condition, enum lttng_domain_type type)
320 {
321 struct lttng_condition_buffer_usage *usage;
322 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
323
324 if (!condition || !is_usage_condition(condition) ||
325 type == LTTNG_DOMAIN_NONE) {
326 status = LTTNG_CONDITION_STATUS_INVALID;
327 goto end;
328 }
329
330 usage = container_of(condition, struct lttng_condition_buffer_usage,
331 parent);
332 usage->domain.set = true;
333 usage->domain.type = type;
334 end:
335 return status;
336 }
This page took 0.047611 seconds and 5 git commands to generate.