+static
+void cmd_destroy_session_reply(const struct ltt_session *session,
+ void *_reply_context)
+{
+ int ret;
+ ssize_t comm_ret;
+ const struct cmd_destroy_session_reply_context *reply_context =
+ _reply_context;
+ struct lttng_dynamic_buffer payload;
+ struct lttcomm_session_destroy_command_header cmd_header;
+ struct lttng_trace_archive_location *location = NULL;
+ struct lttcomm_lttng_msg llm = {
+ .cmd_type = LTTNG_DESTROY_SESSION,
+ .ret_code = reply_context->destruction_status,
+ .pid = UINT32_MAX,
+ .cmd_header_size =
+ sizeof(struct lttcomm_session_destroy_command_header),
+ .data_size = 0,
+ };
+ size_t payload_size_before_location;
+
+ lttng_dynamic_buffer_init(&payload);
+
+ ret = lttng_dynamic_buffer_append(&payload, &llm, sizeof(llm));
+ if (ret) {
+ ERR("Failed to append session destruction message");
+ goto error;
+ }
+
+ cmd_header.rotation_state =
+ (int32_t) (reply_context->implicit_rotation_on_destroy ?
+ session->rotation_state :
+ LTTNG_ROTATION_STATE_NO_ROTATION);
+ ret = lttng_dynamic_buffer_append(&payload, &cmd_header,
+ sizeof(cmd_header));
+ if (ret) {
+ ERR("Failed to append session destruction command header");
+ goto error;
+ }
+
+ if (!reply_context->implicit_rotation_on_destroy) {
+ DBG("No implicit rotation performed during the destruction of session \"%s\", sending reply",
+ session->name);
+ goto send_reply;
+ }
+ if (session->rotation_state != LTTNG_ROTATION_STATE_COMPLETED) {
+ DBG("Rotation state of session \"%s\" is not \"completed\", sending session destruction reply",
+ session->name);
+ goto send_reply;
+ }
+
+ location = session_get_trace_archive_location(session);
+ if (!location) {
+ ERR("Failed to get the location of the trace archive produced during the destruction of session \"%s\"",
+ session->name);
+ goto error;
+ }
+
+ payload_size_before_location = payload.size;
+ comm_ret = lttng_trace_archive_location_serialize(location,
+ &payload);
+ if (comm_ret < 0) {
+ ERR("Failed to serialize the location of the trace archive produced during the destruction of session \"%s\"",
+ session->name);
+ goto error;
+ }
+ /* Update the message to indicate the location's length. */
+ ((struct lttcomm_lttng_msg *) payload.data)->data_size =
+ payload.size - payload_size_before_location;
+send_reply:
+ comm_ret = lttcomm_send_unix_sock(reply_context->reply_sock_fd,
+ payload.data, payload.size);
+ if (comm_ret != (ssize_t) payload.size) {
+ ERR("Failed to send result of the destruction of session \"%s\" to client",
+ session->name);
+ }
+error:
+ ret = close(reply_context->reply_sock_fd);
+ if (ret) {
+ PERROR("Failed to close client socket in deferred session destroy reply");
+ }
+ lttng_dynamic_buffer_reset(&payload);
+ free(_reply_context);
+}
+