From 3647288fe42b25340f905046f3bd9aef21e12aaa Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Tue, 21 Aug 2018 16:56:19 -0400 Subject: [PATCH] Use the dynamic buffer to serialize notification objects MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The objects of the notification/trigger APIs are currently serialized by calling their serialization functions with a NULL buffer, returning the expected size, and then calling the serialization function with a sufficiently-large buffer. This code predates the dynamic buffer utility which can now be used to perform serialization operations in one pass. Signed-off-by: Jérémie Galarneau --- include/lttng/action/action-internal.h | 7 +- include/lttng/condition/condition-internal.h | 10 ++- include/lttng/condition/evaluation-internal.h | 9 +- .../notification/notification-internal.h | 5 +- include/lttng/trigger/trigger-internal.h | 4 +- .../notification-thread-events.c | 31 +++---- src/common/action.c | 29 +++--- src/common/buffer-usage.c | 89 ++++++++++--------- src/common/condition.c | 27 +++--- src/common/evaluation.c | 21 ++--- src/common/notification.c | 41 ++++----- src/common/notify.c | 3 +- src/common/session-consumed-size.c | 60 ++++++------- src/common/trigger.c | 38 ++++---- src/lib/lttng-ctl/channel.c | 40 ++++----- src/lib/lttng-ctl/lttng-ctl.c | 56 ++++-------- 16 files changed, 211 insertions(+), 259 deletions(-) diff --git a/include/lttng/action/action-internal.h b/include/lttng/action/action-internal.h index 1ab8f9a81..0c862a3a2 100644 --- a/include/lttng/action/action-internal.h +++ b/include/lttng/action/action-internal.h @@ -21,12 +21,14 @@ #include #include #include +#include #include #include typedef bool (*action_validate_cb)(struct lttng_action *action); typedef void (*action_destroy_cb)(struct lttng_action *action); -typedef ssize_t (*action_serialize_cb)(struct lttng_action *action, char *buf); +typedef int (*action_serialize_cb)(struct lttng_action *action, + struct lttng_dynamic_buffer *buf); struct lttng_action { enum lttng_action_type type; @@ -44,7 +46,8 @@ LTTNG_HIDDEN bool lttng_action_validate(struct lttng_action *action); LTTNG_HIDDEN -ssize_t lttng_action_serialize(struct lttng_action *action, char *buf); +int lttng_action_serialize(struct lttng_action *action, + struct lttng_dynamic_buffer *buf); LTTNG_HIDDEN ssize_t lttng_action_create_from_buffer(const struct lttng_buffer_view *view, diff --git a/include/lttng/condition/condition-internal.h b/include/lttng/condition/condition-internal.h index 969c76820..c54141e22 100644 --- a/include/lttng/condition/condition-internal.h +++ b/include/lttng/condition/condition-internal.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -28,8 +29,9 @@ typedef void (*condition_destroy_cb)(struct lttng_condition *condition); typedef bool (*condition_validate_cb)(const struct lttng_condition *condition); -typedef ssize_t (*condition_serialize_cb)( - const struct lttng_condition *condition, char *buf); +typedef int (*condition_serialize_cb)( + const struct lttng_condition *condition, + struct lttng_dynamic_buffer *buf); typedef bool (*condition_equal_cb)(const struct lttng_condition *a, const struct lttng_condition *b); typedef ssize_t (*condition_create_from_buffer_cb)( @@ -63,8 +65,8 @@ ssize_t lttng_condition_create_from_buffer( struct lttng_condition **condition); LTTNG_HIDDEN -ssize_t lttng_condition_serialize(const struct lttng_condition *condition, - char *buf); +int lttng_condition_serialize(const struct lttng_condition *condition, + struct lttng_dynamic_buffer *buf); LTTNG_HIDDEN bool lttng_condition_is_equal(const struct lttng_condition *a, diff --git a/include/lttng/condition/evaluation-internal.h b/include/lttng/condition/evaluation-internal.h index e2b6c3848..95119b37e 100644 --- a/include/lttng/condition/evaluation-internal.h +++ b/include/lttng/condition/evaluation-internal.h @@ -21,12 +21,13 @@ #include #include #include +#include #include #include typedef void (*evaluation_destroy_cb)(struct lttng_evaluation *evaluation); -typedef ssize_t (*evaluation_serialize_cb)(struct lttng_evaluation *evaluation, - char *buf); +typedef int (*evaluation_serialize_cb)(struct lttng_evaluation *evaluation, + struct lttng_dynamic_buffer *buf); struct lttng_evaluation_comm { /* enum lttng_condition_type type */ @@ -45,7 +46,7 @@ ssize_t lttng_evaluation_create_from_buffer(const struct lttng_buffer_view *view struct lttng_evaluation **evaluation); LTTNG_HIDDEN -ssize_t lttng_evaluation_serialize(struct lttng_evaluation *evaluation, - char *buf); +int lttng_evaluation_serialize(struct lttng_evaluation *evaluation, + struct lttng_dynamic_buffer *buf); #endif /* LTTNG_EVALUATION_INTERNAL_H */ diff --git a/include/lttng/notification/notification-internal.h b/include/lttng/notification/notification-internal.h index 9bdf2a934..648977f33 100644 --- a/include/lttng/notification/notification-internal.h +++ b/include/lttng/notification/notification-internal.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -58,8 +59,8 @@ struct lttng_notification *lttng_notification_create( struct lttng_evaluation *evaluation); LTTNG_HIDDEN -ssize_t lttng_notification_serialize(struct lttng_notification *notification, - char *buf); +int lttng_notification_serialize(struct lttng_notification *notification, + struct lttng_dynamic_buffer *buf); LTTNG_HIDDEN ssize_t lttng_notification_create_from_buffer( diff --git a/include/lttng/trigger/trigger-internal.h b/include/lttng/trigger/trigger-internal.h index 23192863e..22975bf41 100644 --- a/include/lttng/trigger/trigger-internal.h +++ b/include/lttng/trigger/trigger-internal.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,8 @@ ssize_t lttng_trigger_create_from_buffer(const struct lttng_buffer_view *view, struct lttng_trigger **trigger); LTTNG_HIDDEN -ssize_t lttng_trigger_serialize(struct lttng_trigger *trigger, char *buf); +int lttng_trigger_serialize(struct lttng_trigger *trigger, + struct lttng_dynamic_buffer *buf); LTTNG_HIDDEN bool lttng_trigger_validate(struct lttng_trigger *trigger); diff --git a/src/bin/lttng-sessiond/notification-thread-events.c b/src/bin/lttng-sessiond/notification-thread-events.c index 9d006845f..33876874b 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.c +++ b/src/bin/lttng-sessiond/notification-thread-events.c @@ -2387,8 +2387,9 @@ int send_evaluation_to_clients(struct lttng_trigger *trigger, struct notification_client_list_element *client_list_element, *tmp; struct lttng_notification *notification; struct lttng_condition *condition; - ssize_t expected_notification_size, notification_size; - struct lttng_notification_channel_message msg; + struct lttng_notification_channel_message msg_header = { + .type = (int8_t) LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_NOTIFICATION, + }; lttng_dynamic_buffer_init(&msg_buffer); @@ -2401,35 +2402,23 @@ int send_evaluation_to_clients(struct lttng_trigger *trigger, goto end; } - expected_notification_size = lttng_notification_serialize(notification, - NULL); - if (expected_notification_size < 0) { - ERR("[notification-thread] Failed to get size of serialized notification"); - ret = -1; - goto end; - } - - msg.type = (int8_t) LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_NOTIFICATION; - msg.size = (uint32_t) expected_notification_size; - ret = lttng_dynamic_buffer_append(&msg_buffer, &msg, sizeof(msg)); + ret = lttng_dynamic_buffer_append(&msg_buffer, &msg_header, + sizeof(msg_header)); if (ret) { goto end; } - ret = lttng_dynamic_buffer_set_size(&msg_buffer, - msg_buffer.size + expected_notification_size); + ret = lttng_notification_serialize(notification, &msg_buffer); if (ret) { - goto end; - } - - notification_size = lttng_notification_serialize(notification, - msg_buffer.data + sizeof(msg)); - if (notification_size != expected_notification_size) { ERR("[notification-thread] Failed to serialize notification"); ret = -1; goto end; } + /* Update payload size. */ + ((struct lttng_notification_channel_message * ) msg_buffer.data)->size = + (uint32_t) (msg_buffer.size - sizeof(msg_header)); + cds_list_for_each_entry_safe(client_list_element, tmp, &client_list->list, node) { struct notification_client *client = diff --git a/src/common/action.c b/src/common/action.c index 3abdfaf21..0ce93c852 100644 --- a/src/common/action.c +++ b/src/common/action.c @@ -57,29 +57,24 @@ end: } LTTNG_HIDDEN -ssize_t lttng_action_serialize(struct lttng_action *action, char *buf) +int lttng_action_serialize(struct lttng_action *action, + struct lttng_dynamic_buffer *buf) { - ssize_t ret, action_size; - struct lttng_action_comm action_comm; - - if (!action) { - ret = -1; + int ret; + struct lttng_action_comm action_comm = { + .action_type = (int8_t) action->type, + }; + + ret = lttng_dynamic_buffer_append(buf, &action_comm, + sizeof(action_comm)); + if (ret) { goto end; } - action_comm.action_type = (int8_t) action->type; - ret = sizeof(struct lttng_action_comm); - if (buf) { - memcpy(buf, &action_comm, ret); - buf += ret; - } - - action_size = action->serialize(action, buf); - if (action_size < 0) { - ret = action_size; + ret = action->serialize(action, buf); + if (ret) { goto end; } - ret += action_size; end: return ret; } diff --git a/src/common/buffer-usage.c b/src/common/buffer-usage.c index 16292ea91..3d0026081 100644 --- a/src/common/buffer-usage.c +++ b/src/common/buffer-usage.c @@ -95,12 +95,14 @@ end: } static -ssize_t lttng_condition_buffer_usage_serialize( - const struct lttng_condition *condition, char *buf) +int lttng_condition_buffer_usage_serialize( + const struct lttng_condition *condition, + struct lttng_dynamic_buffer *buf) { + int ret; struct lttng_condition_buffer_usage *usage; - ssize_t ret, size; size_t session_name_len, channel_name_len; + struct lttng_condition_buffer_usage_comm usage_comm; if (!condition || !IS_USAGE_CONDITION(condition)) { ret = -1; @@ -110,7 +112,7 @@ ssize_t lttng_condition_buffer_usage_serialize( DBG("Serializing buffer usage condition"); usage = container_of(condition, struct lttng_condition_buffer_usage, parent); - size = sizeof(struct lttng_condition_buffer_usage_comm); + session_name_len = strlen(usage->session_name) + 1; channel_name_len = strlen(usage->channel_name) + 1; if (session_name_len > LTTNG_NAME_MAX || @@ -118,36 +120,41 @@ ssize_t lttng_condition_buffer_usage_serialize( ret = -1; goto end; } - size += session_name_len + channel_name_len; - if (buf) { - struct lttng_condition_buffer_usage_comm usage_comm = { - .threshold_set_in_bytes = usage->threshold_bytes.set ? 1 : 0, - .session_name_len = session_name_len, - .channel_name_len = channel_name_len, - .domain_type = (int8_t) usage->domain.type, - }; - - if (usage->threshold_bytes.set) { - usage_comm.threshold = usage->threshold_bytes.value; - } else { - uint64_t val = double_to_fixed( - usage->threshold_ratio.value); - - if (val > UINT32_MAX) { - /* overflow. */ - ret = -1; - goto end; - } - usage_comm.threshold = val; + + usage_comm.threshold_set_in_bytes = !!usage->threshold_bytes.set; + usage_comm.session_name_len = session_name_len; + usage_comm.channel_name_len = channel_name_len; + usage_comm.domain_type = (int8_t) usage->domain.type; + + if (usage->threshold_bytes.set) { + usage_comm.threshold = usage->threshold_bytes.value; + } else { + uint64_t val = double_to_fixed( + usage->threshold_ratio.value); + + if (val > UINT32_MAX) { + /* overflow. */ + ret = -1; + goto end; } + usage_comm.threshold = val; + } - memcpy(buf, &usage_comm, sizeof(usage_comm)); - buf += sizeof(usage_comm); - memcpy(buf, usage->session_name, session_name_len); - buf += session_name_len; - memcpy(buf, usage->channel_name, channel_name_len); + ret = lttng_dynamic_buffer_append(buf, &usage_comm, + sizeof(usage_comm)); + if (ret) { + goto end; + } + ret = lttng_dynamic_buffer_append(buf, usage->session_name, + session_name_len); + if (ret) { + goto end; + } + ret = lttng_dynamic_buffer_append(buf, usage->channel_name, + channel_name_len); + if (ret) { + goto end; } - ret = size; end: return ret; } @@ -739,25 +746,19 @@ end: } static -ssize_t lttng_evaluation_buffer_usage_serialize( - struct lttng_evaluation *evaluation, char *buf) +int lttng_evaluation_buffer_usage_serialize( + struct lttng_evaluation *evaluation, + struct lttng_dynamic_buffer *buf) { - ssize_t ret; struct lttng_evaluation_buffer_usage *usage; + struct lttng_evaluation_buffer_usage_comm comm; usage = container_of(evaluation, struct lttng_evaluation_buffer_usage, parent); - if (buf) { - struct lttng_evaluation_buffer_usage_comm comm = { - .buffer_use = usage->buffer_use, - .buffer_capacity = usage->buffer_capacity, - }; + comm.buffer_use = usage->buffer_use; + comm.buffer_capacity = usage->buffer_capacity; - memcpy(buf, &comm, sizeof(comm)); - } - - ret = sizeof(struct lttng_evaluation_buffer_usage_comm); - return ret; + return lttng_dynamic_buffer_append(buf, &comm, sizeof(comm)); } static diff --git a/src/common/condition.c b/src/common/condition.c index 60d32e6cc..9a9e9babd 100644 --- a/src/common/condition.c +++ b/src/common/condition.c @@ -63,32 +63,29 @@ end: } LTTNG_HIDDEN -ssize_t lttng_condition_serialize(const struct lttng_condition *condition, - char *buf) +int lttng_condition_serialize(const struct lttng_condition *condition, + struct lttng_dynamic_buffer *buf) { - ssize_t ret, condition_size; - struct lttng_condition_comm condition_comm = { - .condition_type = (int8_t) (condition ? - condition->type : LTTNG_CONDITION_TYPE_UNKNOWN) - }; + int ret; + struct lttng_condition_comm condition_comm = { 0 }; if (!condition) { ret = -1; goto end; } - ret = sizeof(struct lttng_condition_comm); - if (buf) { - memcpy(buf, &condition_comm, ret); - buf += ret; + condition_comm.condition_type = (int8_t) condition->type; + + ret = lttng_dynamic_buffer_append(buf, &condition_comm, + sizeof(condition_comm)); + if (ret) { + goto end; } - condition_size = condition->serialize(condition, buf); - if (condition_size < 0) { - ret = condition_size; + ret = condition->serialize(condition, buf); + if (ret) { goto end; } - ret += condition_size; end: return ret; } diff --git a/src/common/evaluation.c b/src/common/evaluation.c index b2c2df815..f07c81b18 100644 --- a/src/common/evaluation.c +++ b/src/common/evaluation.c @@ -24,29 +24,26 @@ #include LTTNG_HIDDEN -ssize_t lttng_evaluation_serialize(struct lttng_evaluation *evaluation, - char *buf) +int lttng_evaluation_serialize(struct lttng_evaluation *evaluation, + struct lttng_dynamic_buffer *buf) { - ssize_t ret, offset = 0; + int ret; struct lttng_evaluation_comm evaluation_comm = { .type = (int8_t) evaluation->type }; - if (buf) { - memcpy(buf, &evaluation_comm, sizeof(evaluation_comm)); + ret = lttng_dynamic_buffer_append(buf, &evaluation_comm, + sizeof(evaluation_comm)); + if (ret) { + goto end; } - offset += sizeof(evaluation_comm); if (evaluation->serialize) { - ret = evaluation->serialize(evaluation, - buf ? (buf + offset) : NULL); - if (ret < 0) { + ret = evaluation->serialize(evaluation, buf); + if (ret) { goto end; } - offset += ret; } - - ret = offset; end: return ret; } diff --git a/src/common/notification.c b/src/common/notification.c index 785af6816..3826534cd 100644 --- a/src/common/notification.c +++ b/src/common/notification.c @@ -46,40 +46,33 @@ end: } LTTNG_HIDDEN -ssize_t lttng_notification_serialize(struct lttng_notification *notification, - char *buf) +int lttng_notification_serialize(struct lttng_notification *notification, + struct lttng_dynamic_buffer *buf) { - ssize_t ret, condition_size, evaluation_size, offset = 0; + int ret; + size_t header_offset, size_before_payload; struct lttng_notification_comm notification_comm = { 0 }; + struct lttng_notification_comm *header; - if (!notification) { - ret = -1; - goto end; - } + header_offset = buf->size; + ret = lttng_dynamic_buffer_append(buf, ¬ification_comm, + sizeof(notification_comm)); - offset += sizeof(notification_comm); - condition_size = lttng_condition_serialize(notification->condition, - buf ? (buf + offset) : NULL); - if (condition_size < 0) { - ret = condition_size; + size_before_payload = buf->size; + ret = lttng_condition_serialize(notification->condition, + buf); + if (ret) { goto end; } - offset += condition_size; - evaluation_size = lttng_evaluation_serialize(notification->evaluation, - buf ? (buf + offset) : NULL); - if (evaluation_size < 0) { - ret = evaluation_size; + ret = lttng_evaluation_serialize(notification->evaluation, buf); + if (ret) { goto end; } - offset += evaluation_size; - if (buf) { - notification_comm.length = - (uint32_t) (condition_size + evaluation_size); - memcpy(buf, ¬ification_comm, sizeof(notification_comm)); - } - ret = offset; + /* Update payload size. */ + header = (struct lttng_notification_comm *) ((char *) buf->data + header_offset); + header->length = (uint32_t) (buf->size - size_before_payload); end: return ret; diff --git a/src/common/notify.c b/src/common/notify.c index 956c0ecff..f5026413f 100644 --- a/src/common/notify.c +++ b/src/common/notify.c @@ -27,7 +27,8 @@ void lttng_action_notify_destroy(struct lttng_action *action) } static -ssize_t lttng_action_notify_serialize(struct lttng_action *action, char *buf) +int lttng_action_notify_serialize(struct lttng_action *action, + struct lttng_dynamic_buffer *buf) { return 0; } diff --git a/src/common/session-consumed-size.c b/src/common/session-consumed-size.c index cc5b790e2..f29176f8d 100644 --- a/src/common/session-consumed-size.c +++ b/src/common/session-consumed-size.c @@ -73,40 +73,45 @@ end: } static -ssize_t lttng_condition_session_consumed_size_serialize( - const struct lttng_condition *condition, char *buf) +int lttng_condition_session_consumed_size_serialize( + const struct lttng_condition *condition, + struct lttng_dynamic_buffer *buf) { - struct lttng_condition_session_consumed_size *consumed; - ssize_t ret, size; + int ret; size_t session_name_len; + struct lttng_condition_session_consumed_size *consumed; + struct lttng_condition_session_consumed_size_comm consumed_comm; if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition)) { ret = -1; goto end; } - DBG("Serializing session consumed condition"); - consumed = container_of(condition, struct lttng_condition_session_consumed_size, + DBG("Serializing session consumed size condition"); + consumed = container_of(condition, + struct lttng_condition_session_consumed_size, parent); - size = sizeof(struct lttng_condition_session_consumed_size_comm); + session_name_len = strlen(consumed->session_name) + 1; if (session_name_len > LTTNG_NAME_MAX) { ret = -1; goto end; } - size += session_name_len; - if (buf) { - struct lttng_condition_session_consumed_size_comm consumed_comm = { - .consumed_threshold_bytes = consumed->consumed_threshold_bytes.value, - .session_name_len = session_name_len, - }; - memcpy(buf, &consumed_comm, sizeof(consumed_comm)); - buf += sizeof(consumed_comm); - memcpy(buf, consumed->session_name, session_name_len); - buf += session_name_len; + consumed_comm.consumed_threshold_bytes = + consumed->consumed_threshold_bytes.value; + consumed_comm.session_name_len = (uint32_t) session_name_len; + + ret = lttng_dynamic_buffer_append(buf, &consumed_comm, + sizeof(consumed_comm)); + if (ret) { + goto end; + } + ret = lttng_dynamic_buffer_append(buf, consumed->session_name, + session_name_len); + if (ret) { + goto end; } - ret = size; end: return ret; } @@ -397,24 +402,17 @@ end: } static -ssize_t lttng_evaluation_session_consumed_size_serialize( - struct lttng_evaluation *evaluation, char *buf) +int lttng_evaluation_session_consumed_size_serialize( + struct lttng_evaluation *evaluation, + struct lttng_dynamic_buffer *buf) { - ssize_t ret; struct lttng_evaluation_session_consumed_size *consumed; + struct lttng_evaluation_session_consumed_size_comm comm; consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size, parent); - if (buf) { - struct lttng_evaluation_session_consumed_size_comm comm = { - .session_consumed = consumed->session_consumed, - }; - - memcpy(buf, &comm, sizeof(comm)); - } - - ret = sizeof(struct lttng_evaluation_session_consumed_size_comm); - return ret; + comm.session_consumed = consumed->session_consumed; + return lttng_dynamic_buffer_append(buf, &comm, sizeof(comm)); } static diff --git a/src/common/trigger.c b/src/common/trigger.c index 70b7e29e5..1de1b3b49 100644 --- a/src/common/trigger.c +++ b/src/common/trigger.c @@ -141,43 +141,39 @@ error: } /* - * Returns the size of a trigger (header + condition + action). * Both elements are stored contiguously, see their "*_comm" structure * for the detailed format. */ LTTNG_HIDDEN -ssize_t lttng_trigger_serialize(struct lttng_trigger *trigger, char *buf) +int lttng_trigger_serialize(struct lttng_trigger *trigger, + struct lttng_dynamic_buffer *buf) { + int ret; + size_t header_offset, size_before_payload; struct lttng_trigger_comm trigger_comm = { 0 }; - ssize_t action_size, condition_size, offset = 0, ret; + struct lttng_trigger_comm *header; - if (!trigger) { - ret = -1; + header_offset = buf->size; + ret = lttng_dynamic_buffer_append(buf, &trigger_comm, + sizeof(trigger_comm)); + if (ret) { goto end; } - offset += sizeof(trigger_comm); - condition_size = lttng_condition_serialize(trigger->condition, - buf ? (buf + offset) : NULL); - if (condition_size < 0) { - ret = -1; + size_before_payload = buf->size; + ret = lttng_condition_serialize(trigger->condition, buf); + if (ret) { goto end; } - offset += condition_size; - action_size = lttng_action_serialize(trigger->action, - buf ? (buf + offset) : NULL); - if (action_size < 0) { - ret = -1; + ret = lttng_action_serialize(trigger->action, buf); + if (ret) { goto end; } - offset += action_size; - if (buf) { - trigger_comm.length = (uint32_t) (condition_size + action_size); - memcpy(buf, &trigger_comm, sizeof(trigger_comm)); - } - ret = offset; + /* Update payload size. */ + header = (struct lttng_trigger_comm *) ((char *) buf->data + header_offset); + header->length = buf->size - size_before_payload; end: return ret; } diff --git a/src/lib/lttng-ctl/channel.c b/src/lib/lttng-ctl/channel.c index 16474464d..49a3684db 100644 --- a/src/lib/lttng-ctl/channel.c +++ b/src/lib/lttng-ctl/channel.c @@ -575,14 +575,16 @@ enum lttng_notification_channel_status send_condition_command( const struct lttng_condition *condition) { int socket; - ssize_t command_size, ret; + ssize_t ret; enum lttng_notification_channel_status status = LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; - char *command_buffer = NULL; - struct lttng_notification_channel_message cmd_message = { - .type = type, + struct lttng_dynamic_buffer buffer; + struct lttng_notification_channel_message cmd_header = { + .type = (int8_t) type, }; + lttng_dynamic_buffer_init(&buffer); + if (!channel) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID; goto end; @@ -598,28 +600,24 @@ enum lttng_notification_channel_status send_condition_command( goto end_unlock; } - ret = lttng_condition_serialize(condition, NULL); - if (ret < 0) { - status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID; - goto end_unlock; - } - assert(ret < UINT32_MAX); - cmd_message.size = (uint32_t) ret; - command_size = ret + sizeof( - struct lttng_notification_channel_message); - command_buffer = zmalloc(command_size); - if (!command_buffer) { + ret = lttng_dynamic_buffer_append(&buffer, &cmd_header, + sizeof(cmd_header)); + if (ret) { + status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_unlock; } - memcpy(command_buffer, &cmd_message, sizeof(cmd_message)); - ret = lttng_condition_serialize(condition, - command_buffer + sizeof(cmd_message)); - if (ret < 0) { + ret = lttng_condition_serialize(condition, &buffer); + if (ret) { + status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID; goto end_unlock; } - ret = lttcomm_send_unix_sock(socket, command_buffer, command_size); + /* Update payload length. */ + ((struct lttng_notification_channel_message *) buffer.data)->size = + (uint32_t) (buffer.size - sizeof(cmd_header)); + + ret = lttcomm_send_unix_sock(socket, buffer.data, buffer.size); if (ret < 0) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_unlock; @@ -633,7 +631,7 @@ enum lttng_notification_channel_status send_condition_command( end_unlock: pthread_mutex_unlock(&channel->lock); end: - free(command_buffer); + lttng_dynamic_buffer_reset(&buffer); return status; } diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 8ca8e46ef..f0f2e801c 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -2666,9 +2666,9 @@ int lttng_register_trigger(struct lttng_trigger *trigger) { int ret; struct lttcomm_session_msg lsm; - char *trigger_buf = NULL; - ssize_t trigger_size; + struct lttng_dynamic_buffer buffer; + lttng_dynamic_buffer_init(&buffer); if (!trigger) { ret = -LTTNG_ERR_INVALID; goto end; @@ -2679,30 +2679,19 @@ int lttng_register_trigger(struct lttng_trigger *trigger) goto end; } - trigger_size = lttng_trigger_serialize(trigger, NULL); - if (trigger_size < 0) { + ret = lttng_trigger_serialize(trigger, &buffer); + if (ret < 0) { ret = -LTTNG_ERR_UNK; goto end; } - trigger_buf = zmalloc(trigger_size); - if (!trigger_buf) { - ret = -LTTNG_ERR_NOMEM; - goto end; - } - memset(&lsm, 0, sizeof(lsm)); lsm.cmd_type = LTTNG_REGISTER_TRIGGER; - if (lttng_trigger_serialize(trigger, trigger_buf) < 0) { - ret = -LTTNG_ERR_UNK; - goto end; - } - - lsm.u.trigger.length = (uint32_t) trigger_size; - ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, trigger_buf, - trigger_size, NULL); + lsm.u.trigger.length = (uint32_t) buffer.size; + ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, buffer.data, + buffer.size, NULL); end: - free(trigger_buf); + lttng_dynamic_buffer_reset(&buffer); return ret; } @@ -2710,43 +2699,32 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) { int ret; struct lttcomm_session_msg lsm; - char *trigger_buf = NULL; - ssize_t trigger_size; + struct lttng_dynamic_buffer buffer; + lttng_dynamic_buffer_init(&buffer); if (!trigger) { ret = -LTTNG_ERR_INVALID; goto end; } if (!lttng_trigger_validate(trigger)) { - ret = -LTTNG_ERR_INVALID; + ret = -LTTNG_ERR_INVALID_TRIGGER; goto end; } - trigger_size = lttng_trigger_serialize(trigger, NULL); - if (trigger_size < 0) { + ret = lttng_trigger_serialize(trigger, &buffer); + if (ret < 0) { ret = -LTTNG_ERR_UNK; goto end; } - trigger_buf = zmalloc(trigger_size); - if (!trigger_buf) { - ret = -LTTNG_ERR_NOMEM; - goto end; - } - memset(&lsm, 0, sizeof(lsm)); lsm.cmd_type = LTTNG_UNREGISTER_TRIGGER; - if (lttng_trigger_serialize(trigger, trigger_buf) < 0) { - ret = -LTTNG_ERR_UNK; - goto end; - } - - lsm.u.trigger.length = (uint32_t) trigger_size; - ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, trigger_buf, - trigger_size, NULL); + lsm.u.trigger.length = (uint32_t) buffer.size; + ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, buffer.data, + buffer.size, NULL); end: - free(trigger_buf); + lttng_dynamic_buffer_reset(&buffer); return ret; } -- 2.34.1