+
+LTTNG_EXPORT enum lttng_error_code lttng_domain_supports_trace_format(
+ const struct lttng_endpoint *session_daemon_endpoint,
+ enum lttng_domain_type domain_type,
+ const struct lttng_trace_format_descriptor *trace_format_descriptor)
+{
+ int ret;
+ enum lttng_error_code ret_code;
+ struct lttcomm_session_msg lsm = {
+ .cmd_type = LTTNG_EXECUTE_TRACE_FORMAT_SUPPORT_QUERY,
+ .session = {},
+ .domain = {},
+ .u = {},
+ .fd_count = 0,
+ };
+ struct lttng_payload message;
+ struct lttng_payload reply;
+ struct lttcomm_session_msg *message_lsm;
+
+ lttng_payload_init(&message);
+ lttng_payload_init(&reply);
+
+ if (!session_daemon_endpoint || !trace_format_descriptor) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ lsm.domain.type = domain_type;
+ lsm.u.trace_format_support_query.query_type = 0;
+ lsm.u.trace_format_support_query.type_payload_length = 0;
+
+ if (session_daemon_endpoint != lttng_session_daemon_command_endpoint) {
+ ret_code = LTTNG_ERR_INVALID_ERROR_QUERY_TARGET;
+ goto end;
+ }
+
+ ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
+ if (ret) {
+ ret_code = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ ret = reinterpret_cast<const lttng::trace_format_descriptor *>(trace_format_descriptor)
+ ->serialize(&message);
+ if (ret) {
+ ret_code = LTTNG_ERR_UNK;
+ goto end;
+ }
+
+ message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
+ message_lsm->u.trace_format_support_query.trace_format_length =
+ (uint32_t) message.buffer.size - sizeof(lsm);
+
+ {
+ struct lttng_payload_view message_view =
+ lttng_payload_view_from_payload(&message, 0, -1);
+
+ message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
+ ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
+ if (ret < 0) {
+ ret_code = (lttng_error_code) -ret;
+ goto end;
+ }
+ if (ret != 0) {
+ /* No payload expected */
+ ret = LTTNG_ERR_INVALID_PROTOCOL;
+ }
+ }
+
+ ret_code = LTTNG_OK;
+end:
+ lttng_payload_reset(&message);
+ lttng_payload_reset(&reply);
+ return ret_code;
+}
+
+LTTNG_EXPORT extern enum lttng_error_code lttng_destination_supports_trace_format(
+ const struct lttng_endpoint *session_daemon_endpoint,
+ const char *destination_url,
+ const struct lttng_trace_format_descriptor *trace_format_descriptor)
+{
+ int ret;
+ ssize_t size;
+ enum lttng_error_code ret_code;
+ struct lttcomm_session_msg lsm = {
+ .cmd_type = LTTNG_EXECUTE_TRACE_FORMAT_SUPPORT_QUERY,
+ .session = {},
+ .domain = {},
+ .u = {},
+ .fd_count = 0,
+ };
+ struct lttng_payload message;
+ struct lttng_payload reply;
+ struct lttcomm_session_msg *message_lsm;
+ struct lttng_uri *uris = NULL;
+ size_t size_before_payload = 0;
+
+ lttng_payload_init(&message);
+ lttng_payload_init(&reply);
+
+ if (!session_daemon_endpoint || !trace_format_descriptor) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ size = uri_parse_str_urls(destination_url, NULL, &uris);
+ if (size < 1) {
+ ret_code = LTTNG_ERR_INVALID;
+ goto end;
+ }
+
+ if (uris[0].dtype == LTTNG_DST_PATH) {
+ /* Local output */
+ ret_code = LTTNG_OK;
+ goto end;
+ }
+
+ lsm.u.trace_format_support_query.query_type = 1;
+
+ if (session_daemon_endpoint != lttng_session_daemon_command_endpoint) {
+ ret_code = LTTNG_ERR_INVALID_ERROR_QUERY_TARGET;
+ goto end;
+ }
+
+ ret = lttng_dynamic_buffer_append(&message.buffer, &lsm, sizeof(lsm));
+ if (ret) {
+ ret_code = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ size_before_payload = message.buffer.size;
+
+ ret = reinterpret_cast<const lttng::trace_format_descriptor *>(trace_format_descriptor)
+ ->serialize(&message);
+ if (ret) {
+ ret_code = LTTNG_ERR_UNK;
+ goto end;
+ }
+
+ message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
+ message_lsm->u.trace_format_support_query.trace_format_length =
+ (uint32_t) message.buffer.size - size_before_payload;
+
+ /* FIXME replace all this with good old serialization of sub query type
+ * object. (internal) */
+ size_before_payload = message.buffer.size;
+ ret = lttng_dynamic_buffer_append(&message.buffer, &uris[0], sizeof(*uris));
+ if (ret) {
+ ret_code = LTTNG_ERR_NOMEM;
+ goto end;
+ }
+
+ message_lsm = (struct lttcomm_session_msg *) message.buffer.data;
+ message_lsm->u.trace_format_support_query.type_payload_length =
+ (uint32_t) message.buffer.size - size_before_payload;
+
+ {
+ struct lttng_payload_view message_view =
+ lttng_payload_view_from_payload(&message, 0, -1);
+
+ message_lsm->fd_count = lttng_payload_view_get_fd_handle_count(&message_view);
+ ret = lttng_ctl_ask_sessiond_payload(&message_view, &reply);
+ if (ret < 0) {
+ ret_code = (lttng_error_code) -ret;
+ goto end;
+ }
+ if (ret != 0) {
+ /* No payload expected */
+ ret_code = LTTNG_ERR_INVALID_PROTOCOL;
+ goto end;
+ }
+ }
+
+ ret_code = LTTNG_OK;
+end:
+ lttng_payload_reset(&message);
+ lttng_payload_reset(&reply);
+ return ret_code;
+}