copytrace: option to skip the copy of packet/content size
[babeltrace.git] / plugins / ctf / fs-sink / write.c
CommitLineData
bc506aa5
JD
1/*
2 * writer.c
3 *
4 * Babeltrace CTF Writer Output Plugin Event Handling
5 *
6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29#include <babeltrace/ctf-ir/event.h>
30#include <babeltrace/ctf-ir/packet.h>
31#include <babeltrace/ctf-ir/event-class.h>
32#include <babeltrace/ctf-ir/stream.h>
33#include <babeltrace/ctf-ir/stream-class.h>
ac0c6bdd 34#include <babeltrace/ctf-ir/clock-class.h>
bc506aa5
JD
35#include <babeltrace/ctf-ir/fields.h>
36#include <babeltrace/ctf-writer/stream-class.h>
37#include <babeltrace/ctf-writer/stream.h>
38
91b73004
JD
39#include <ctfcopytrace.h>
40
bc506aa5
JD
41#include "writer.h"
42
bc506aa5 43static
91b73004
JD
44struct bt_ctf_stream_class *insert_new_stream_class(
45 struct writer_component *writer_component,
46 struct bt_ctf_writer *ctf_writer,
47 struct bt_ctf_stream_class *stream_class)
bc506aa5 48{
b2f1f465 49 struct bt_ctf_stream_class *writer_stream_class = NULL;
9ae49d3d 50 struct bt_ctf_trace *trace = NULL, *writer_trace = NULL;
3241bc18 51 enum bt_component_status ret;
bc506aa5 52
3241bc18
JD
53 trace = bt_ctf_stream_class_get_trace(stream_class);
54 if (!trace) {
91b73004
JD
55 fprintf(writer_component->err,
56 "[error] %s in %s:%d\n", __func__, __FILE__,
bc506aa5 57 __LINE__);
9ae49d3d 58 goto error;
bc506aa5
JD
59 }
60
91b73004
JD
61 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
62 if (!writer_trace) {
91b73004
JD
63 fprintf(writer_component->err,
64 "[error] %s in %s:%d\n", __func__, __FILE__,
d00b90bf 65 __LINE__);
9ae49d3d 66 goto error;
bc506aa5
JD
67 }
68
91b73004
JD
69 ret = ctf_copy_clock_classes(writer_component->err, writer_trace,
70 writer_stream_class, trace);
bc506aa5 71 if (ret != BT_COMPONENT_STATUS_OK) {
91b73004
JD
72 fprintf(writer_component->err,
73 "[error] %s in %s:%d\n", __func__, __FILE__,
bc506aa5 74 __LINE__);
9ae49d3d 75 goto error;
b2f1f465
JD
76 }
77
78 writer_stream_class = ctf_copy_stream_class(writer_component->err,
79 stream_class, writer_trace, true);
80 if (!writer_stream_class) {
81 fprintf(writer_component->err, "[error] Failed to copy stream class\n");
82 fprintf(writer_component->err, "[error] %s in %s:%d\n",
83 __func__, __FILE__, __LINE__);
9ae49d3d 84 goto error;
bc506aa5 85 }
bc506aa5 86
bc506aa5
JD
87 g_hash_table_insert(writer_component->stream_class_map,
88 (gpointer) stream_class, writer_stream_class);
89
9ae49d3d
JD
90 goto end;
91
92error:
93 BT_PUT(writer_stream_class);
94end:
b2f1f465 95 bt_put(writer_trace);
b2f1f465 96 bt_put(trace);
bc506aa5
JD
97 return writer_stream_class;
98}
99
100static
101struct bt_ctf_stream *insert_new_stream(
102 struct writer_component *writer_component,
103 struct bt_ctf_writer *ctf_writer,
104 struct bt_ctf_stream_class *stream_class,
105 struct bt_ctf_stream *stream)
106{
9ae49d3d
JD
107 struct bt_ctf_stream *writer_stream = NULL;
108 struct bt_ctf_stream_class *writer_stream_class = NULL;
bc506aa5
JD
109
110 writer_stream_class = g_hash_table_lookup(
111 writer_component->stream_class_map,
112 (gpointer) stream_class);
9ae49d3d 113 if (!writer_stream_class) {
bc506aa5
JD
114 writer_stream_class = insert_new_stream_class(
115 writer_component, ctf_writer, stream_class);
116 if (!writer_stream_class) {
bc506aa5
JD
117 fprintf(writer_component->err, "[error] %s in %s:%d\n",
118 __func__, __FILE__, __LINE__);
9ae49d3d 119 goto error;
bc506aa5
JD
120 }
121 }
9ae49d3d 122 bt_get(writer_stream_class);
bc506aa5
JD
123
124 writer_stream = bt_ctf_writer_create_stream(ctf_writer,
125 writer_stream_class);
126 if (!writer_stream) {
127 fprintf(writer_component->err, "[error] %s in %s:%d\n",
128 __func__, __FILE__, __LINE__);
9ae49d3d 129 goto error;
bc506aa5
JD
130 }
131
132 g_hash_table_insert(writer_component->stream_map, (gpointer) stream,
133 writer_stream);
134
9ae49d3d 135 goto end;
bc506aa5 136
9ae49d3d
JD
137error:
138 BT_PUT(writer_stream);
bc506aa5 139end:
9ae49d3d 140 bt_put(writer_stream_class);
bc506aa5
JD
141 return writer_stream;
142}
143
144static
145struct bt_ctf_stream *lookup_stream(struct writer_component *writer_component,
146 struct bt_ctf_stream *stream)
147{
148 return (struct bt_ctf_stream *) g_hash_table_lookup(
149 writer_component->stream_map,
150 (gpointer) stream);
151}
152
153static
154struct bt_ctf_event_class *get_event_class(struct writer_component *writer_component,
155 struct bt_ctf_stream_class *writer_stream_class,
156 struct bt_ctf_event_class *event_class)
157{
a9f0d01b
PP
158 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class,
159 bt_ctf_event_class_get_id(event_class));
bc506aa5
JD
160}
161
162struct bt_ctf_writer *insert_new_writer(
163 struct writer_component *writer_component,
164 struct bt_ctf_trace *trace)
165{
9ae49d3d
JD
166 struct bt_ctf_writer *ctf_writer = NULL;
167 struct bt_ctf_trace *writer_trace = NULL;
bc506aa5
JD
168 char trace_name[PATH_MAX];
169 enum bt_component_status ret;
170
9ae49d3d 171 /* FIXME: replace with trace name when it will work. */
bc506aa5 172 snprintf(trace_name, PATH_MAX, "%s/%s_%03d",
9057f037
JD
173 writer_component->base_path->str,
174 writer_component->trace_name_base->str,
bc506aa5
JD
175 writer_component->trace_id++);
176 printf_verbose("CTF-Writer creating trace in %s\n", trace_name);
9057f037 177
bc506aa5
JD
178 ctf_writer = bt_ctf_writer_create(trace_name);
179 if (!ctf_writer) {
180 fprintf(writer_component->err, "[error] %s in %s:%d\n",
181 __func__, __FILE__, __LINE__);
9ae49d3d 182 goto error;
bc506aa5
JD
183 }
184
91b73004
JD
185 writer_trace = bt_ctf_writer_get_trace(ctf_writer);
186 if (!writer_trace) {
91b73004
JD
187 fprintf(writer_component->err,
188 "[error] %s in %s:%d\n", __func__, __FILE__,
189 __LINE__);
9ae49d3d 190 goto error;
91b73004
JD
191 }
192
193 ret = ctf_copy_trace(writer_component->err, trace, writer_trace);
bc506aa5
JD
194 if (ret != BT_COMPONENT_STATUS_OK) {
195 fprintf(writer_component->err, "[error] Failed to copy trace\n");
196 fprintf(writer_component->err, "[error] %s in %s:%d\n",
197 __func__, __FILE__, __LINE__);
198 BT_PUT(ctf_writer);
199 goto end;
200 }
9ae49d3d 201 BT_PUT(writer_trace);
bc506aa5
JD
202
203 g_hash_table_insert(writer_component->trace_map, (gpointer) trace,
204 ctf_writer);
205
9ae49d3d
JD
206 goto end;
207
208error:
209 bt_put(writer_trace);
210 BT_PUT(ctf_writer);
bc506aa5
JD
211end:
212 return ctf_writer;
213}
214
215static
216struct bt_ctf_writer *get_writer(struct writer_component *writer_component,
217 struct bt_ctf_stream_class *stream_class)
218{
9ae49d3d
JD
219 struct bt_ctf_trace *trace = NULL;
220 struct bt_ctf_writer *ctf_writer = NULL;
bc506aa5
JD
221
222 trace = bt_ctf_stream_class_get_trace(stream_class);
223 if (!trace) {
224 ctf_writer = NULL;
225 fprintf(writer_component->err, "[error] %s in %s:%d\n",
226 __func__, __FILE__, __LINE__);
9ae49d3d 227 goto error;
bc506aa5
JD
228 }
229
230 ctf_writer = g_hash_table_lookup(writer_component->trace_map,
231 (gpointer) trace);
9ae49d3d 232 if (!ctf_writer) {
bc506aa5
JD
233 ctf_writer = insert_new_writer(writer_component, trace);
234 }
9ae49d3d
JD
235 bt_get(ctf_writer);
236 BT_PUT(trace);
237 goto end;
bc506aa5 238
9ae49d3d
JD
239error:
240 BT_PUT(ctf_writer);
bc506aa5
JD
241end:
242 return ctf_writer;
243}
244
245static
246struct bt_ctf_stream *get_writer_stream(
247 struct writer_component *writer_component,
248 struct bt_ctf_packet *packet, struct bt_ctf_stream *stream)
249{
9ae49d3d
JD
250 struct bt_ctf_stream_class *stream_class = NULL;
251 struct bt_ctf_writer *ctf_writer = NULL;
252 struct bt_ctf_stream *writer_stream = NULL;
bc506aa5
JD
253
254 stream_class = bt_ctf_stream_get_class(stream);
255 if (!stream_class) {
bc506aa5
JD
256 fprintf(writer_component->err, "[error] %s in %s:%d\n",
257 __func__, __FILE__, __LINE__);
9ae49d3d 258 goto error;
bc506aa5
JD
259 }
260
261 ctf_writer = get_writer(writer_component, stream_class);
262 if (!ctf_writer) {
bc506aa5
JD
263 fprintf(writer_component->err, "[error] %s in %s:%d\n",
264 __func__, __FILE__, __LINE__);
9ae49d3d 265 goto error;
bc506aa5
JD
266 }
267
268 writer_stream = lookup_stream(writer_component, stream);
9ae49d3d 269 if (!writer_stream) {
bc506aa5
JD
270 writer_stream = insert_new_stream(writer_component, ctf_writer,
271 stream_class, stream);
272 }
9ae49d3d
JD
273 bt_get(writer_stream);
274
275 goto end;
bc506aa5 276
9ae49d3d
JD
277error:
278 BT_PUT(writer_stream);
279end:
bc506aa5 280 bt_put(ctf_writer);
bc506aa5 281 bt_put(stream_class);
bc506aa5
JD
282 return writer_stream;
283}
284
285BT_HIDDEN
286enum bt_component_status writer_new_packet(
287 struct writer_component *writer_component,
288 struct bt_ctf_packet *packet)
289{
9ae49d3d
JD
290 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
291 struct bt_ctf_field *writer_packet_context = NULL;
bc506aa5 292 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
b2f1f465 293 int int_ret;
bc506aa5
JD
294
295 stream = bt_ctf_packet_get_stream(packet);
296 if (!stream) {
bc506aa5
JD
297 fprintf(writer_component->err, "[error] %s in %s:%d\n",
298 __func__, __FILE__, __LINE__);
9ae49d3d 299 goto error;
bc506aa5
JD
300 }
301
bc506aa5
JD
302 writer_stream = get_writer_stream(writer_component, packet, stream);
303 if (!writer_stream) {
bc506aa5
JD
304 fprintf(writer_component->err, "[error] %s in %s:%d\n",
305 __func__, __FILE__, __LINE__);
9ae49d3d 306 goto error;
bc506aa5 307 }
9ae49d3d 308 BT_PUT(stream);
bc506aa5 309
b2f1f465 310 writer_packet_context = ctf_copy_packet_context(writer_component->err,
ab80adac 311 packet, writer_stream, 1);
b2f1f465 312 if (!writer_packet_context) {
91b73004
JD
313 fprintf(writer_component->err, "[error] %s in %s:%d\n",
314 __func__, __FILE__, __LINE__);
9ae49d3d 315 goto error;
bc506aa5
JD
316 }
317
b2f1f465
JD
318 int_ret = bt_ctf_stream_set_packet_context(writer_stream,
319 writer_packet_context);
320 if (int_ret < 0) {
b2f1f465
JD
321 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
322 __FILE__, __LINE__);
9ae49d3d 323 goto error;
b2f1f465 324 }
9ae49d3d
JD
325 BT_PUT(writer_stream);
326 BT_PUT(writer_packet_context);
b2f1f465 327
9ae49d3d 328 goto end;
bc506aa5 329
9ae49d3d
JD
330error:
331 ret = BT_COMPONENT_STATUS_ERROR;
332end:
333 bt_put(writer_stream);
b2f1f465 334 bt_put(writer_packet_context);
91b73004 335 bt_put(stream);
bc506aa5
JD
336 return ret;
337}
338
339BT_HIDDEN
340enum bt_component_status writer_close_packet(
341 struct writer_component *writer_component,
342 struct bt_ctf_packet *packet)
343{
9ae49d3d 344 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
bc506aa5
JD
345 enum bt_component_status ret;
346
347 stream = bt_ctf_packet_get_stream(packet);
348 if (!stream) {
bc506aa5
JD
349 fprintf(writer_component->err, "[error] %s in %s:%d\n",
350 __func__, __FILE__, __LINE__);
9ae49d3d 351 goto error;
bc506aa5
JD
352 }
353
354 writer_stream = lookup_stream(writer_component, stream);
355 if (!writer_stream) {
bc506aa5
JD
356 fprintf(writer_component->err, "[error] %s in %s:%d\n",
357 __func__, __FILE__, __LINE__);
9ae49d3d 358 goto error;
bc506aa5 359 }
9ae49d3d 360 BT_PUT(stream);
bc506aa5 361
9ae49d3d 362 bt_get(writer_stream);
bc506aa5 363
bc506aa5
JD
364 ret = bt_ctf_stream_flush(writer_stream);
365 if (ret < 0) {
366 fprintf(writer_component->err,
367 "[error] Failed to flush packet\n");
9ae49d3d 368 goto error;
bc506aa5 369 }
9ae49d3d 370 BT_PUT(writer_stream);
bc506aa5
JD
371
372 ret = BT_COMPONENT_STATUS_OK;
9ae49d3d 373 goto end;
bc506aa5 374
9ae49d3d
JD
375error:
376 ret = BT_COMPONENT_STATUS_ERROR;
377end:
bc506aa5 378 bt_put(writer_stream);
bc506aa5 379 bt_put(stream);
bc506aa5
JD
380 return ret;
381}
382
bc506aa5
JD
383BT_HIDDEN
384enum bt_component_status writer_output_event(
385 struct writer_component *writer_component,
386 struct bt_ctf_event *event)
387{
388 enum bt_component_status ret;
9ae49d3d
JD
389 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
390 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
391 struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL;
392 struct bt_ctf_event *writer_event = NULL;
bc506aa5
JD
393 const char *event_name;
394 int int_ret;
395
396 event_class = bt_ctf_event_get_class(event);
397 if (!event_class) {
bc506aa5
JD
398 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
399 __FILE__, __LINE__);
9ae49d3d 400 goto error;
bc506aa5
JD
401 }
402
403 event_name = bt_ctf_event_class_get_name(event_class);
404 if (!event_name) {
bc506aa5
JD
405 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
406 __FILE__, __LINE__);
9ae49d3d 407 goto error;
bc506aa5 408 }
bc506aa5
JD
409
410 stream = bt_ctf_event_get_stream(event);
411 if (!stream) {
bc506aa5
JD
412 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
413 __FILE__, __LINE__);
9ae49d3d 414 goto error;
bc506aa5
JD
415 }
416
417 writer_stream = lookup_stream(writer_component, stream);
418 if (!writer_stream || !bt_get(writer_stream)) {
bc506aa5
JD
419 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
420 __FILE__, __LINE__);
9ae49d3d 421 goto error;
bc506aa5
JD
422 }
423
424 stream_class = bt_ctf_event_class_get_stream_class(event_class);
425 if (!stream_class) {
bc506aa5
JD
426 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
427 __FILE__, __LINE__);
9ae49d3d 428 goto error;
bc506aa5
JD
429 }
430
431 writer_stream_class = g_hash_table_lookup(
432 writer_component->stream_class_map,
433 (gpointer) stream_class);
434 if (!writer_stream_class || !bt_get(writer_stream_class)) {
bc506aa5
JD
435 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
436 __FILE__, __LINE__);
9ae49d3d 437 goto error;
bc506aa5
JD
438 }
439
440 writer_event_class = get_event_class(writer_component,
441 writer_stream_class, event_class);
442 if (!writer_event_class) {
af34e875
JD
443 writer_event_class = ctf_copy_event_class(writer_component->err,
444 event_class);
445 if (!writer_event_class) {
af34e875
JD
446 fprintf(writer_component->err, "[error] %s in %s:%d\n",
447 __func__, __FILE__, __LINE__);
9ae49d3d 448 goto error;
af34e875
JD
449 }
450 int_ret = bt_ctf_stream_class_add_event_class(
451 writer_stream_class, writer_event_class);
452 if (int_ret) {
af34e875
JD
453 fprintf(writer_component->err, "[error] %s in %s:%d\n",
454 __func__, __FILE__, __LINE__);
9ae49d3d 455 goto error;
af34e875 456 }
bc506aa5
JD
457 }
458
b2f1f465
JD
459 writer_event = ctf_copy_event(writer_component->err, event,
460 writer_event_class, true);
bc506aa5 461 if (!writer_event) {
bc506aa5
JD
462 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
463 __FILE__, __LINE__);
464 fprintf(writer_component->err, "[error] Failed to copy event %s\n",
465 bt_ctf_event_class_get_name(writer_event_class));
9ae49d3d 466 goto error;
bc506aa5
JD
467 }
468
469 int_ret = bt_ctf_stream_append_event(writer_stream, writer_event);
470 if (int_ret < 0) {
bc506aa5
JD
471 fprintf(writer_component->err, "[error] %s in %s:%d\n", __func__,
472 __FILE__, __LINE__);
473 fprintf(writer_component->err, "[error] Failed to append event %s\n",
474 bt_ctf_event_class_get_name(writer_event_class));
9ae49d3d 475 goto error;
bc506aa5
JD
476 }
477
478 ret = BT_COMPONENT_STATUS_OK;
9ae49d3d 479 goto end;
bc506aa5 480
9ae49d3d
JD
481error:
482 ret = BT_COMPONENT_STATUS_ERROR;
483end:
bc506aa5 484 bt_put(writer_event);
bc506aa5 485 bt_put(writer_event_class);
bc506aa5 486 bt_put(writer_stream_class);
bc506aa5 487 bt_put(stream_class);
bc506aa5 488 bt_put(writer_stream);
bc506aa5 489 bt_put(stream);
bc506aa5 490 bt_put(event_class);
bc506aa5
JD
491 return ret;
492}
This page took 0.049397 seconds and 4 git commands to generate.