X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=plugins%2Fctf%2Ffs-src%2Ffs.c;h=3f49e00cba439d621116f1ed7e87392884d099d5;hb=04c0ba87d950a956848ba53f657930ce6b255aee;hp=965f5963e6f8f1ed15a0619be9bc8d508400a9dc;hpb=94cf822ec0adbb6d6d33d6475c5b58e1dd7e2b79;p=babeltrace.git diff --git a/plugins/ctf/fs-src/fs.c b/plugins/ctf/fs-src/fs.c index 965f5963..3f49e00c 100644 --- a/plugins/ctf/fs-src/fs.c +++ b/plugins/ctf/fs-src/fs.c @@ -25,6 +25,7 @@ * SOFTWARE. */ +#include #include #include #include @@ -41,18 +42,17 @@ #include #include #include -#include #include "fs.h" #include "metadata.h" #include "data-stream-file.h" #include "file.h" #include "../common/metadata/decoder.h" +#include "query.h" #define PRINT_ERR_STREAM ctf_fs->error_fp #define PRINT_PREFIX "ctf-fs" #define PRINT_DBG_CHECK ctf_fs_debug #include "../print.h" -#define METADATA_TEXT_SIG "/* CTF 1.8" BT_HIDDEN bool ctf_fs_debug; @@ -271,7 +271,6 @@ int create_one_port_for_trace(struct ctf_fs_trace *ctf_fs_trace, struct ctf_fs_ds_file_group *ds_file_group) { int ret = 0; - struct bt_private_port *port = NULL; struct ctf_fs_port_data *port_data = NULL; GString *port_name = NULL; struct ctf_fs_component *ctf_fs = ctf_fs_trace->ctf_fs; @@ -300,9 +299,9 @@ int create_one_port_for_trace(struct ctf_fs_trace *ctf_fs_trace, } port_data->ds_file_group = ds_file_group; - port = bt_private_component_source_add_output_private_port( - ctf_fs->priv_comp, port_name->str, port_data); - if (!port) { + ret = bt_private_component_source_add_output_private_port( + ctf_fs->priv_comp, port_name->str, port_data, NULL); + if (ret) { goto error; } @@ -318,7 +317,6 @@ end: g_string_free(port_name, TRUE); } - bt_put(port); port_data_destroy(port_data); return ret; } @@ -930,6 +928,13 @@ struct ctf_fs_trace *ctf_fs_trace_create(struct ctf_fs_component *ctf_fs, goto error; } + /* + * create_ds_file_groups() created all the streams that this + * trace needs. There won't be any more. Therefore it is safe to + * make this trace static. + */ + (void) bt_ctf_trace_set_is_static(ctf_fs_trace->metadata->trace); + goto end; error: @@ -966,39 +971,31 @@ static int add_trace_path(struct ctf_fs_component *ctf_fs, GList **trace_paths, const char *path) { - GString *path_str = g_string_new(NULL); + GString *norm_path = NULL; int ret = 0; - char *rp = NULL; - if (!path_str) { + norm_path = bt_common_normalize_path(path, NULL); + if (!norm_path) { + PERR("Failed to normalize path `%s`.\n", path); ret = -1; goto end; } - /* - * Find the real path so that we don't have relative components - * in the trace name. This also squashes consecutive slashes and - * removes any slash at the end. - */ - rp = realpath(path, NULL); - if (!rp) { - PERR("realpath() failed: %s (%d)\n", strerror(errno), errno); - ret = -1; - goto end; - } - - if (strcmp(rp, "/") == 0) { + if (strcmp(norm_path->str, "/") == 0) { PERR("Opening a trace in `/` is not supported.\n"); ret = -1; goto end; } - g_string_assign(path_str, rp); - *trace_paths = g_list_prepend(*trace_paths, path_str); + *trace_paths = g_list_prepend(*trace_paths, norm_path); assert(*trace_paths); + norm_path = NULL; end: - free(rp); + if (norm_path) { + g_string_free(norm_path, TRUE); + } + return ret; } @@ -1019,8 +1016,8 @@ int find_ctf_traces(struct ctf_fs_component *ctf_fs, if (ret) { /* - * Do not even recurse: a CTF trace cannot contain - * another CTF trace. + * Stop recursion: a CTF trace cannot contain another + * CTF trace. */ ret = add_trace_path(ctf_fs, trace_paths, start_path); goto end; @@ -1075,68 +1072,52 @@ end: } static -GList *create_trace_names(GList *trace_paths) { +GList *create_trace_names(GList *trace_paths, const char *base_path) { GList *trace_names = NULL; - size_t chars_to_strip = 0; - size_t at = 0; GList *node; - bool done = false; + const char *last_sep; + size_t base_dist; /* - * Find the number of characters to strip from the beginning, - * that is, the longest prefix until a common slash (also - * stripped). + * At this point we know that all the trace paths are + * normalized, and so is the base path. This means that + * they are absolute and they don't end with a separator. + * We can simply find the location of the last separator + * in the base path, which gives us the name of the actual + * directory to look into, and use this location as the + * start of each trace name within each trace path. + * + * For example: + * + * Base path: /home/user/my-traces/some-trace + * Trace paths: + * - /home/user/my-traces/some-trace/host1/trace1 + * - /home/user/my-traces/some-trace/host1/trace2 + * - /home/user/my-traces/some-trace/host2/trace + * - /home/user/my-traces/some-trace/other-trace + * + * In this case the trace names are: + * + * - some-trace/host1/trace1 + * - some-trace/host1/trace2 + * - some-trace/host2/trace + * - some-trace/other-trace */ - while (true) { - gchar common_ch = '\0'; - - for (node = trace_paths; node; node = g_list_next(node)) { - GString *gstr = node->data; - gchar this_ch = gstr->str[at]; - - if (this_ch == '\0') { - done = true; - break; - } - - if (common_ch == '\0') { - /* - * Establish the expected common - * character at this position. - */ - common_ch = this_ch; - continue; - } - - if (this_ch != common_ch) { - done = true; - break; - } - } + last_sep = strrchr(base_path, G_DIR_SEPARATOR); - if (done) { - break; - } - - if (common_ch == '/') { - /* - * Common character is a slash: safe to include - * this slash in the number of characters to - * strip because the paths are guaranteed not to - * end with slash. - */ - chars_to_strip = at + 1; - } + /* We know there's at least one separator */ + assert(last_sep); - at++; - } + /* Distance to base */ + base_dist = last_sep - base_path + 1; /* Create the trace names */ for (node = trace_paths; node; node = g_list_next(node)) { GString *trace_name = g_string_new(NULL); GString *trace_path = node->data; - g_string_assign(trace_name, &trace_path->str[chars_to_strip]); + assert(trace_name); + g_string_assign(trace_name, &trace_path->str[base_dist]); trace_names = g_list_append(trace_names, trace_name); } @@ -1149,12 +1130,20 @@ int create_ctf_fs_traces(struct ctf_fs_component *ctf_fs, { struct ctf_fs_trace *ctf_fs_trace = NULL; int ret = 0; + GString *norm_path = NULL; GList *trace_paths = NULL; GList *trace_names = NULL; GList *tp_node; GList *tn_node; - ret = find_ctf_traces(ctf_fs, &trace_paths, path_param); + norm_path = bt_common_normalize_path(path_param, NULL); + if (!norm_path) { + PERR("Failed to normalize path: `%s`.\n", + path_param); + goto error; + } + + ret = find_ctf_traces(ctf_fs, &trace_paths, norm_path->str); if (ret) { goto error; } @@ -1165,7 +1154,7 @@ int create_ctf_fs_traces(struct ctf_fs_component *ctf_fs, goto error; } - trace_names = create_trace_names(trace_paths); + trace_names = create_trace_names(trace_paths, norm_path->str); if (!trace_names) { PERR("Cannot create trace names from trace paths.\n"); goto error; @@ -1216,6 +1205,10 @@ end: g_list_free(trace_names); } + if (norm_path) { + g_string_free(norm_path, TRUE); + } + return ret; } @@ -1281,7 +1274,7 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp, } ctf_fs->error_fp = stderr; - ctf_fs->page_size = (size_t) getpagesize(); + ctf_fs->page_size = bt_common_get_page_size(); ctf_fs->port_data = g_ptr_array_new_with_free_func(port_data_destroy); if (!ctf_fs->port_data) { goto error; @@ -1330,125 +1323,14 @@ BT_HIDDEN struct bt_value *ctf_fs_query(struct bt_component_class *comp_class, const char *object, struct bt_value *params) { - struct bt_value *results = NULL; - struct bt_value *path_value = NULL; - char *metadata_text = NULL; - FILE *metadata_fp = NULL; - GString *g_metadata_text = NULL; - - if (strcmp(object, "metadata-info") == 0) { - int ret; - int bo; - const char *path; - bool is_packetized; - - results = bt_value_map_create(); - if (!results) { - goto error; - } - - if (!bt_value_is_map(params)) { - fprintf(stderr, - "Query parameters is not a map value object\n"); - goto error; - } + struct bt_value *result = NULL; - path_value = bt_value_map_get(params, "path"); - ret = bt_value_string_get(path_value, &path); - if (ret) { - fprintf(stderr, - "Cannot get `path` string parameter\n"); - goto error; - } - - assert(path); - metadata_fp = ctf_fs_metadata_open_file(path); - if (!metadata_fp) { - fprintf(stderr, - "Cannot open trace at path `%s`\n", path); - goto error; - } - - is_packetized = ctf_metadata_decoder_is_packetized(metadata_fp, - &bo); - - if (is_packetized) { - ret = ctf_metadata_decoder_packetized_file_stream_to_buf( - metadata_fp, &metadata_text, bo); - if (ret) { - fprintf(stderr, - "Cannot decode packetized metadata file\n"); - goto error; - } - } else { - long filesize; - - fseek(metadata_fp, 0, SEEK_END); - filesize = ftell(metadata_fp); - rewind(metadata_fp); - metadata_text = malloc(filesize + 1); - if (!metadata_text) { - fprintf(stderr, - "Cannot allocate buffer for metadata text\n"); - goto error; - } - - if (fread(metadata_text, filesize, 1, metadata_fp) != - 1) { - fprintf(stderr, - "Cannot read metadata file\n"); - goto error; - } - - metadata_text[filesize] = '\0'; - } - - g_metadata_text = g_string_new(NULL); - if (!g_metadata_text) { - goto error; - } - - if (strncmp(metadata_text, METADATA_TEXT_SIG, - sizeof(METADATA_TEXT_SIG) - 1) != 0) { - g_string_assign(g_metadata_text, METADATA_TEXT_SIG); - g_string_append(g_metadata_text, " */\n\n"); - } - - g_string_append(g_metadata_text, metadata_text); - - ret = bt_value_map_insert_string(results, "text", - g_metadata_text->str); - if (ret) { - fprintf(stderr, "Cannot insert metadata text into results\n"); - goto error; - } - - ret = bt_value_map_insert_bool(results, "is-packetized", - is_packetized); - if (ret) { - fprintf(stderr, "Cannot insert is packetized into results\n"); - goto error; - } + if (!strcmp(object, "metadata-info")) { + result = metadata_info_query(comp_class, params); } else { fprintf(stderr, "Unknown query object `%s`\n", object); - goto error; + goto end; } - - goto end; - -error: - BT_PUT(results); - end: - bt_put(path_value); - free(metadata_text); - - if (g_metadata_text) { - g_string_free(g_metadata_text, TRUE); - } - - if (metadata_fp) { - fclose(metadata_fp); - } - return results; + return result; }