Fix: mixed enums used in source.ctf.fs
[babeltrace.git] / plugins / ctf / fs-src / fs.c
index 8738f233bf12c6399088eb3cc65c33840b1ff30b..12099ec4e8fa8fcbfc9b6497834914745fb1f63a 100644 (file)
 #include "data-stream-file.h"
 #include "file.h"
 #include "../common/metadata/decoder.h"
+#include "../common/notif-iter/notif-iter.h"
 #include "query.h"
 
 #define BT_LOG_TAG "PLUGIN-CTF-FS-SRC"
 #include "logging.h"
 
-BT_HIDDEN
-bool ctf_fs_debug;
-
 static
 int notif_iter_data_set_current_ds_file(struct ctf_fs_notif_iter_data *notif_iter_data)
 {
@@ -70,6 +68,7 @@ int notif_iter_data_set_current_ds_file(struct ctf_fs_notif_iter_data *notif_ite
        ctf_fs_ds_file_destroy(notif_iter_data->ds_file);
        notif_iter_data->ds_file = ctf_fs_ds_file_create(
                notif_iter_data->ds_file_group->ctf_fs_trace,
+               notif_iter_data->notif_iter,
                notif_iter_data->ds_file_group->stream,
                ds_file_info->path->str);
        if (!notif_iter_data->ds_file) {
@@ -88,6 +87,11 @@ void ctf_fs_notif_iter_data_destroy(
        }
 
        ctf_fs_ds_file_destroy(notif_iter_data->ds_file);
+
+       if (notif_iter_data->notif_iter) {
+               bt_ctf_notif_iter_destroy(notif_iter_data->notif_iter);
+       }
+
        g_free(notif_iter_data);
 }
 
@@ -171,6 +175,16 @@ enum bt_notification_iterator_status ctf_fs_iterator_init(
                goto error;
        }
 
+       notif_iter_data->notif_iter = bt_ctf_notif_iter_create(
+               port_data->ds_file_group->ctf_fs_trace->metadata->trace,
+               bt_common_get_page_size() * 8,
+               ctf_fs_ds_file_medops, NULL);
+       if (!notif_iter_data->notif_iter) {
+               BT_LOGE_STR("Cannot create a CTF notification iterator.");
+               ret = BT_NOTIFICATION_ITERATOR_STATUS_NOMEM;
+               goto error;
+       }
+
        notif_iter_data->ds_file_group = port_data->ds_file_group;
        iret = notif_iter_data_set_current_ds_file(notif_iter_data);
        if (iret) {
@@ -269,6 +283,31 @@ void port_data_destroy(void *data) {
        g_free(port_data);
 }
 
+static
+GString *get_stream_instance_unique_name(
+               struct ctf_fs_ds_file_group *ds_file_group)
+{
+       GString *name;
+       struct ctf_fs_ds_file_info *ds_file_info;
+
+       name = g_string_new(NULL);
+       if (!name) {
+               goto end;
+       }
+
+       /*
+        * If there's more than one stream file in the stream file
+        * group, the first (earliest) stream file's path is used as
+        * the stream's unique name.
+        */
+       assert(ds_file_group->ds_file_infos->len > 0);
+       ds_file_info = g_ptr_array_index(ds_file_group->ds_file_infos, 0);
+       g_string_assign(name, ds_file_info->path->str);
+
+end:
+       return name;
+}
+
 static
 int create_one_port_for_trace(struct ctf_fs_component *ctf_fs,
                struct ctf_fs_trace *ctf_fs_trace,
@@ -277,22 +316,12 @@ int create_one_port_for_trace(struct ctf_fs_component *ctf_fs,
        int ret = 0;
        struct ctf_fs_port_data *port_data = NULL;
        GString *port_name = NULL;
-       struct ctf_fs_ds_file_info *ds_file_info =
-               g_ptr_array_index(ds_file_group->ds_file_infos, 0);
 
-       port_name = g_string_new(NULL);
+       port_name = get_stream_instance_unique_name(ds_file_group);
        if (!port_name) {
                goto error;
        }
 
-       /*
-        * Assign the name for the new output port. If there's more than
-        * one stream file in the stream file group, the first
-        * (earliest) stream file's path is used.
-        */
-       assert(ds_file_group->ds_file_infos->len > 0);
-       ds_file_info = g_ptr_array_index(ds_file_group->ds_file_infos, 0);
-       g_string_assign(port_name, ds_file_info->path->str);
        BT_LOGD("Creating one port named `%s`", port_name->str);
 
        /* Create output port for this file */
@@ -348,6 +377,7 @@ end:
        return ret;
 }
 
+static
 uint64_t get_packet_header_stream_instance_id(struct ctf_fs_trace *ctf_fs_trace,
                struct bt_ctf_field *packet_header_field)
 {
@@ -393,7 +423,7 @@ struct bt_ctf_stream_class *stream_class_from_packet_header(
        stream_id_field = bt_ctf_field_structure_get_field_by_name(
                packet_header_field, "stream_id");
        if (!stream_id_field) {
-               goto end;
+               goto single_stream_class;
        }
 
        ret = bt_ctf_field_unsigned_integer_get_value(stream_id_field,
@@ -535,6 +565,7 @@ void ctf_fs_ds_file_group_destroy(struct ctf_fs_ds_file_group *ds_file_group)
        }
 
        bt_put(ds_file_group->stream);
+       bt_put(ds_file_group->stream_class);
        g_free(ds_file_group);
 }
 
@@ -546,7 +577,6 @@ struct ctf_fs_ds_file_group *ctf_fs_ds_file_group_create(
 {
        struct ctf_fs_ds_file_group *ds_file_group;
 
-       assert(stream_class);
        ds_file_group = g_new0(struct ctf_fs_ds_file_group, 1);
        if (!ds_file_group) {
                goto error;
@@ -558,20 +588,10 @@ struct ctf_fs_ds_file_group *ctf_fs_ds_file_group_create(
                goto error;
        }
 
-       if (stream_instance_id == -1ULL) {
-               ds_file_group->stream = bt_ctf_stream_create(
-                       stream_class, NULL);
-       } else {
-               ds_file_group->stream = bt_ctf_stream_create_with_id(
-                       stream_class, NULL, stream_instance_id);
-       }
-
-       if (!ds_file_group->stream) {
-               goto error;
-       }
-
+       ds_file_group->stream_id = stream_instance_id;
+       assert(stream_class);
+       ds_file_group->stream_class = bt_get(stream_class);
        ds_file_group->ctf_fs_trace = ctf_fs_trace;
-
        goto end;
 
 error:
@@ -582,6 +602,26 @@ end:
        return ds_file_group;
 }
 
+/* Replace by g_ptr_array_insert when we depend on glib >= 2.40. */
+static
+void array_insert(GPtrArray *array, gpointer element, size_t pos)
+{
+       size_t original_array_len = array->len;
+
+       /* Allocate an unused element at the end of the array. */
+       g_ptr_array_add(array, NULL);
+
+       /* If we are not inserting at the end, move the elements by one. */
+       if (pos < original_array_len) {
+               memmove(&(array->pdata[pos + 1]),
+                       &(array->pdata[pos]),
+                       (original_array_len - pos) * sizeof(gpointer));
+       }
+
+       /* Insert the value and bump the array len */
+       array->pdata[pos] = element;
+}
+
 static
 int ctf_fs_ds_file_group_add_ds_file_info(
                struct ctf_fs_ds_file_group *ds_file_group,
@@ -609,12 +649,7 @@ int ctf_fs_ds_file_group_add_ds_file_info(
                }
        }
 
-       if (i == ds_file_group->ds_file_infos->len) {
-               /* Append instead */
-               i = -1;
-       }
-
-       g_ptr_array_insert(ds_file_group->ds_file_infos, i, ds_file_info);
+       array_insert(ds_file_group->ds_file_infos, ds_file_info, i);
        ds_file_info = NULL;
        goto end;
 
@@ -639,10 +674,18 @@ int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace,
        bool add_group = false;
        int ret;
        size_t i;
-       struct ctf_fs_ds_file *ds_file;
+       struct ctf_fs_ds_file *ds_file = NULL;
        struct ctf_fs_ds_index *index = NULL;
+       struct bt_ctf_notif_iter *notif_iter = NULL;
 
-       ds_file = ctf_fs_ds_file_create(ctf_fs_trace, NULL, path);
+       notif_iter = bt_ctf_notif_iter_create(ctf_fs_trace->metadata->trace,
+               bt_common_get_page_size() * 8, ctf_fs_ds_file_medops, NULL);
+       if (!notif_iter) {
+               BT_LOGE_STR("Cannot create a CTF notification iterator.");
+               goto error;
+       }
+
+       ds_file = ctf_fs_ds_file_create(ctf_fs_trace, notif_iter, NULL, path);
        if (!ds_file) {
                goto error;
        }
@@ -688,7 +731,6 @@ int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace,
                 * there's no timestamp to order the file within its
                 * group.
                 */
-
                ds_file_group = ctf_fs_ds_file_group_create(ctf_fs_trace,
                        stream_class, stream_instance_id);
                if (!ds_file_group) {
@@ -696,7 +738,7 @@ int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace,
                }
 
                ret = ctf_fs_ds_file_group_add_ds_file_info(ds_file_group,
-                               path, begin_ns, index);
+                       path, begin_ns, index);
                /* Ownership of index is transferred. */
                index = NULL;
                if (ret) {
@@ -712,20 +754,12 @@ int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace,
 
        /* Find an existing stream file group with this ID */
        for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) {
-               int64_t id;
-               struct bt_ctf_stream_class *cand_stream_class;
-
                ds_file_group = g_ptr_array_index(
                        ctf_fs_trace->ds_file_groups, i);
-               id = bt_ctf_stream_get_id(ds_file_group->stream);
-               cand_stream_class = bt_ctf_stream_get_class(
-                       ds_file_group->stream);
-
-               assert(cand_stream_class);
-               bt_put(cand_stream_class);
 
-               if (cand_stream_class == stream_class &&
-                               (uint64_t) id == stream_instance_id) {
+               if (ds_file_group->stream_class == stream_class &&
+                               ds_file_group->stream_id ==
+                               stream_instance_id) {
                        break;
                }
 
@@ -742,8 +776,8 @@ int add_ds_file_to_ds_file_group(struct ctf_fs_trace *ctf_fs_trace,
                add_group = true;
        }
 
-       ret = ctf_fs_ds_file_group_add_ds_file_info(ds_file_group,
-                       path, begin_ns, index);
+       ret = ctf_fs_ds_file_group_add_ds_file_info(ds_file_group, path,
+               begin_ns, index);
        index = NULL;
        if (ret) {
                goto error;
@@ -759,7 +793,13 @@ end:
        if (add_group && ds_file_group) {
                g_ptr_array_add(ctf_fs_trace->ds_file_groups, ds_file_group);
        }
+
        ctf_fs_ds_file_destroy(ds_file);
+
+       if (notif_iter) {
+               bt_ctf_notif_iter_destroy(notif_iter);
+       }
+
        ctf_fs_ds_index_destroy(index);
        bt_put(packet_header_field);
        bt_put(packet_context_field);
@@ -774,6 +814,7 @@ int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace)
        const char *basename;
        GError *error = NULL;
        GDir *dir = NULL;
+       size_t i;
 
        /* Check each file in the path directory, except specific ones */
        dir = g_dir_open(ctf_fs_trace->path->str, 0, &error);
@@ -835,7 +876,7 @@ int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace)
                ret = add_ds_file_to_ds_file_group(ctf_fs_trace,
                        file->path->str);
                if (ret) {
-                       BT_LOGD("Cannot add stream file `%s` to stream file group",
+                       BT_LOGE("Cannot add stream file `%s` to stream file group",
                                file->path->str);
                        ctf_fs_file_destroy(file);
                        goto error;
@@ -844,6 +885,43 @@ int create_ds_file_groups(struct ctf_fs_trace *ctf_fs_trace)
                ctf_fs_file_destroy(file);
        }
 
+       /*
+        * At this point, DS file groupes are created, but their
+        * associated stream objects do not exist yet. This is because
+        * we need to name the created stream object with the data
+        * stream file's path. We have everything we need here to do
+        * this.
+        */
+       for (i = 0; i < ctf_fs_trace->ds_file_groups->len; i++) {
+               struct ctf_fs_ds_file_group *ds_file_group =
+                       g_ptr_array_index(ctf_fs_trace->ds_file_groups, i);
+               GString *name = get_stream_instance_unique_name(ds_file_group);
+
+               if (!name) {
+                       goto error;
+               }
+
+               if (ds_file_group->stream_id == -1ULL) {
+                       /* No stream ID */
+                       ds_file_group->stream = bt_ctf_stream_create(
+                               ds_file_group->stream_class, name->str);
+               } else {
+                       /* Specific stream ID */
+                       ds_file_group->stream = bt_ctf_stream_create_with_id(
+                               ds_file_group->stream_class, name->str,
+                               ds_file_group->stream_id);
+               }
+
+               g_string_free(name, TRUE);
+
+               if (!ds_file_group->stream) {
+                       BT_LOGE("Cannot create stream for DS file group: "
+                               "addr=%p, stream-name=\"%s\"",
+                               ds_file_group, name->str);
+                       goto error;
+               }
+       }
+
        goto end;
 
 error:
@@ -901,7 +979,7 @@ end:
 
 BT_HIDDEN
 struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
-               struct metadata_overrides *overrides)
+               struct ctf_fs_metadata_config *metadata_config)
 {
        struct ctf_fs_trace *ctf_fs_trace;
        int ret;
@@ -932,7 +1010,7 @@ struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
                goto error;
        }
 
-       ret = ctf_fs_metadata_set_trace(ctf_fs_trace, overrides);
+       ret = ctf_fs_metadata_set_trace(ctf_fs_trace, metadata_config);
        if (ret) {
                goto error;
        }
@@ -1152,10 +1230,6 @@ int create_ctf_fs_traces(struct ctf_fs_component *ctf_fs,
        GList *trace_names = NULL;
        GList *tp_node;
        GList *tn_node;
-       struct metadata_overrides metadata_overrides = {
-               .clock_offset_s = ctf_fs->options.clock_offset,
-               .clock_offset_ns = ctf_fs->options.clock_offset_ns,
-       };
 
        norm_path = bt_common_normalize_path(path_param, NULL);
        if (!norm_path) {
@@ -1188,7 +1262,7 @@ int create_ctf_fs_traces(struct ctf_fs_component *ctf_fs,
                GString *trace_name = tn_node->data;
 
                ctf_fs_trace = ctf_fs_trace_create(trace_path->str,
-                               trace_name->str, &metadata_overrides);
+                               trace_name->str, &ctf_fs->metadata_config);
                if (!ctf_fs_trace) {
                        BT_LOGE("Cannot create trace for `%s`.",
                                trace_path->str);
@@ -1245,7 +1319,8 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp,
        struct ctf_fs_component *ctf_fs;
        struct bt_value *value = NULL;
        const char *path_param;
-       int ret;
+       enum bt_component_status ret;
+       enum bt_value_status value_ret;
 
        ctf_fs = g_new0(struct ctf_fs_component, 1);
        if (!ctf_fs) {
@@ -1253,7 +1328,7 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp,
        }
 
        ret = bt_private_component_set_user_data(priv_comp, ctf_fs);
-       assert(ret == 0);
+       assert(ret == BT_COMPONENT_STATUS_OK);
 
        /*
         * We don't need to get a new reference here because as long as
@@ -1266,34 +1341,30 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp,
                goto error;
        }
 
-       ret = bt_value_string_get(value, &path_param);
-       assert(ret == 0);
+       value_ret = bt_value_string_get(value, &path_param);
+       assert(value_ret == BT_VALUE_STATUS_OK);
        BT_PUT(value);
-       value = bt_value_map_get(params, "offset-s");
+       value = bt_value_map_get(params, "clock-class-offset-s");
        if (value) {
-               int64_t offset;
-
                if (!bt_value_is_integer(value)) {
-                       BT_LOGE("offset-s should be an integer");
+                       BT_LOGE("clock-class-offset-s should be an integer");
                        goto error;
                }
-               ret = bt_value_integer_get(value, &offset);
-               assert(ret == 0);
-               ctf_fs->options.clock_offset = offset;
+               value_ret = bt_value_integer_get(value,
+                       &ctf_fs->metadata_config.clock_class_offset_s);
+               assert(value_ret == BT_VALUE_STATUS_OK);
                BT_PUT(value);
        }
 
-       value = bt_value_map_get(params, "offset-ns");
+       value = bt_value_map_get(params, "clock-class-offset-ns");
        if (value) {
-               int64_t offset;
-
                if (!bt_value_is_integer(value)) {
-                       BT_LOGE("offset-ns should be an integer");
+                       BT_LOGE("clock-class-offset-ns should be an integer");
                        goto error;
                }
-               ret = bt_value_integer_get(value, &offset);
-               assert(ret == 0);
-               ctf_fs->options.clock_offset_ns = offset;
+               value_ret = bt_value_integer_get(value,
+                       &ctf_fs->metadata_config.clock_class_offset_ns);
+               assert(value_ret == BT_VALUE_STATUS_OK);
                BT_PUT(value);
        }
 
@@ -1308,8 +1379,7 @@ struct ctf_fs_component *ctf_fs_create(struct bt_private_component *priv_comp,
                goto error;
        }
 
-       ret = create_ctf_fs_traces(ctf_fs, path_param);
-       if (ret) {
+       if (create_ctf_fs_traces(ctf_fs, path_param)) {
                goto error;
        }
 
@@ -1319,7 +1389,7 @@ error:
        ctf_fs_destroy(ctf_fs);
        ctf_fs = NULL;
        ret = bt_private_component_set_user_data(priv_comp, NULL);
-       assert(ret == 0);
+       assert(ret == BT_COMPONENT_STATUS_OK);
 
 end:
        bt_put(value);
@@ -1333,7 +1403,6 @@ enum bt_component_status ctf_fs_init(struct bt_private_component *priv_comp,
        struct ctf_fs_component *ctf_fs;
        enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
 
-       ctf_fs_debug = g_strcmp0(getenv("CTF_FS_DEBUG"), "1") == 0;
        ctf_fs = ctf_fs_create(priv_comp, params);
        if (!ctf_fs) {
                ret = BT_COMPONENT_STATUS_ERROR;
This page took 0.030167 seconds and 4 git commands to generate.