* right amount of memory and copying the original information from the lsm
* structure.
*
- * Return total size of the buffer pointed by buf.
+ * Return 0 on success, negative value on error.
*/
-static int setup_lttng_msg(struct command_ctx *cmd_ctx, size_t size)
+static int setup_lttng_msg(struct command_ctx *cmd_ctx,
+ const void *payload_buf, size_t payload_len,
+ const void *cmd_header_buf, size_t cmd_header_len)
{
- int ret, buf_size;
+ int ret = 0;
+ const size_t header_len = sizeof(struct lttcomm_lttng_msg);
+ const size_t cmd_header_offset = header_len;
+ const size_t payload_offset = cmd_header_offset + cmd_header_len;
+ const size_t total_msg_size = header_len + cmd_header_len + payload_len;
- buf_size = size;
+ cmd_ctx->llm = zmalloc(total_msg_size);
- cmd_ctx->llm = zmalloc(sizeof(struct lttcomm_lttng_msg) + buf_size);
if (cmd_ctx->llm == NULL) {
PERROR("zmalloc");
ret = -ENOMEM;
- goto error;
+ goto end;
}
/* Copy common data */
cmd_ctx->llm->cmd_type = cmd_ctx->lsm->cmd_type;
cmd_ctx->llm->pid = cmd_ctx->lsm->domain.attr.pid;
+ cmd_ctx->llm->cmd_header_size = cmd_header_len;
+ cmd_ctx->llm->data_size = payload_len;
+ cmd_ctx->lttng_msg_size = total_msg_size;
- cmd_ctx->llm->data_size = size;
- cmd_ctx->lttng_msg_size = sizeof(struct lttcomm_lttng_msg) + buf_size;
+ /* Copy command header */
+ memcpy(((uint8_t *) cmd_ctx->llm) + cmd_header_offset, cmd_header_buf,
+ cmd_header_len);
- return buf_size;
+ /* Copy payload */
+ memcpy(((uint8_t *) cmd_ctx->llm) + payload_offset, payload_buf,
+ payload_len);
-error:
+end:
return ret;
}
+/*
+ * Version of setup_lttng_msg() without command header.
+ */
+static int setup_lttng_msg_no_cmd_header(struct command_ctx *cmd_ctx,
+ void *payload_buf, size_t payload_len)
+{
+ return setup_lttng_msg(cmd_ctx, payload_buf, payload_len, NULL, 0);
+}
/*
* Update the kernel poll set of all channel fd available over all tracing
* session. Add the wakeup pipe at the end of the set.
break;
default:
/* Setup lttng message with no payload */
- ret = setup_lttng_msg(cmd_ctx, 0);
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, NULL, 0);
if (ret < 0) {
/* This label does not try to unlock the session */
goto init_setup_error;
* Setup lttng message with payload size set to the event list size in
* bytes and then copy list into the llm payload.
*/
- ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_event) * nb_events);
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, events,
+ sizeof(struct lttng_event) * nb_events);
+ free(events);
+
if (ret < 0) {
- free(events);
goto setup_error;
}
- /* Copy event list into message payload */
- memcpy(cmd_ctx->llm->payload, events,
- sizeof(struct lttng_event) * nb_events);
-
- free(events);
-
ret = LTTNG_OK;
break;
}
* Setup lttng message with payload size set to the event list size in
* bytes and then copy list into the llm payload.
*/
- ret = setup_lttng_msg(cmd_ctx,
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, fields,
sizeof(struct lttng_event_field) * nb_fields);
+ free(fields);
+
if (ret < 0) {
- free(fields);
goto setup_error;
}
- /* Copy event list into message payload */
- memcpy(cmd_ctx->llm->payload, fields,
- sizeof(struct lttng_event_field) * nb_fields);
-
- free(fields);
-
ret = LTTNG_OK;
break;
}
* Setup lttng message with payload size set to the event list size in
* bytes and then copy list into the llm payload.
*/
- ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_event) * nb_events);
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, events,
+ sizeof(struct lttng_event) * nb_events);
+ free(events);
+
if (ret < 0) {
- free(events);
goto setup_error;
}
- /* Copy event list into message payload */
- memcpy(cmd_ctx->llm->payload, events,
- sizeof(struct lttng_event) * nb_events);
-
- free(events);
-
ret = LTTNG_OK;
break;
}
* Setup lttng message with payload size set to the event list size in
* bytes and then copy list into the llm payload.
*/
- ret = setup_lttng_msg(cmd_ctx, sizeof(int32_t) * nr_pids);
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, pids,
+ sizeof(int32_t) * nr_pids);
+ free(pids);
+
if (ret < 0) {
- free(pids);
goto setup_error;
}
- /* Copy event list into message payload */
- memcpy(cmd_ctx->llm->payload, pids,
- sizeof(int) * nr_pids);
-
- free(pids);
-
ret = LTTNG_OK;
break;
}
goto error;
}
- ret = setup_lttng_msg(cmd_ctx, nb_dom * sizeof(struct lttng_domain));
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, domains,
+ nb_dom * sizeof(struct lttng_domain));
+ free(domains);
+
if (ret < 0) {
- free(domains);
goto setup_error;
}
- /* Copy event list into message payload */
- memcpy(cmd_ctx->llm->payload, domains,
- nb_dom * sizeof(struct lttng_domain));
-
- free(domains);
-
ret = LTTNG_OK;
break;
}
goto error;
}
- ret = setup_lttng_msg(cmd_ctx, nb_chan * sizeof(struct lttng_channel));
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, channels,
+ nb_chan * sizeof(struct lttng_channel));
+ free(channels);
+
if (ret < 0) {
- free(channels);
goto setup_error;
}
- /* Copy event list into message payload */
- memcpy(cmd_ctx->llm->payload, channels,
- nb_chan * sizeof(struct lttng_channel));
-
- free(channels);
-
ret = LTTNG_OK;
break;
}
goto error;
}
- ret = setup_lttng_msg(cmd_ctx, nb_event * sizeof(struct lttng_event));
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, events,
+ nb_event * sizeof(struct lttng_event));
+ free(events);
+
if (ret < 0) {
- free(events);
goto setup_error;
}
- /* Copy event list into message payload */
- memcpy(cmd_ctx->llm->payload, events,
- nb_event * sizeof(struct lttng_event));
-
- free(events);
-
ret = LTTNG_OK;
break;
}
case LTTNG_LIST_SESSIONS:
{
unsigned int nr_sessions;
+ void *sessions_payload;
+ size_t payload_len;
session_lock_list();
nr_sessions = lttng_sessions_count(
LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds),
LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds));
+ payload_len = sizeof(struct lttng_session) * nr_sessions;
+ sessions_payload = zmalloc(payload_len);
- ret = setup_lttng_msg(cmd_ctx, sizeof(struct lttng_session) * nr_sessions);
- if (ret < 0) {
+ if (!sessions_payload) {
session_unlock_list();
+ ret = -ENOMEM;
goto setup_error;
}
- /* Filled the session array */
- cmd_list_lttng_sessions((struct lttng_session *)(cmd_ctx->llm->payload),
+ cmd_list_lttng_sessions(sessions_payload,
LTTNG_SOCK_GET_UID_CRED(&cmd_ctx->creds),
LTTNG_SOCK_GET_GID_CRED(&cmd_ctx->creds));
-
session_unlock_list();
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, sessions_payload,
+ payload_len);
+ free(sessions_payload);
+
+ if (ret < 0) {
+ goto setup_error;
+ }
+
ret = LTTNG_OK;
break;
}
case LTTNG_DATA_PENDING:
{
int pending_ret;
-
- /* 1 byte to return whether or not data is pending */
- ret = setup_lttng_msg(cmd_ctx, 1);
- if (ret < 0) {
- goto setup_error;
- }
+ uint8_t pending_ret_byte;
pending_ret = cmd_data_pending(cmd_ctx->session);
+
/*
* FIXME
*
* "unknown" error.
*/
if (pending_ret == 0 || pending_ret == 1) {
- ret = LTTNG_OK;
+ /*
+ * ret will be set to LTTNG_OK at the end of
+ * this function.
+ */
} else if (pending_ret < 0) {
ret = LTTNG_ERR_UNK;
goto setup_error;
goto setup_error;
}
- *cmd_ctx->llm->payload = (uint8_t) pending_ret;
+ pending_ret_byte = (uint8_t) pending_ret;
+
+ /* 1 byte to return whether or not data is pending */
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx,
+ &pending_ret_byte, 1);
+
+ if (ret < 0) {
+ goto setup_error;
+ }
+
+ ret = LTTNG_OK;
break;
}
case LTTNG_SNAPSHOT_ADD_OUTPUT:
goto error;
}
- ret = setup_lttng_msg(cmd_ctx, sizeof(reply));
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, &reply,
+ sizeof(reply));
if (ret < 0) {
goto setup_error;
}
/* Copy output list into message payload */
- memcpy(cmd_ctx->llm->payload, &reply, sizeof(reply));
ret = LTTNG_OK;
break;
}
goto error;
}
- ret = setup_lttng_msg(cmd_ctx,
+ assert((nb_output > 0 && outputs) || nb_output == 0);
+ ret = setup_lttng_msg_no_cmd_header(cmd_ctx, outputs,
nb_output * sizeof(struct lttng_snapshot_output));
+ free(outputs);
+
if (ret < 0) {
- free(outputs);
goto setup_error;
}
- if (outputs) {
- /* Copy output list into message payload */
- memcpy(cmd_ctx->llm->payload, outputs,
- nb_output * sizeof(struct lttng_snapshot_output));
- free(outputs);
- }
-
ret = LTTNG_OK;
break;
}
error:
if (cmd_ctx->llm == NULL) {
DBG("Missing llm structure. Allocating one.");
- if (setup_lttng_msg(cmd_ctx, 0) < 0) {
+ if (setup_lttng_msg_no_cmd_header(cmd_ctx, NULL, 0) < 0) {
goto setup_error;
}
}