MI: implement all objects related to trigger machine interface
[lttng-tools.git] / src / common / snapshot.c
1 /*
2 * Copyright (C) 2020 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #include <common/error.h>
9 #include <common/mi-lttng.h>
10 #include <common/payload-view.h>
11 #include <common/payload.h>
12 #include <common/snapshot.h>
13 #include <lttng/snapshot-internal.h>
14 #include <lttng/snapshot.h>
15
16 #include <assert.h>
17 #include <stdlib.h>
18
19 LTTNG_HIDDEN
20 bool lttng_snapshot_output_validate(const struct lttng_snapshot_output *output)
21 {
22 bool valid = false;
23 size_t len;
24
25 /*
26 * It is mandatory to have a ctrl_url. If there is only one output
27 * URL (in the net://, net6:// or file:// form), it will be in this
28 * field.
29 */
30 len = lttng_strnlen(output->ctrl_url, sizeof(output->ctrl_url));
31 if (len == 0 || len >= sizeof(output->ctrl_url)) {
32 goto end;
33 }
34
35 len = lttng_strnlen(output->data_url, sizeof(output->data_url));
36 if (len >= sizeof(output->data_url)) {
37 goto end;
38 }
39
40 len = lttng_strnlen(output->name, sizeof(output->name));
41 if (len >= sizeof(output->name)) {
42 goto end;
43 }
44
45 valid = true;
46
47 end:
48 return valid;
49 }
50
51 LTTNG_HIDDEN
52 bool lttng_snapshot_output_is_equal(
53 const struct lttng_snapshot_output *a,
54 const struct lttng_snapshot_output *b)
55 {
56 bool equal = false;
57
58 assert(a);
59 assert(b);
60
61 if (a->max_size != b->max_size) {
62 goto end;
63 }
64
65 if (strcmp(a->name, b->name) != 0) {
66 goto end;
67 }
68
69 if (strcmp(a->ctrl_url, b->ctrl_url) != 0) {
70 goto end;
71 }
72
73 if (strcmp(a->data_url, b->data_url) != 0) {
74 goto end;
75 }
76
77 equal = true;
78
79 end:
80 return equal;
81 }
82
83 /*
84 * This is essentially the same as `struct lttng_snapshot_output`, but packed.
85 */
86 struct lttng_snapshot_output_comm {
87 uint32_t id;
88 uint64_t max_size;
89 char name[LTTNG_NAME_MAX];
90 char ctrl_url[PATH_MAX];
91 char data_url[PATH_MAX];
92 } LTTNG_PACKED;
93
94 LTTNG_HIDDEN
95 int lttng_snapshot_output_serialize(
96 const struct lttng_snapshot_output *output,
97 struct lttng_payload *payload)
98 {
99 struct lttng_snapshot_output_comm comm;
100 int ret;
101
102 comm.id = output->id;
103 comm.max_size = output->max_size;
104
105 ret = lttng_strncpy(comm.name, output->name, sizeof(comm.name));
106 if (ret) {
107 goto end;
108 }
109
110 ret = lttng_strncpy(
111 comm.ctrl_url, output->ctrl_url, sizeof(comm.ctrl_url));
112 if (ret) {
113 goto end;
114 }
115
116 ret = lttng_strncpy(
117 comm.data_url, output->data_url, sizeof(comm.data_url));
118 if (ret) {
119 goto end;
120 }
121
122 ret = lttng_dynamic_buffer_append(
123 &payload->buffer, &comm, sizeof(comm));
124 if (ret) {
125 goto end;
126 }
127
128 end:
129 return ret;
130 }
131
132 LTTNG_HIDDEN
133 ssize_t lttng_snapshot_output_create_from_payload(
134 struct lttng_payload_view *view,
135 struct lttng_snapshot_output **output_p)
136 {
137 const struct lttng_snapshot_output_comm *comm;
138 struct lttng_snapshot_output *output = NULL;
139 int ret;
140
141 if (view->buffer.size != sizeof(*comm)) {
142 ret = -1;
143 goto end;
144 }
145
146 output = lttng_snapshot_output_create();
147 if (!output) {
148 ret = -1;
149 goto end;
150 }
151
152 comm = (typeof(comm)) view->buffer.data;
153
154 output->id = comm->id;
155 output->max_size = comm->max_size;
156
157 ret = lttng_strncpy(output->name, comm->name, sizeof(output->name));
158 if (ret) {
159 goto end;
160 }
161
162 ret = lttng_strncpy(output->ctrl_url, comm->ctrl_url,
163 sizeof(output->ctrl_url));
164 if (ret) {
165 goto end;
166 }
167
168 ret = lttng_strncpy(output->data_url, comm->data_url,
169 sizeof(output->data_url));
170 if (ret) {
171 goto end;
172 }
173
174 *output_p = output;
175 output = NULL;
176 ret = sizeof(*comm);
177
178 end:
179 lttng_snapshot_output_destroy(output);
180 return ret;
181 }
182
183 LTTNG_HIDDEN
184 enum lttng_error_code lttng_snapshot_output_mi_serialize(
185 const struct lttng_snapshot_output *output,
186 struct mi_writer *writer)
187 {
188 int ret;
189 enum lttng_error_code ret_code;
190
191 assert(output);
192 assert(writer);
193
194 /* Open output element. */
195 ret = mi_lttng_writer_open_element(writer,
196 mi_lttng_element_action_snapshot_session_output);
197 if (ret) {
198 goto mi_error;
199 }
200
201 /* Name. */
202 if (strnlen(output->name, LTTNG_NAME_MAX) != 0) {
203 ret = mi_lttng_writer_write_element_string(
204 writer, config_element_name, output->name);
205 if (ret) {
206 goto mi_error;
207 }
208 }
209
210 /* Control url (always present). */
211 ret = mi_lttng_writer_write_element_string(writer,
212 mi_lttng_element_snapshot_ctrl_url, output->ctrl_url);
213 if (ret) {
214 goto mi_error;
215 }
216
217 /* Data url (optional). */
218 if (strnlen(output->data_url, PATH_MAX) != 0) {
219 ret = mi_lttng_writer_write_element_string(writer,
220 mi_lttng_element_snapshot_data_url,
221 output->data_url);
222 if (ret) {
223 goto mi_error;
224 }
225 }
226
227 /*
228 * Maximum size in bytes of the snapshot meaning the total size of all
229 * streams combined. A value of 0 means unlimited. The default value is
230 * UINT64_MAX which also means unlimited in practice.
231 *
232 * The value is not serialized when it is set to either of those values
233 * to normalize them to '0'.
234 */
235 if (output->max_size > 0 && output->max_size != UINT64_MAX) {
236 /* Total size of all stream combined. */
237 ret = mi_lttng_writer_write_element_unsigned_int(writer,
238 mi_lttng_element_snapshot_max_size,
239 output->max_size);
240 if (ret) {
241 goto mi_error;
242 }
243 }
244
245 /* Close output element. */
246 ret = mi_lttng_writer_close_element(writer);
247 if (ret) {
248 goto mi_error;
249 }
250
251 ret_code = LTTNG_OK;
252 goto end;
253
254 mi_error:
255 ret_code = LTTNG_ERR_MI_IO_FAIL;
256 end:
257 return ret_code;
258 }
This page took 0.034363 seconds and 4 git commands to generate.