+void trace_destroy_kernel_channel(struct ltt_kernel_channel *channel)
+{
+ struct ltt_kernel_stream *stream, *stmp;
+ struct ltt_kernel_event *event, *etmp;
+
+ DBG("[trace] Closing channel fd %d", channel->fd);
+ /* Close kernel fd */
+ close(channel->fd);
+ free(channel->pathname);
+ /* Free attributes structure */
+ free(channel->channel);
+
+ /* For each stream in the channel list */
+ cds_list_for_each_entry_safe(stream, stmp, &channel->stream_list.head, list) {
+ trace_destroy_kernel_stream(stream);
+ }
+
+ /* For each event in the channel list */
+ cds_list_for_each_entry_safe(event, etmp, &channel->events_list.head, list) {
+ trace_destroy_kernel_event(event);
+ }
+
+ /* Remove from channel list */
+ cds_list_del(&channel->list);
+ free(channel);
+}
+
+void trace_destroy_kernel_metadata(struct ltt_kernel_metadata *metadata)
+{
+ DBG("[trace] Closing metadata fd %d", metadata->fd);
+ /* Close kernel fd */
+ close(metadata->fd);
+ /* Free attributes */
+ free(metadata->conf);
+
+ free(metadata);
+}
+
+void trace_destroy_kernel_session(struct ltt_kernel_session *session)
+{
+ struct ltt_kernel_channel *channel, *ctmp;
+
+ DBG("[trace] Closing session fd %d", session->fd);
+ /* Close kernel fds */
+ close(session->fd);
+ if (session->metadata_stream_fd != 0) {
+ DBG("[trace] Closing metadata stream fd %d", session->metadata_stream_fd);
+ close(session->metadata_stream_fd);
+ }
+
+ if (session->metadata != NULL) {
+ trace_destroy_kernel_metadata(session->metadata);
+ }
+
+ cds_list_for_each_entry_safe(channel, ctmp, &session->channel_list.head, list) {
+ trace_destroy_kernel_channel(channel);
+ }
+
+ free(session);
+}