+ struct ctf_fs_iterator *ctf_it;
+ struct ctf_fs_component *ctf_fs;
+ enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
+
+ assert(source && it);
+
+ ctf_fs = bt_component_get_private_data(source);
+ if (!ctf_fs) {
+ ret = BT_COMPONENT_STATUS_INVALID;
+ goto end;
+ }
+
+ ctf_it = g_new0(struct ctf_fs_iterator, 1);
+ if (!ctf_it) {
+ ret = BT_COMPONENT_STATUS_NOMEM;
+ goto end;
+ }
+
+ ctf_it->stream_ht = g_hash_table_new_full(g_direct_hash,
+ g_direct_equal, bt_put, stream_destroy);
+ if (!ctf_it->stream_ht) {
+ goto error;
+ }
+ ctf_it->pending_streams = g_ptr_array_new_with_free_func(
+ stream_destroy);
+ if (!ctf_it->pending_streams) {
+ goto error;
+ }
+ ctf_it->pending_notifications = bt_notification_heap_create(
+ compare_notifications, NULL);
+ if (!ctf_it->pending_notifications) {
+ goto error;
+ }
+
+ ret = open_trace_streams(ctf_fs, ctf_it);
+ if (ret) {
+ goto error;
+ }
+
+ ret = bt_notification_iterator_set_get_cb(it, ctf_fs_iterator_get);
+ if (ret) {
+ goto error;
+ }
+
+ ret = bt_notification_iterator_set_next_cb(it, ctf_fs_iterator_next);
+ if (ret) {
+ goto error;
+ }
+
+ ret = bt_notification_iterator_set_destroy_cb(it,
+ ctf_fs_iterator_destroy);
+ if (ret) {
+ goto error;
+ }
+
+ ret = bt_notification_iterator_set_private_data(it, ctf_it);
+ if (ret) {
+ goto error;
+ }
+end:
+ return ret;
+error:
+ (void) bt_notification_iterator_set_private_data(it, NULL);
+ ctf_fs_iterator_destroy_data(ctf_it);
+ goto end;
+}
+
+static
+void ctf_fs_destroy_data(struct ctf_fs_component *ctf_fs)
+{
+ if (ctf_fs->trace_path) {
+ g_string_free(ctf_fs->trace_path, TRUE);
+ }
+ if (ctf_fs->metadata) {
+ ctf_fs_metadata_fini(ctf_fs->metadata);
+ g_free(ctf_fs->metadata);
+ }
+ g_free(ctf_fs);
+}
+
+static
+void ctf_fs_destroy(struct bt_component *component)
+{
+ void *data = bt_component_get_private_data(component);
+
+ ctf_fs_destroy_data(data);