X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=blobdiff_plain;f=converter%2Fbabeltrace.c;h=58f534c81a9a3c3ba05ce60f7f6675c70835023b;hp=10083516823dff0f39445e345fbd510566282564;hb=37ea109aded53fd7a07b858a82f8c8c80c03a8a1;hpb=fd94f11cb83df9a8c764c41c28f552de7d8b14e0 diff --git a/converter/babeltrace.c b/converter/babeltrace.c index 10083516..58f534c8 100644 --- a/converter/babeltrace.c +++ b/converter/babeltrace.c @@ -26,8 +26,6 @@ * SOFTWARE. */ -#define _GNU_SOURCE -#include #include #include #include @@ -57,6 +55,10 @@ #define DEFAULT_FILE_ARRAY_SIZE 1 +#define NET_URL_PREFIX "net://" +#define NET4_URL_PREFIX "net4://" +#define NET6_URL_PREFIX "net6://" + static char *opt_input_format, *opt_output_format; /* @@ -68,6 +70,7 @@ static char *opt_input_format, *opt_output_format; */ static GPtrArray *opt_input_paths; static char *opt_output_path; +int opt_stream_intersection; static struct bt_format *fmt_read; @@ -99,6 +102,7 @@ enum { OPT_CLOCK_DATE, OPT_CLOCK_GMT, OPT_CLOCK_FORCE_CORRELATE, + OPT_STREAM_INTERSECTION, }; /* @@ -128,6 +132,7 @@ static struct poptOption long_options[] = { { "clock-date", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_DATE, NULL, NULL }, { "clock-gmt", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_GMT, NULL, NULL }, { "clock-force-correlate", 0, POPT_ARG_NONE, NULL, OPT_CLOCK_FORCE_CORRELATE, NULL, NULL }, + { "stream-intersection", 0, POPT_ARG_NONE, NULL, OPT_STREAM_INTERSECTION, NULL, NULL }, { NULL, 0, 0, NULL, 0, NULL, NULL }, }; @@ -173,6 +178,7 @@ static void usage(FILE *fp) fprintf(fp, " --clock-gmt Print clock in GMT time zone (default: local time zone)\n"); fprintf(fp, " --clock-force-correlate Assume that clocks are inherently correlated\n"); fprintf(fp, " across traces.\n"); + fprintf(fp, " --stream-intersection Only print events when all streams are active.\n"); list_formats(fp); fprintf(fp, "\n"); } @@ -392,6 +398,9 @@ static int parse_options(int argc, char **argv) case OPT_CLOCK_FORCE_CORRELATE: opt_clock_force_correlate = 1; break; + case OPT_STREAM_INTERSECTION: + opt_stream_intersection = 1; + break; default: ret = -EINVAL; @@ -451,15 +460,20 @@ static int traverse_trace_dir(const char *fpath, const struct stat *sb, /* No meta data, just return */ return 0; } else { + int err_close = 0; + closeret = close(metafd); if (closeret < 0) { perror("close"); - return -1; /* failure */ + err_close = 1; } closeret = close(dirfd); if (closeret < 0) { perror("close"); - return -1; /* failure */ + err_close = 1; + } + if (err_close) { + return -1; } /* Add path to the global list */ @@ -492,6 +506,17 @@ int bt_context_add_traces_recursive(struct bt_context *ctx, const char *path, { int ret = 0, trace_ids = 0; + if ((strncmp(path, NET4_URL_PREFIX, sizeof(NET4_URL_PREFIX) - 1)) == 0 || + (strncmp(path, NET6_URL_PREFIX, sizeof(NET6_URL_PREFIX) - 1)) == 0 || + (strncmp(path, NET_URL_PREFIX, sizeof(NET_URL_PREFIX) - 1)) == 0) { + ret = bt_context_add_trace(ctx, + path, format_str, packet_seek, NULL, NULL); + if (ret < 0) { + fprintf(stderr, "[warning] [Context] cannot open trace \"%s\" " + "for reading.\n", path); + } + return ret; + } /* Should lock traversed_paths mutex here if used in multithread */ traversed_paths = g_ptr_array_new(); @@ -597,6 +622,39 @@ end: return ret; } +static +struct bt_ctf_iter *iter_create_intersect(struct bt_context *ctx, + struct bt_iter_pos *inter_begin_pos, + struct bt_iter_pos *inter_end_pos) +{ + uint64_t begin = 0, end = ULLONG_MAX; + /* Useless but needed for bt_iter_create_time_pos. */ + struct bt_iter bt_iter; + int ret; + + ret = ctf_find_packets_intersection(ctx, &begin, &end); + if (ret == 1) { + fprintf(stderr, "[error] No intersection found between trace files.\n"); + ret = -1; + goto error; + } else if (ret != 0) { + goto error; + } + inter_begin_pos = bt_iter_create_time_pos(&bt_iter, begin); + if (!inter_begin_pos) { + goto error; + } + inter_end_pos = bt_iter_create_time_pos(&bt_iter, end); + if (!inter_end_pos) { + goto error; + } + + return bt_ctf_iter_create(ctx, inter_begin_pos, + inter_end_pos); +error: + return NULL; +} + static int convert_trace(struct bt_trace_descriptor *td_write, struct bt_context *ctx) @@ -604,17 +662,23 @@ int convert_trace(struct bt_trace_descriptor *td_write, struct bt_ctf_iter *iter; struct ctf_text_stream_pos *sout; struct bt_iter_pos begin_pos; + struct bt_iter_pos *inter_begin_pos = NULL, *inter_end_pos = NULL; struct bt_ctf_event *ctf_event; int ret; sout = container_of(td_write, struct ctf_text_stream_pos, trace_descriptor); - if (!sout->parent.event_cb) + if (!sout->parent.event_cb) { return 0; + } - begin_pos.type = BT_SEEK_BEGIN; - iter = bt_ctf_iter_create(ctx, &begin_pos, NULL); + if (opt_stream_intersection) { + iter = iter_create_intersect(ctx, inter_begin_pos, inter_end_pos); + } else { + begin_pos.type = BT_SEEK_BEGIN; + iter = bt_ctf_iter_create(ctx, &begin_pos, NULL); + } if (!iter) { ret = -1; goto error_iter; @@ -626,14 +690,21 @@ int convert_trace(struct bt_trace_descriptor *td_write, goto end; } ret = bt_iter_next(bt_ctf_get_iter(iter)); - if (ret < 0) + if (ret < 0) { goto end; + } } ret = 0; end: bt_ctf_iter_destroy(iter); error_iter: + if (inter_begin_pos) { + bt_iter_free_pos(inter_begin_pos); + } + if (inter_end_pos) { + bt_iter_free_pos(inter_end_pos); + } return ret; } @@ -692,7 +763,7 @@ int main(int argc, char **argv) } } fmt_read = bt_lookup_format(g_quark_from_static_string(opt_input_format)); - if (!fmt_read || fmt_read->name != g_quark_from_static_string("ctf")) { + if (!fmt_read) { fprintf(stderr, "[error] Format \"%s\" is not supported.\n\n", opt_input_format); partial_error = 1; @@ -752,10 +823,13 @@ int main(int argc, char **argv) goto error_copy_trace; } - ret = convert_trace(td_write, ctx); - if (ret) { - fprintf(stderr, "Error printing trace.\n\n"); - goto error_copy_trace; + /* For now, we support only CTF iterators */ + if (fmt_read->name == g_quark_from_static_string("ctf")) { + ret = convert_trace(td_write, ctx); + if (ret) { + fprintf(stderr, "Error printing trace.\n\n"); + goto error_copy_trace; + } } ret = trace_post_handler(td_write, ctx);