Fix: correctly close metadata on sessiond thread shutdown
[lttng-tools.git] / src / lib / lttng-ctl / snapshot.c
1 /*
2 * Copyright (C) 2013 - David Goulet <dgoulet@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 #define _GNU_SOURCE
19 #include <assert.h>
20 #include <string.h>
21
22 #include <common/sessiond-comm/sessiond-comm.h>
23 #include <lttng/lttng-error.h>
24 #include <lttng/snapshot.h>
25 #include <lttng/snapshot-internal.h>
26
27 #include "lttng-ctl-helper.h"
28
29 /*
30 * Add an output object to a session identified by name.
31 *
32 * Return 0 on success or else a negative LTTNG_ERR code.
33 */
34 int lttng_snapshot_add_output(const char *session_name,
35 struct lttng_snapshot_output *output)
36 {
37 int ret;
38 struct lttcomm_session_msg lsm;
39 struct lttcomm_lttng_output_id *reply;
40
41 if (!session_name || !output) {
42 return -LTTNG_ERR_INVALID;
43 }
44
45 memset(&lsm, 0, sizeof(lsm));
46 lsm.cmd_type = LTTNG_SNAPSHOT_ADD_OUTPUT;
47
48 lttng_ctl_copy_string(lsm.session.name, session_name,
49 sizeof(lsm.session.name));
50 memcpy(&lsm.u.snapshot_output.output, output,
51 sizeof(lsm.u.snapshot_output.output));
52
53 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &reply);
54 if (ret < 0) {
55 return ret;
56 }
57
58 output->id = reply->id;
59 free(reply);
60
61 return 0;
62 }
63
64 /*
65 * Delete an output object to a session identified by name.
66 *
67 * Return 0 on success or else a negative LTTNG_ERR code.
68 */
69 int lttng_snapshot_del_output(const char *session_name,
70 struct lttng_snapshot_output *output)
71 {
72 struct lttcomm_session_msg lsm;
73
74 if (!session_name || !output) {
75 return -LTTNG_ERR_INVALID;
76 }
77
78 memset(&lsm, 0, sizeof(lsm));
79 lsm.cmd_type = LTTNG_SNAPSHOT_DEL_OUTPUT;
80
81 lttng_ctl_copy_string(lsm.session.name, session_name,
82 sizeof(lsm.session.name));
83 memcpy(&lsm.u.snapshot_output.output, output,
84 sizeof(lsm.u.snapshot_output.output));
85
86 return lttng_ctl_ask_sessiond(&lsm, NULL);
87 }
88
89 /*
90 * List all snapshot output(s) of a session identified by name. The output list
91 * object is populated and can be iterated over with the get_next call below.
92 *
93 * Return 0 on success or else a negative LTTNG_ERR code and the list pointer
94 * is untouched.
95 */
96 int lttng_snapshot_list_output(const char *session_name,
97 struct lttng_snapshot_output_list **list)
98 {
99 int ret;
100 struct lttcomm_session_msg lsm;
101 struct lttng_snapshot_output_list *new_list = NULL;
102
103 if (!session_name || !list) {
104 ret = -LTTNG_ERR_INVALID;
105 goto error;
106 }
107
108 memset(&lsm, 0, sizeof(lsm));
109 lsm.cmd_type = LTTNG_SNAPSHOT_LIST_OUTPUT;
110
111 lttng_ctl_copy_string(lsm.session.name, session_name,
112 sizeof(lsm.session.name));
113
114 new_list = zmalloc(sizeof(*new_list));
115 if (!new_list) {
116 ret = -LTTNG_ERR_NOMEM;
117 goto error;
118 }
119
120 ret = lttng_ctl_ask_sessiond(&lsm, (void **) &new_list->array);
121 if (ret < 0) {
122 goto free_error;
123 }
124
125 new_list->count = ret / sizeof(struct lttng_snapshot_output);
126 *list = new_list;
127 return 0;
128
129 free_error:
130 free(new_list);
131 error:
132 return ret;
133 }
134
135 /*
136 * Return the next available snapshot output object in the given list. A list
137 * output command MUST have been done before.
138 *
139 * Return the next object on success or else NULL indicating the end of the
140 * list.
141 */
142 struct lttng_snapshot_output *lttng_snapshot_output_list_get_next(
143 struct lttng_snapshot_output_list *list)
144 {
145 struct lttng_snapshot_output *output = NULL;
146
147 if (!list) {
148 goto error;
149 }
150
151 /* We've reached the end. */
152 if (list->index == list->count) {
153 goto end;
154 }
155
156 output = &list->array[list->index];
157 list->index++;
158
159 end:
160 error:
161 return output;
162 }
163
164 /*
165 * Free an output list object.
166 */
167 void lttng_snapshot_output_list_destroy(struct lttng_snapshot_output_list *list)
168 {
169 if (!list) {
170 return;
171 }
172
173 free(list->array);
174 free(list);
175 }
176
177 /*
178 * Snapshot a trace for the given session.
179 *
180 * The output object can be NULL but an add output MUST be done prior to this
181 * call. If it's not NULL, it will be used to snapshot a trace.
182 *
183 * The wait parameter is ignored for now. The snapshot record command will
184 * ALWAYS wait for the snapshot to complete before returning meaning the
185 * snapshot has been written on disk or streamed over the network to a relayd.
186 *
187 * Return 0 on success or else a negative LTTNG_ERR value.
188 */
189 int lttng_snapshot_record(const char *session_name,
190 struct lttng_snapshot_output *output, int wait)
191 {
192 struct lttcomm_session_msg lsm;
193
194 if (!session_name) {
195 return -LTTNG_ERR_INVALID;
196 }
197
198 memset(&lsm, 0, sizeof(lsm));
199 lsm.cmd_type = LTTNG_SNAPSHOT_RECORD;
200
201 lttng_ctl_copy_string(lsm.session.name, session_name,
202 sizeof(lsm.session.name));
203
204 /*
205 * Not having an output object will use the default one of the session that
206 * would need to be set by a call to add output prior to calling snapshot
207 * record.
208 */
209 if (output) {
210 memcpy(&lsm.u.snapshot_record.output, output,
211 sizeof(lsm.u.snapshot_record.output));
212 }
213
214 /* The wait param is ignored. */
215
216 return lttng_ctl_ask_sessiond(&lsm, NULL);
217 }
218
219 /*
220 * Return an newly allocated snapshot output object or NULL on error.
221 */
222 struct lttng_snapshot_output *lttng_snapshot_output_create(void)
223 {
224 struct lttng_snapshot_output *output;
225
226 output = zmalloc(sizeof(struct lttng_snapshot_output));
227 if (!output) {
228 goto error;
229 }
230
231 output->max_size = (uint64_t) -1ULL;
232
233 error:
234 return output;
235 }
236
237 /*
238 * Free a given snapshot output object.
239 */
240 void lttng_snapshot_output_destroy(struct lttng_snapshot_output *obj)
241 {
242 if (obj) {
243 free(obj);
244 }
245 }
246
247 /*
248 * Getter family functions of snapshot output.
249 */
250
251 uint32_t lttng_snapshot_output_get_id(struct lttng_snapshot_output *output)
252 {
253 return output->id;
254 }
255
256 const char *lttng_snapshot_output_get_name(
257 struct lttng_snapshot_output *output)
258 {
259 return output->name;
260 }
261
262 const char *lttng_snapshot_output_get_data_url(struct lttng_snapshot_output *output)
263 {
264 return output->data_url;
265 }
266
267 const char *lttng_snapshot_output_get_ctrl_url(struct lttng_snapshot_output *output)
268 {
269 return output->ctrl_url;
270 }
271
272 uint64_t lttng_snapshot_output_get_maxsize(
273 struct lttng_snapshot_output *output)
274 {
275 return output->max_size;
276 }
277
278 /*
279 * Setter family functions for snapshot output.
280 */
281
282 int lttng_snapshot_output_set_id(uint32_t id,
283 struct lttng_snapshot_output *output)
284 {
285 if (!output || id == 0) {
286 return -LTTNG_ERR_INVALID;
287 }
288
289 output->id = id;
290 return 0;
291 }
292
293 int lttng_snapshot_output_set_size(uint64_t size,
294 struct lttng_snapshot_output *output)
295 {
296 if (!output) {
297 return -LTTNG_ERR_INVALID;
298 }
299
300 output->max_size = size;
301 return 0;
302 }
303
304 int lttng_snapshot_output_set_name(const char *name,
305 struct lttng_snapshot_output *output)
306 {
307 if (!output || !name) {
308 return -LTTNG_ERR_INVALID;
309 }
310
311 lttng_ctl_copy_string(output->name, name, sizeof(output->name));
312 return 0;
313 }
314
315 int lttng_snapshot_output_set_ctrl_url(const char *url,
316 struct lttng_snapshot_output *output)
317 {
318 if (!output || !url) {
319 return -LTTNG_ERR_INVALID;
320 }
321
322 lttng_ctl_copy_string(output->ctrl_url, url, sizeof(output->ctrl_url));
323 return 0;
324 }
325
326 int lttng_snapshot_output_set_data_url(const char *url,
327 struct lttng_snapshot_output *output)
328 {
329 if (!output || !url) {
330 return -LTTNG_ERR_INVALID;
331 }
332
333 lttng_ctl_copy_string(output->data_url, url, sizeof(output->data_url));
334 return 0;
335 }
This page took 0.036016 seconds and 4 git commands to generate.