struct trace_chunk_registry_ht_element *element =
container_of(node, typeof(*element), rcu_node);
- lttng_trace_chunk_registry_destroy(element->trace_chunk_registry);
free(element);
}
element->sessiond_trace_chunk_registry = NULL;
}
+ lttng_trace_chunk_registry_destroy(element->trace_chunk_registry);
/* Defered reclaim of the object */
call_rcu(&element->rcu_node, trace_chunk_registry_ht_element_free);
}
void trace_chunk_registry_ht_element_put(
struct trace_chunk_registry_ht_element *element)
{
+ if (!element) {
+ return;
+ }
+
urcu_ref_put(&element->ref, trace_chunk_registry_ht_element_release);
}
urcu_ref_init(&new_element->ref);
cds_lfht_node_init(&new_element->ht_node);
new_element->trace_chunk_registry = trace_chunk_registry;
+ trace_chunk_registry = NULL;
/* Attempt to publish the new element. */
rcu_read_lock();
ERR("Failed to create trace chunk registry for session daemon {%s}",
uuid_str);
}
+ lttng_trace_chunk_registry_destroy(trace_chunk_registry);
return ret;
}
published_chunk = lttng_trace_chunk_registry_publish_chunk(
element->trace_chunk_registry, session_id, new_chunk);
+ /*
+ * At this point, two references to the published chunks exist. One
+ * is taken by the registry while the other is being returned to the
+ * caller. In the use case of the relay daemon, the reference held
+ * by the registry itself is undesirable.
+ *
+ * We want the trace chunk to be removed from the registry as soon
+ * as it is not being used by the relay daemon (through a session
+ * or a stream). This differs from the behaviour of the consumer
+ * daemon which relies on an explicit command from the session
+ * daemon to release the registry's reference.
+ */
+ lttng_trace_chunk_put(published_chunk);
end:
trace_chunk_registry_ht_element_put(element);
return published_chunk;
end:
return chunk;
}
+
+int sessiond_trace_chunk_registry_chunk_exists(
+ struct sessiond_trace_chunk_registry *sessiond_registry,
+ const lttng_uuid sessiond_uuid,
+ uint64_t session_id, uint64_t chunk_id, bool *chunk_exists)
+{
+ int ret;
+ struct trace_chunk_registry_ht_element *element;
+ struct trace_chunk_registry_ht_key key;
+
+ lttng_uuid_copy(key.sessiond_uuid, sessiond_uuid);
+ element = trace_chunk_registry_ht_element_find(sessiond_registry, &key);
+ if (!element) {
+ char uuid_str[UUID_STR_LEN];
+
+ lttng_uuid_to_str(sessiond_uuid, uuid_str);
+ /*
+ * While this certainly means that the chunk does not exist,
+ * it is unexpected for a chunk existence query to target a
+ * session daemon that does not have an active
+ * connection/registry. This would indicate a protocol
+ * (or internal) error.
+ */
+ ERR("Failed to find trace chunk registry of sessiond {%s}",
+ uuid_str);
+ ret = -1;
+ goto end;
+ }
+
+ ret = lttng_trace_chunk_registry_chunk_exists(
+ element->trace_chunk_registry,
+ session_id, chunk_id, chunk_exists);
+ trace_chunk_registry_ht_element_put(element);
+end:
+ return ret;
+}