+LTTNG_HIDDEN
+int lttng_ctl_ask_sessiond_payload(struct lttng_payload_view *message,
+ struct lttng_payload *reply)
+{
+ int ret;
+ struct lttcomm_lttng_msg llm;
+ const int fd_count = lttng_payload_view_get_fd_handle_count(message);
+
+ assert(reply->buffer.size == 0);
+ assert(lttng_dynamic_pointer_array_get_count(&reply->_fd_handles) == 0);
+
+ ret = connect_sessiond();
+ if (ret < 0) {
+ ret = -LTTNG_ERR_NO_SESSIOND;
+ goto end;
+ } else {
+ sessiond_socket = ret;
+ connected = 1;
+ }
+
+ /* Send command to session daemon */
+ ret = lttcomm_send_creds_unix_sock(sessiond_socket, message->buffer.data,
+ message->buffer.size);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_FATAL;
+ goto end;
+ }
+
+ if (fd_count > 0) {
+ ret = lttcomm_send_payload_view_fds_unix_sock(sessiond_socket,
+ message);
+ if (ret < 0) {
+ ret = -LTTNG_ERR_FATAL;
+ goto end;
+ }
+ }
+
+ /* Get header from data transmission */
+ ret = recv_payload_sessiond(reply, sizeof(llm));
+ if (ret < 0) {
+ /* Ret value is a valid lttng error code. */
+ goto end;
+ }
+
+ llm = *((typeof(llm) *) reply->buffer.data);
+
+ /* Check error code if OK */
+ if (llm.ret_code != LTTNG_OK) {
+ ret = -llm.ret_code;
+ goto end;
+ }
+
+ if (llm.cmd_header_size > 0) {
+ ret = recv_payload_sessiond(reply, llm.cmd_header_size);
+ if (ret < 0) {
+ goto end;
+ }
+ }
+
+ /* Get command header from data transmission */
+ if (llm.data_size > 0) {
+ ret = recv_payload_sessiond(reply, llm.data_size);
+ if (ret < 0) {
+ goto end;
+ }
+ }
+
+ if (llm.fd_count > 0) {
+ ret = lttcomm_recv_payload_fds_unix_sock(
+ sessiond_socket, llm.fd_count, reply);
+ if (ret < 0) {
+ goto end;
+ }
+ }
+
+ /* Don't return the llm header to the caller. */
+ memmove(reply->buffer.data, reply->buffer.data + sizeof(llm),
+ reply->buffer.size - sizeof(llm));
+ ret = lttng_dynamic_buffer_set_size(
+ &reply->buffer, reply->buffer.size - sizeof(llm));
+ if (ret) {
+ /* Can't happen as size is reduced. */
+ abort();
+ }
+
+ ret = reply->buffer.size;
+
+end:
+ disconnect_sessiond();
+ return ret;
+}
+