From: Jérémie Galarneau Date: Wed, 10 Jun 2020 19:39:47 +0000 (-0400) Subject: liblttng-ctl: use lttng_payload for serialize/create_from_buffer X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=commitdiff_plain;h=c0a66c84b5b2484b75798aec7543b680b4d4ab6c liblttng-ctl: use lttng_payload for serialize/create_from_buffer Some objects used in the sessiond <-> liblttng-ctl communication (e.g. such as userspace probe event rule) contain file descriptors that must be carried accross process boundaries (fd passing). Since those objects are often nested within a higher-level object hierarchy, it makes sense to adapt the existing serialize/create_from_buffer interface to use an lttng_payload. An lttng_payload contains a dynamic buffer and an array of file descriptors. Objects are expected to push their file descriptors in the payload in the same way they currently push the bytes of their binary representation in a dynamic buffer. Conversely, an lttng_payload_view interface is added and contains a buffer_view and an iterator which allows objects to ̀ pop` a file descriptors when appropriate. Tests are added to validate the FD consumption behaviour depending on the origin of payload views (root view or descendant view). Signed-off-by: Jérémie Galarneau Change-Id: Id378d8b5a3376a074ab138a60733377e39a24133 --- diff --git a/include/lttng/action/action-internal.h b/include/lttng/action/action-internal.h index f747276c7..152b27eab 100644 --- a/include/lttng/action/action-internal.h +++ b/include/lttng/action/action-internal.h @@ -12,17 +12,19 @@ #include #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 int (*action_serialize_cb)(struct lttng_action *action, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *payload); typedef bool (*action_equal_cb)(const struct lttng_action *a, const struct lttng_action *b); -typedef ssize_t (*action_create_from_buffer_cb)( - const struct lttng_buffer_view *view, +typedef ssize_t (*action_create_from_payload_cb)( + struct lttng_payload_view *view, struct lttng_action **action); struct lttng_action { @@ -51,10 +53,10 @@ bool lttng_action_validate(struct lttng_action *action); LTTNG_HIDDEN int lttng_action_serialize(struct lttng_action *action, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *buf); LTTNG_HIDDEN -ssize_t lttng_action_create_from_buffer(const struct lttng_buffer_view *view, +ssize_t lttng_action_create_from_payload(struct lttng_payload_view *view, struct lttng_action **action); LTTNG_HIDDEN diff --git a/include/lttng/action/notify-internal.h b/include/lttng/action/notify-internal.h index a9d50612d..1a6abe561 100644 --- a/include/lttng/action/notify-internal.h +++ b/include/lttng/action/notify-internal.h @@ -16,8 +16,8 @@ struct lttng_action_notify { }; LTTNG_HIDDEN -ssize_t lttng_action_notify_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_action_notify_create_from_payload( + struct lttng_payload_view *view, struct lttng_action **action); #endif /* LTTNG_ACTION_NOTIFY_INTERNAL_H */ diff --git a/include/lttng/action/rotate-session-internal.h b/include/lttng/action/rotate-session-internal.h index 2cce9fc78..eb1e53451 100644 --- a/include/lttng/action/rotate-session-internal.h +++ b/include/lttng/action/rotate-session-internal.h @@ -8,22 +8,20 @@ #ifndef LTTNG_ACTION_ROTATE_SESSION_INTERNAL_H #define LTTNG_ACTION_ROTATE_SESSION_INTERNAL_H -#include - #include struct lttng_action; -struct lttng_buffer_view; +struct lttng_payload_view; /* - * Create a "rotate session" action from a buffer view. + * Create a "rotate session" action from a payload view. * * On success, return the number of bytes consumed from `view`, and the created * action in `*action`. On failure, return -1. */ LTTNG_HIDDEN -extern ssize_t lttng_action_rotate_session_create_from_buffer( - const struct lttng_buffer_view *view, +extern ssize_t lttng_action_rotate_session_create_from_payload( + struct lttng_payload_view *view, struct lttng_action **action); #endif /* LTTNG_ACTION_ROTATE_SESSION_INTERNAL_H */ diff --git a/include/lttng/action/start-session-internal.h b/include/lttng/action/start-session-internal.h index 7f60103eb..bc15c78a6 100644 --- a/include/lttng/action/start-session-internal.h +++ b/include/lttng/action/start-session-internal.h @@ -8,22 +8,20 @@ #ifndef LTTNG_ACTION_START_SESSION_INTERNAL_H #define LTTNG_ACTION_START_SESSION_INTERNAL_H -#include - #include struct lttng_action; -struct lttng_buffer_view; +struct lttng_payload_view; /* - * Create a "start session" action from a buffer view. + * Create a "start session" action from a payload view. * * On success, return the number of bytes consumed from `view`, and the created * action in `*action`. On failure, return -1. */ LTTNG_HIDDEN -extern ssize_t lttng_action_start_session_create_from_buffer( - const struct lttng_buffer_view *view, +extern ssize_t lttng_action_start_session_create_from_payload( + struct lttng_payload_view *view, struct lttng_action **action); #endif /* LTTNG_ACTION_START_SESSION_INTERNAL_H */ diff --git a/include/lttng/action/stop-session-internal.h b/include/lttng/action/stop-session-internal.h index 150002e84..592ef0e2c 100644 --- a/include/lttng/action/stop-session-internal.h +++ b/include/lttng/action/stop-session-internal.h @@ -8,22 +8,20 @@ #ifndef LTTNG_ACTION_STOP_SESSION_INTERNAL_H #define LTTNG_ACTION_STOP_SESSION_INTERNAL_H -#include - #include struct lttng_action; -struct lttng_buffer_view; +struct lttng_payload_view; /* - * Create a "stop session" action from a buffer view. + * Create a "stop session" action from a payload view. * * On success, return the number of bytes consumed from `view`, and the created * action in `*action`. On failure, return -1. */ LTTNG_HIDDEN -extern ssize_t lttng_action_stop_session_create_from_buffer( - const struct lttng_buffer_view *view, +extern ssize_t lttng_action_stop_session_create_from_payload( + struct lttng_payload_view *view, struct lttng_action **action); #endif /* LTTNG_ACTION_STOP_SESSION_INTERNAL_H */ diff --git a/include/lttng/condition/buffer-usage-internal.h b/include/lttng/condition/buffer-usage-internal.h index edeeb941d..8ddce3505 100644 --- a/include/lttng/condition/buffer-usage-internal.h +++ b/include/lttng/condition/buffer-usage-internal.h @@ -68,23 +68,23 @@ struct lttng_evaluation *lttng_evaluation_buffer_usage_create( uint64_t capacity); LTTNG_HIDDEN -ssize_t lttng_condition_buffer_usage_low_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_buffer_usage_low_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **condition); LTTNG_HIDDEN -ssize_t lttng_condition_buffer_usage_high_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_buffer_usage_high_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **condition); LTTNG_HIDDEN -ssize_t lttng_evaluation_buffer_usage_low_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_buffer_usage_low_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **evaluation); LTTNG_HIDDEN -ssize_t lttng_evaluation_buffer_usage_high_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_buffer_usage_high_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **evaluation); #endif /* LTTNG_CONDITION_BUFFER_USAGE_INTERNAL_H */ diff --git a/include/lttng/condition/condition-internal.h b/include/lttng/condition/condition-internal.h index 60686d29f..306272ab8 100644 --- a/include/lttng/condition/condition-internal.h +++ b/include/lttng/condition/condition-internal.h @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -21,11 +21,11 @@ typedef void (*condition_destroy_cb)(struct lttng_condition *condition); typedef bool (*condition_validate_cb)(const struct lttng_condition *condition); typedef int (*condition_serialize_cb)( const struct lttng_condition *condition, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *payload); typedef bool (*condition_equal_cb)(const struct lttng_condition *a, const struct lttng_condition *b); -typedef ssize_t (*condition_create_from_buffer_cb)( - const struct lttng_buffer_view *view, +typedef ssize_t (*condition_create_from_payload_cb)( + struct lttng_payload_view *view, struct lttng_condition **condition); struct lttng_condition { @@ -50,13 +50,13 @@ LTTNG_HIDDEN bool lttng_condition_validate(const struct lttng_condition *condition); LTTNG_HIDDEN -ssize_t lttng_condition_create_from_buffer( - const struct lttng_buffer_view *buffer, +ssize_t lttng_condition_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **condition); LTTNG_HIDDEN int lttng_condition_serialize(const struct lttng_condition *condition, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *payload); 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 a2cb432fc..15ae4af4d 100644 --- a/include/lttng/condition/evaluation-internal.h +++ b/include/lttng/condition/evaluation-internal.h @@ -10,15 +10,16 @@ #include #include -#include -#include #include #include +struct lttng_payload; +struct lttng_payload_view; + typedef void (*evaluation_destroy_cb)(struct lttng_evaluation *evaluation); typedef int (*evaluation_serialize_cb)( const struct lttng_evaluation *evaluation, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *payload); struct lttng_evaluation_comm { /* enum lttng_condition_type type */ @@ -37,11 +38,11 @@ void lttng_evaluation_init(struct lttng_evaluation *evaluation, enum lttng_condition_type type); LTTNG_HIDDEN -ssize_t lttng_evaluation_create_from_buffer(const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_create_from_payload(struct lttng_payload_view *view, struct lttng_evaluation **evaluation); LTTNG_HIDDEN int lttng_evaluation_serialize(const struct lttng_evaluation *evaluation, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *payload); #endif /* LTTNG_EVALUATION_INTERNAL_H */ diff --git a/include/lttng/condition/session-consumed-size-internal.h b/include/lttng/condition/session-consumed-size-internal.h index effc1e1f5..fdd3ecc11 100644 --- a/include/lttng/condition/session-consumed-size-internal.h +++ b/include/lttng/condition/session-consumed-size-internal.h @@ -14,6 +14,9 @@ #include #include +struct lttng_payload; +struct lttng_payload_view; + struct lttng_condition_session_consumed_size { struct lttng_condition parent; struct { @@ -44,13 +47,13 @@ struct lttng_evaluation *lttng_evaluation_session_consumed_size_create( uint64_t consumed); LTTNG_HIDDEN -ssize_t lttng_condition_session_consumed_size_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_session_consumed_size_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **condition); LTTNG_HIDDEN -ssize_t lttng_evaluation_session_consumed_size_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_session_consumed_size_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **evaluation); #endif /* LTTNG_CONDITION_SESSION_CONSUMED_SIZE_INTERNAL_H */ diff --git a/include/lttng/condition/session-rotation-internal.h b/include/lttng/condition/session-rotation-internal.h index 8aac28b14..7772b8bea 100644 --- a/include/lttng/condition/session-rotation-internal.h +++ b/include/lttng/condition/session-rotation-internal.h @@ -38,13 +38,13 @@ struct lttng_evaluation_session_rotation_comm { } LTTNG_PACKED; LTTNG_HIDDEN -ssize_t lttng_condition_session_rotation_ongoing_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_session_rotation_ongoing_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **condition); LTTNG_HIDDEN -ssize_t lttng_condition_session_rotation_completed_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_session_rotation_completed_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **condition); LTTNG_HIDDEN @@ -58,13 +58,13 @@ struct lttng_evaluation *lttng_evaluation_session_rotation_completed_create( struct lttng_trace_archive_location *location); LTTNG_HIDDEN -ssize_t lttng_evaluation_session_rotation_ongoing_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_session_rotation_ongoing_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **evaluation); LTTNG_HIDDEN -ssize_t lttng_evaluation_session_rotation_completed_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_session_rotation_completed_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **evaluation); #endif /* LTTNG_CONDITION_SESSION_ROTATION_INTERNAL_H */ diff --git a/include/lttng/notification/notification-internal.h b/include/lttng/notification/notification-internal.h index c50536dc6..a4b0eec2e 100644 --- a/include/lttng/notification/notification-internal.h +++ b/include/lttng/notification/notification-internal.h @@ -10,12 +10,13 @@ #include #include -#include -#include #include #include #include +struct lttng_payload; +struct lttng_payload_view; + struct lttng_notification { struct lttng_condition *condition; struct lttng_evaluation *evaluation; @@ -35,11 +36,11 @@ struct lttng_notification *lttng_notification_create( LTTNG_HIDDEN int lttng_notification_serialize(const struct lttng_notification *notification, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *payload); LTTNG_HIDDEN -ssize_t lttng_notification_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_notification_create_from_payload( + struct lttng_payload_view *view, struct lttng_notification **notification); #endif /* LTTNG_NOTIFICATION_INTERNAL_H */ diff --git a/include/lttng/trigger/trigger-internal.h b/include/lttng/trigger/trigger-internal.h index cff4504a7..2cef67d07 100644 --- a/include/lttng/trigger/trigger-internal.h +++ b/include/lttng/trigger/trigger-internal.h @@ -10,12 +10,13 @@ #include #include -#include -#include #include #include #include +struct lttng_payload; +struct lttng_payload_view; + struct lttng_trigger { struct lttng_condition *condition; struct lttng_action *action; @@ -29,12 +30,12 @@ struct lttng_trigger_comm { } LTTNG_PACKED; LTTNG_HIDDEN -ssize_t lttng_trigger_create_from_buffer(const struct lttng_buffer_view *view, +ssize_t lttng_trigger_create_from_payload(struct lttng_payload_view *view, struct lttng_trigger **trigger); LTTNG_HIDDEN int lttng_trigger_serialize(struct lttng_trigger *trigger, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *payload); LTTNG_HIDDEN const struct lttng_condition *lttng_trigger_get_const_condition( diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index e45d4423a..296357756 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -7,6 +7,7 @@ */ #include "bin/lttng-sessiond/tracker.h" +#include "common/sessiond-comm/payload.h" #include "lttng/lttng-error.h" #include "lttng/tracker.h" #define _LGPL_SOURCE @@ -26,6 +27,8 @@ #include #include #include +#include +#include #include #include #include @@ -4350,19 +4353,19 @@ int cmd_register_trigger(struct command_ctx *cmd_ctx, int sock, size_t trigger_len; ssize_t sock_recv_len; struct lttng_trigger *trigger = NULL; - struct lttng_buffer_view view; - struct lttng_dynamic_buffer trigger_buffer; + struct lttng_payload trigger_payload; - lttng_dynamic_buffer_init(&trigger_buffer); + lttng_payload_init(&trigger_payload); trigger_len = (size_t) cmd_ctx->lsm->u.trigger.length; - ret = lttng_dynamic_buffer_set_size(&trigger_buffer, trigger_len); + ret = lttng_dynamic_buffer_set_size( + &trigger_payload.buffer, trigger_len); if (ret) { ret = LTTNG_ERR_NOMEM; goto end; } - sock_recv_len = lttcomm_recv_unix_sock(sock, trigger_buffer.data, - trigger_len); + sock_recv_len = lttcomm_recv_unix_sock( + sock, trigger_payload.buffer.data, trigger_len); if (sock_recv_len < 0 || sock_recv_len != trigger_len) { ERR("Failed to receive \"register trigger\" command payload"); /* TODO: should this be a new error enum ? */ @@ -4370,12 +4373,17 @@ int cmd_register_trigger(struct command_ctx *cmd_ctx, int sock, goto end; } - view = lttng_buffer_view_from_dynamic_buffer(&trigger_buffer, 0, -1); - if (lttng_trigger_create_from_buffer(&view, &trigger) != - trigger_len) { - ERR("Invalid trigger payload received in \"register trigger\" command"); - ret = LTTNG_ERR_INVALID_TRIGGER; - goto end; + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &trigger_payload, 0, -1); + + if (lttng_trigger_create_from_payload(&view, &trigger) != + trigger_len) { + ERR("Invalid trigger payload received in \"register trigger\" command"); + ret = LTTNG_ERR_INVALID_TRIGGER; + goto end; + } } ret = notification_thread_command_register_trigger(notification_thread, @@ -4384,7 +4392,7 @@ int cmd_register_trigger(struct command_ctx *cmd_ctx, int sock, trigger = NULL; end: lttng_trigger_destroy(trigger); - lttng_dynamic_buffer_reset(&trigger_buffer); + lttng_payload_reset(&trigger_payload); return ret; } @@ -4395,19 +4403,19 @@ int cmd_unregister_trigger(struct command_ctx *cmd_ctx, int sock, size_t trigger_len; ssize_t sock_recv_len; struct lttng_trigger *trigger = NULL; - struct lttng_buffer_view view; - struct lttng_dynamic_buffer trigger_buffer; + struct lttng_payload trigger_payload; - lttng_dynamic_buffer_init(&trigger_buffer); + lttng_payload_init(&trigger_payload); trigger_len = (size_t) cmd_ctx->lsm->u.trigger.length; - ret = lttng_dynamic_buffer_set_size(&trigger_buffer, trigger_len); + ret = lttng_dynamic_buffer_set_size( + &trigger_payload.buffer, trigger_len); if (ret) { ret = LTTNG_ERR_NOMEM; goto end; } - sock_recv_len = lttcomm_recv_unix_sock(sock, trigger_buffer.data, - trigger_len); + sock_recv_len = lttcomm_recv_unix_sock( + sock, trigger_payload.buffer.data, trigger_len); if (sock_recv_len < 0 || sock_recv_len != trigger_len) { ERR("Failed to receive \"unregister trigger\" command payload"); /* TODO: should this be a new error enum ? */ @@ -4415,19 +4423,24 @@ int cmd_unregister_trigger(struct command_ctx *cmd_ctx, int sock, goto end; } - view = lttng_buffer_view_from_dynamic_buffer(&trigger_buffer, 0, -1); - if (lttng_trigger_create_from_buffer(&view, &trigger) != - trigger_len) { - ERR("Invalid trigger payload received in \"unregister trigger\" command"); - ret = LTTNG_ERR_INVALID_TRIGGER; - goto end; + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &trigger_payload, 0, -1); + + if (lttng_trigger_create_from_payload(&view, &trigger) != + trigger_len) { + ERR("Invalid trigger payload received in \"unregister trigger\" command"); + ret = LTTNG_ERR_INVALID_TRIGGER; + goto end; + } } ret = notification_thread_command_unregister_trigger(notification_thread, trigger); end: lttng_trigger_destroy(trigger); - lttng_dynamic_buffer_reset(&trigger_buffer); + lttng_payload_reset(&trigger_payload); return ret; } diff --git a/src/bin/lttng-sessiond/notification-thread-events.c b/src/bin/lttng-sessiond/notification-thread-events.c index 6c69a0232..2cb6ad68a 100644 --- a/src/bin/lttng-sessiond/notification-thread-events.c +++ b/src/bin/lttng-sessiond/notification-thread-events.c @@ -2801,14 +2801,14 @@ int client_dispatch_message(struct notification_client *client, struct lttng_condition *condition; enum lttng_notification_channel_status status = LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; - const struct lttng_buffer_view condition_view = - lttng_buffer_view_from_dynamic_buffer( + struct lttng_payload_view condition_view = + lttng_payload_view_from_dynamic_buffer( &client->communication.inbound.buffer, 0, -1); size_t expected_condition_size = client->communication.inbound.buffer.size; - ret = lttng_condition_create_from_buffer(&condition_view, + ret = lttng_condition_create_from_payload(&condition_view, &condition); if (ret != expected_condition_size) { ERR("[notification-thread] Malformed condition received from client"); @@ -3112,7 +3112,7 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger, uid_t channel_uid, gid_t channel_gid) { int ret = 0; - struct lttng_dynamic_buffer msg_buffer; + struct lttng_payload msg_payload; struct notification_client_list_element *client_list_element, *tmp; const struct lttng_notification notification = { .condition = (struct lttng_condition *) lttng_trigger_get_const_condition(trigger), @@ -3122,15 +3122,15 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger, .type = (int8_t) LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_NOTIFICATION, }; - lttng_dynamic_buffer_init(&msg_buffer); + lttng_payload_init(&msg_payload); - ret = lttng_dynamic_buffer_append(&msg_buffer, &msg_header, + ret = lttng_dynamic_buffer_append(&msg_payload.buffer, &msg_header, sizeof(msg_header)); if (ret) { goto end; } - ret = lttng_notification_serialize(¬ification, &msg_buffer); + ret = lttng_notification_serialize(¬ification, &msg_payload); if (ret) { ERR("[notification-thread] Failed to serialize notification"); ret = -1; @@ -3138,8 +3138,8 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger, } /* Update payload size. */ - ((struct lttng_notification_channel_message * ) msg_buffer.data)->size = - (uint32_t) (msg_buffer.size - sizeof(msg_header)); + ((struct lttng_notification_channel_message * ) msg_payload.buffer.data)->size = + (uint32_t) (msg_payload.buffer.size - sizeof(msg_header)); cds_list_for_each_entry_safe(client_list_element, tmp, &client_list->list, node) { @@ -3154,7 +3154,7 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger, } DBG("[notification-thread] Sending notification to client (fd = %i, %zu bytes)", - client->socket, msg_buffer.size); + client->socket, msg_payload.buffer.size); if (client->communication.outbound.buffer.size) { /* * Outgoing data is already buffered for this client; @@ -3178,7 +3178,7 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger, ret = lttng_dynamic_buffer_append_buffer( &client->communication.outbound.buffer, - &msg_buffer); + &msg_payload.buffer); if (ret) { goto end; } @@ -3190,7 +3190,7 @@ int send_evaluation_to_clients(const struct lttng_trigger *trigger, } ret = 0; end: - lttng_dynamic_buffer_reset(&msg_buffer); + lttng_payload_reset(&msg_payload); return ret; } diff --git a/src/common/actions/action.c b/src/common/actions/action.c index 98e1849dd..c6b57b9cf 100644 --- a/src/common/actions/action.c +++ b/src/common/actions/action.c @@ -92,20 +92,20 @@ end: LTTNG_HIDDEN int lttng_action_serialize(struct lttng_action *action, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { int ret; struct lttng_action_comm action_comm = { .action_type = (int8_t) action->type, }; - ret = lttng_dynamic_buffer_append(buf, &action_comm, + ret = lttng_dynamic_buffer_append(&payload->buffer, &action_comm, sizeof(action_comm)); if (ret) { goto end; } - ret = action->serialize(action, buf); + ret = action->serialize(action, payload); if (ret) { goto end; } @@ -114,42 +114,41 @@ end: } LTTNG_HIDDEN -ssize_t lttng_action_create_from_buffer(const struct lttng_buffer_view *view, +ssize_t lttng_action_create_from_payload(struct lttng_payload_view *view, struct lttng_action **action) { ssize_t consumed_len, specific_action_consumed_len; const struct lttng_action_comm *action_comm; - action_create_from_buffer_cb create_from_buffer_cb; - struct lttng_buffer_view specific_action_view; + action_create_from_payload_cb create_from_payload_cb; if (!view || !action) { consumed_len = -1; goto end; } - action_comm = (const struct lttng_action_comm *) view->data; + action_comm = (const struct lttng_action_comm *) view->buffer.data; - DBG("Create action from buffer: action-type=%s", + DBG("Create action from payload: action-type=%s", lttng_action_type_string(action_comm->action_type)); switch (action_comm->action_type) { case LTTNG_ACTION_TYPE_NOTIFY: - create_from_buffer_cb = lttng_action_notify_create_from_buffer; + create_from_payload_cb = lttng_action_notify_create_from_payload; break; case LTTNG_ACTION_TYPE_ROTATE_SESSION: - create_from_buffer_cb = - lttng_action_rotate_session_create_from_buffer; + create_from_payload_cb = + lttng_action_rotate_session_create_from_payload; break; case LTTNG_ACTION_TYPE_START_SESSION: - create_from_buffer_cb = - lttng_action_start_session_create_from_buffer; + create_from_payload_cb = + lttng_action_start_session_create_from_payload; break; case LTTNG_ACTION_TYPE_STOP_SESSION: - create_from_buffer_cb = - lttng_action_stop_session_create_from_buffer; + create_from_payload_cb = + lttng_action_stop_session_create_from_payload; break; default: - ERR("Failed to create action from buffer, unhandled action type: action-type=%u (%s)", + ERR("Failed to create action from payload, unhandled action type: action-type=%u (%s)", action_comm->action_type, lttng_action_type_string( action_comm->action_type)); @@ -157,13 +156,16 @@ ssize_t lttng_action_create_from_buffer(const struct lttng_buffer_view *view, goto end; } - /* Create buffer view for the action-type-specific data. */ - specific_action_view = lttng_buffer_view_from_view(view, - sizeof(struct lttng_action_comm), - view->size - sizeof(struct lttng_action_comm)); + { + /* Create buffer view for the action-type-specific data. */ + struct lttng_payload_view specific_action_view = + lttng_payload_view_from_view(view, + sizeof(struct lttng_action_comm), + -1); - specific_action_consumed_len = - create_from_buffer_cb(&specific_action_view, action); + specific_action_consumed_len = create_from_payload_cb( + &specific_action_view, action); + } if (specific_action_consumed_len < 0) { ERR("Failed to create specific action from buffer."); consumed_len = -1; diff --git a/src/common/actions/notify.c b/src/common/actions/notify.c index d03bacb2e..fc7d170c7 100644 --- a/src/common/actions/notify.c +++ b/src/common/actions/notify.c @@ -18,7 +18,7 @@ void lttng_action_notify_destroy(struct lttng_action *action) static int lttng_action_notify_serialize(struct lttng_action *action, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { return 0; } @@ -48,8 +48,8 @@ end: return ¬ify->parent; } -ssize_t lttng_action_notify_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_action_notify_create_from_payload( + struct lttng_payload_view *view, struct lttng_action **action) { ssize_t consumed_length; diff --git a/src/common/actions/rotate-session.c b/src/common/actions/rotate-session.c index 98806230a..9255034da 100644 --- a/src/common/actions/rotate-session.c +++ b/src/common/actions/rotate-session.c @@ -95,7 +95,7 @@ end: return is_equal; } static int lttng_action_rotate_session_serialize( - struct lttng_action *action, struct lttng_dynamic_buffer *buf) + struct lttng_action *action, struct lttng_payload *payload) { struct lttng_action_rotate_session *action_rotate_session; struct lttng_action_rotate_session_comm comm; @@ -103,7 +103,7 @@ static int lttng_action_rotate_session_serialize( int ret; assert(action); - assert(buf); + assert(payload); action_rotate_session = action_rotate_session_from_action(action); @@ -115,13 +115,14 @@ static int lttng_action_rotate_session_serialize( session_name_len = strlen(action_rotate_session->session_name) + 1; comm.session_name_len = session_name_len; - ret = lttng_dynamic_buffer_append(buf, &comm, sizeof(comm)); + ret = lttng_dynamic_buffer_append( + &payload->buffer, &comm, sizeof(comm)); if (ret) { ret = -1; goto end; } - ret = lttng_dynamic_buffer_append(buf, + ret = lttng_dynamic_buffer_append(&payload->buffer, action_rotate_session->session_name, session_name_len); if (ret) { ret = -1; @@ -150,8 +151,8 @@ end: return; } -ssize_t lttng_action_rotate_session_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_action_rotate_session_create_from_payload( + struct lttng_payload_view *view, struct lttng_action **p_action) { ssize_t consumed_len; @@ -166,11 +167,11 @@ ssize_t lttng_action_rotate_session_create_from_buffer( goto end; } - comm = (const struct lttng_action_rotate_session_comm *) view->data; + comm = (typeof(comm)) view->buffer.data; session_name = (const char *) &comm->data; if (!lttng_buffer_view_contains_string( - view, session_name, comm->session_name_len)) { + &view->buffer, session_name, comm->session_name_len)) { consumed_len = -1; goto end; } @@ -182,8 +183,7 @@ ssize_t lttng_action_rotate_session_create_from_buffer( goto end; } - consumed_len = sizeof(struct lttng_action_rotate_session_comm) + - comm->session_name_len; + consumed_len = sizeof(*comm) + comm->session_name_len; *p_action = action; action = NULL; diff --git a/src/common/actions/start-session.c b/src/common/actions/start-session.c index d4095526e..eeb00a5da 100644 --- a/src/common/actions/start-session.c +++ b/src/common/actions/start-session.c @@ -96,7 +96,7 @@ end: } static int lttng_action_start_session_serialize( - struct lttng_action *action, struct lttng_dynamic_buffer *buf) + struct lttng_action *action, struct lttng_payload *payload) { struct lttng_action_start_session *action_start_session; struct lttng_action_start_session_comm comm; @@ -104,7 +104,7 @@ static int lttng_action_start_session_serialize( int ret; assert(action); - assert(buf); + assert(payload); action_start_session = action_start_session_from_action(action); @@ -116,13 +116,13 @@ static int lttng_action_start_session_serialize( session_name_len = strlen(action_start_session->session_name) + 1; comm.session_name_len = session_name_len; - ret = lttng_dynamic_buffer_append(buf, &comm, sizeof(comm)); + ret = lttng_dynamic_buffer_append(&payload->buffer, &comm, sizeof(comm)); if (ret) { ret = -1; goto end; } - ret = lttng_dynamic_buffer_append(buf, + ret = lttng_dynamic_buffer_append(&payload->buffer, action_start_session->session_name, session_name_len); if (ret) { ret = -1; @@ -151,8 +151,8 @@ end: return; } -ssize_t lttng_action_start_session_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_action_start_session_create_from_payload( + struct lttng_payload_view *view, struct lttng_action **p_action) { ssize_t consumed_len; @@ -167,11 +167,11 @@ ssize_t lttng_action_start_session_create_from_buffer( goto end; } - comm = (const struct lttng_action_start_session_comm *) view->data; + comm = (typeof(comm)) view->buffer.data; session_name = (const char *) &comm->data; - if (!lttng_buffer_view_contains_string( - view, session_name, comm->session_name_len)) { + if (!lttng_buffer_view_contains_string(&view->buffer, session_name, + comm->session_name_len)) { consumed_len = -1; goto end; } @@ -183,8 +183,7 @@ ssize_t lttng_action_start_session_create_from_buffer( goto end; } - consumed_len = sizeof(struct lttng_action_start_session_comm) + - comm->session_name_len; + consumed_len = sizeof(*comm) + comm->session_name_len; *p_action = action; action = NULL; diff --git a/src/common/actions/stop-session.c b/src/common/actions/stop-session.c index a36e873cf..33077b676 100644 --- a/src/common/actions/stop-session.c +++ b/src/common/actions/stop-session.c @@ -96,7 +96,7 @@ end: } static int lttng_action_stop_session_serialize( - struct lttng_action *action, struct lttng_dynamic_buffer *buf) + struct lttng_action *action, struct lttng_payload *payload) { struct lttng_action_stop_session *action_stop_session; struct lttng_action_stop_session_comm comm; @@ -104,7 +104,7 @@ static int lttng_action_stop_session_serialize( int ret; assert(action); - assert(buf); + assert(payload); action_stop_session = action_stop_session_from_action(action); @@ -116,13 +116,14 @@ static int lttng_action_stop_session_serialize( session_name_len = strlen(action_stop_session->session_name) + 1; comm.session_name_len = session_name_len; - ret = lttng_dynamic_buffer_append(buf, &comm, sizeof(comm)); + ret = lttng_dynamic_buffer_append( + &payload->buffer, &comm, sizeof(comm)); if (ret) { ret = -1; goto end; } - ret = lttng_dynamic_buffer_append(buf, + ret = lttng_dynamic_buffer_append(&payload->buffer, action_stop_session->session_name, session_name_len); if (ret) { ret = -1; @@ -151,8 +152,8 @@ end: return; } -ssize_t lttng_action_stop_session_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_action_stop_session_create_from_payload( + struct lttng_payload_view *view, struct lttng_action **p_action) { ssize_t consumed_len; @@ -167,11 +168,11 @@ ssize_t lttng_action_stop_session_create_from_buffer( goto end; } - comm = (const struct lttng_action_stop_session_comm *) view->data; + comm = (typeof(comm)) view->buffer.data; session_name = (const char *) &comm->data; if (!lttng_buffer_view_contains_string( - view, session_name, comm->session_name_len)) { + &view->buffer, session_name, comm->session_name_len)) { consumed_len = -1; goto end; } @@ -183,8 +184,7 @@ ssize_t lttng_action_stop_session_create_from_buffer( goto end; } - consumed_len = sizeof(struct lttng_action_stop_session_comm) + - comm->session_name_len; + consumed_len = sizeof(*comm) + comm->session_name_len; *p_action = action; action = NULL; diff --git a/src/common/buffer-usage.c b/src/common/buffer-usage.c index 92081c910..ad6fb8416 100644 --- a/src/common/buffer-usage.c +++ b/src/common/buffer-usage.c @@ -91,7 +91,7 @@ end: static int lttng_condition_buffer_usage_serialize( const struct lttng_condition *condition, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { int ret; struct lttng_condition_buffer_usage *usage; @@ -134,17 +134,19 @@ int lttng_condition_buffer_usage_serialize( usage_comm.threshold = val; } - ret = lttng_dynamic_buffer_append(buf, &usage_comm, + ret = lttng_dynamic_buffer_append(&payload->buffer, &usage_comm, sizeof(usage_comm)); if (ret) { goto end; } - ret = lttng_dynamic_buffer_append(buf, usage->session_name, + + ret = lttng_dynamic_buffer_append(&payload->buffer, usage->session_name, session_name_len); if (ret) { goto end; } - ret = lttng_dynamic_buffer_append(buf, usage->channel_name, + + ret = lttng_dynamic_buffer_append(&payload->buffer, usage->channel_name, channel_name_len); if (ret) { goto end; @@ -243,8 +245,8 @@ struct lttng_condition *lttng_condition_buffer_usage_high_create(void) } static -ssize_t init_condition_from_buffer(struct lttng_condition *condition, - const struct lttng_buffer_view *src_view) +ssize_t init_condition_from_payload(struct lttng_condition *condition, + struct lttng_payload_view *src_view) { ssize_t ret, condition_size; enum lttng_condition_status status; @@ -253,14 +255,14 @@ ssize_t init_condition_from_buffer(struct lttng_condition *condition, const char *session_name, *channel_name; struct lttng_buffer_view names_view; - if (src_view->size < sizeof(*condition_comm)) { + if (src_view->buffer.size < sizeof(*condition_comm)) { ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header"); ret = -1; goto end; } - condition_comm = (const struct lttng_condition_buffer_usage_comm *) src_view->data; - names_view = lttng_buffer_view_from_view(src_view, + condition_comm = (typeof(condition_comm)) src_view->buffer.data; + names_view = lttng_buffer_view_from_view(&src_view->buffer, sizeof(*condition_comm), -1); if (condition_comm->session_name_len > LTTNG_NAME_MAX || @@ -286,6 +288,7 @@ ssize_t init_condition_from_buffer(struct lttng_condition *condition, condition, fixed_to_double(condition_comm->threshold)); } + if (status != LTTNG_CONDITION_STATUS_OK) { ERR("Failed to initialize buffer usage condition threshold"); ret = -1; @@ -354,8 +357,8 @@ end: } LTTNG_HIDDEN -ssize_t lttng_condition_buffer_usage_low_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_buffer_usage_low_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **_condition) { ssize_t ret; @@ -367,7 +370,7 @@ ssize_t lttng_condition_buffer_usage_low_create_from_buffer( goto error; } - ret = init_condition_from_buffer(condition, view); + ret = init_condition_from_payload(condition, view); if (ret < 0) { goto error; } @@ -380,8 +383,8 @@ error: } LTTNG_HIDDEN -ssize_t lttng_condition_buffer_usage_high_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_buffer_usage_high_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **_condition) { ssize_t ret; @@ -393,7 +396,7 @@ ssize_t lttng_condition_buffer_usage_high_create_from_buffer( goto error; } - ret = init_condition_from_buffer(condition, view); + ret = init_condition_from_payload(condition, view); if (ret < 0) { goto error; } @@ -406,15 +409,15 @@ error: } static -struct lttng_evaluation *create_evaluation_from_buffer( +struct lttng_evaluation *create_evaluation_from_payload( enum lttng_condition_type type, - const struct lttng_buffer_view *view) + struct lttng_payload_view *view) { const struct lttng_evaluation_buffer_usage_comm *comm = - (const struct lttng_evaluation_buffer_usage_comm *) view->data; + (typeof(comm)) view->buffer.data; struct lttng_evaluation *evaluation = NULL; - if (view->size < sizeof(*comm)) { + if (view->buffer.size < sizeof(*comm)) { goto end; } @@ -425,8 +428,8 @@ end: } LTTNG_HIDDEN -ssize_t lttng_evaluation_buffer_usage_low_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_buffer_usage_low_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **_evaluation) { ssize_t ret; @@ -437,7 +440,7 @@ ssize_t lttng_evaluation_buffer_usage_low_create_from_buffer( goto error; } - evaluation = create_evaluation_from_buffer( + evaluation = create_evaluation_from_payload( LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW, view); if (!evaluation) { ret = -1; @@ -453,8 +456,8 @@ error: } LTTNG_HIDDEN -ssize_t lttng_evaluation_buffer_usage_high_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_buffer_usage_high_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **_evaluation) { ssize_t ret; @@ -465,7 +468,7 @@ ssize_t lttng_evaluation_buffer_usage_high_create_from_buffer( goto error; } - evaluation = create_evaluation_from_buffer( + evaluation = create_evaluation_from_payload( LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH, view); if (!evaluation) { ret = -1; @@ -730,7 +733,7 @@ end: static int lttng_evaluation_buffer_usage_serialize( const struct lttng_evaluation *evaluation, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { struct lttng_evaluation_buffer_usage *usage; struct lttng_evaluation_buffer_usage_comm comm; @@ -740,7 +743,8 @@ int lttng_evaluation_buffer_usage_serialize( comm.buffer_use = usage->buffer_use; comm.buffer_capacity = usage->buffer_capacity; - return lttng_dynamic_buffer_append(buf, &comm, sizeof(comm)); + return lttng_dynamic_buffer_append( + &payload->buffer, &comm, sizeof(comm)); } static diff --git a/src/common/condition.c b/src/common/condition.c index 076f0627c..367f4a38b 100644 --- a/src/common/condition.c +++ b/src/common/condition.c @@ -55,10 +55,10 @@ end: LTTNG_HIDDEN int lttng_condition_serialize(const struct lttng_condition *condition, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { int ret; - struct lttng_condition_comm condition_comm = { 0 }; + struct lttng_condition_comm condition_comm = {}; if (!condition) { ret = -1; @@ -67,13 +67,13 @@ int lttng_condition_serialize(const struct lttng_condition *condition, condition_comm.condition_type = (int8_t) condition->type; - ret = lttng_dynamic_buffer_append(buf, &condition_comm, + ret = lttng_dynamic_buffer_append(&payload->buffer, &condition_comm, sizeof(condition_comm)); if (ret) { goto end; } - ret = condition->serialize(condition, buf); + ret = condition->serialize(condition, payload); if (ret) { goto end; } @@ -106,38 +106,38 @@ end: } LTTNG_HIDDEN -ssize_t lttng_condition_create_from_buffer( - const struct lttng_buffer_view *buffer, +ssize_t lttng_condition_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **condition) { ssize_t ret, condition_size = 0; const struct lttng_condition_comm *condition_comm; - condition_create_from_buffer_cb create_from_buffer = NULL; + condition_create_from_payload_cb create_from_payload = NULL; - if (!buffer || !condition) { + if (!view || !condition) { ret = -1; goto end; } DBG("Deserializing condition from buffer"); - condition_comm = (const struct lttng_condition_comm *) buffer->data; + condition_comm = (typeof(condition_comm)) view->buffer.data; condition_size += sizeof(*condition_comm); switch ((enum lttng_condition_type) condition_comm->condition_type) { case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW: - create_from_buffer = lttng_condition_buffer_usage_low_create_from_buffer; + create_from_payload = lttng_condition_buffer_usage_low_create_from_payload; break; case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH: - create_from_buffer = lttng_condition_buffer_usage_high_create_from_buffer; + create_from_payload = lttng_condition_buffer_usage_high_create_from_payload; break; case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE: - create_from_buffer = lttng_condition_session_consumed_size_create_from_buffer; + create_from_payload = lttng_condition_session_consumed_size_create_from_payload; break; case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: - create_from_buffer = lttng_condition_session_rotation_ongoing_create_from_buffer; + create_from_payload = lttng_condition_session_rotation_ongoing_create_from_payload; break; case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED: - create_from_buffer = lttng_condition_session_rotation_completed_create_from_buffer; + create_from_payload = lttng_condition_session_rotation_completed_create_from_payload; break; default: ERR("Attempted to create condition of unknown type (%i)", @@ -146,12 +146,12 @@ ssize_t lttng_condition_create_from_buffer( goto end; } - if (create_from_buffer) { - const struct lttng_buffer_view view = - lttng_buffer_view_from_view(buffer, + if (create_from_payload) { + struct lttng_payload_view condition_view = + lttng_payload_view_from_view(view, sizeof(*condition_comm), -1); - ret = create_from_buffer(&view, condition); + ret = create_from_payload(&condition_view, condition); if (ret < 0) { goto end; } diff --git a/src/common/evaluation.c b/src/common/evaluation.c index efd212921..cb379168e 100644 --- a/src/common/evaluation.c +++ b/src/common/evaluation.c @@ -23,21 +23,21 @@ void lttng_evaluation_init(struct lttng_evaluation *evaluation, LTTNG_HIDDEN int lttng_evaluation_serialize(const struct lttng_evaluation *evaluation, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { int ret; struct lttng_evaluation_comm evaluation_comm = { .type = (int8_t) evaluation->type }; - ret = lttng_dynamic_buffer_append(buf, &evaluation_comm, + ret = lttng_dynamic_buffer_append(&payload->buffer, &evaluation_comm, sizeof(evaluation_comm)); if (ret) { goto end; } if (evaluation->serialize) { - ret = evaluation->serialize(evaluation, buf); + ret = evaluation->serialize(evaluation, payload); if (ret) { goto end; } @@ -47,27 +47,27 @@ end: } LTTNG_HIDDEN -ssize_t lttng_evaluation_create_from_buffer( - const struct lttng_buffer_view *src_view, +ssize_t lttng_evaluation_create_from_payload( + struct lttng_payload_view *src_view, struct lttng_evaluation **evaluation) { ssize_t ret, evaluation_size = 0; const struct lttng_evaluation_comm *evaluation_comm; - const struct lttng_buffer_view evaluation_view = - lttng_buffer_view_from_view(src_view, - sizeof(*evaluation_comm), -1); + struct lttng_payload_view evaluation_view = + lttng_payload_view_from_view( + src_view, sizeof(*evaluation_comm), -1); if (!src_view || !evaluation) { ret = -1; goto end; } - evaluation_comm = (const struct lttng_evaluation_comm *) src_view->data; + evaluation_comm = (typeof(evaluation_comm)) src_view->buffer.data; evaluation_size += sizeof(*evaluation_comm); switch ((enum lttng_condition_type) evaluation_comm->type) { case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW: - ret = lttng_evaluation_buffer_usage_low_create_from_buffer( + ret = lttng_evaluation_buffer_usage_low_create_from_payload( &evaluation_view, evaluation); if (ret < 0) { goto end; @@ -75,7 +75,7 @@ ssize_t lttng_evaluation_create_from_buffer( evaluation_size += ret; break; case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH: - ret = lttng_evaluation_buffer_usage_high_create_from_buffer( + ret = lttng_evaluation_buffer_usage_high_create_from_payload( &evaluation_view, evaluation); if (ret < 0) { goto end; @@ -83,7 +83,7 @@ ssize_t lttng_evaluation_create_from_buffer( evaluation_size += ret; break; case LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE: - ret = lttng_evaluation_session_consumed_size_create_from_buffer( + ret = lttng_evaluation_session_consumed_size_create_from_payload( &evaluation_view, evaluation); if (ret < 0) { goto end; @@ -91,7 +91,7 @@ ssize_t lttng_evaluation_create_from_buffer( evaluation_size += ret; break; case LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING: - ret = lttng_evaluation_session_rotation_ongoing_create_from_buffer( + ret = lttng_evaluation_session_rotation_ongoing_create_from_payload( &evaluation_view, evaluation); if (ret < 0) { goto end; @@ -99,7 +99,7 @@ ssize_t lttng_evaluation_create_from_buffer( evaluation_size += ret; break; case LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED: - ret = lttng_evaluation_session_rotation_completed_create_from_buffer( + ret = lttng_evaluation_session_rotation_completed_create_from_payload( &evaluation_view, evaluation); if (ret < 0) { goto end; @@ -112,6 +112,7 @@ ssize_t lttng_evaluation_create_from_buffer( ret = -1; goto end; } + ret = evaluation_size; end: return ret; diff --git a/src/common/notification.c b/src/common/notification.c index 6b32bd9ac..806c55619 100644 --- a/src/common/notification.c +++ b/src/common/notification.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include LTTNG_HIDDEN @@ -36,81 +38,89 @@ end: LTTNG_HIDDEN int lttng_notification_serialize(const struct lttng_notification *notification, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { int ret; size_t header_offset, size_before_payload; struct lttng_notification_comm notification_comm = { 0 }; struct lttng_notification_comm *header; - header_offset = buf->size; - ret = lttng_dynamic_buffer_append(buf, ¬ification_comm, + header_offset = payload->buffer.size; + ret = lttng_dynamic_buffer_append(&payload->buffer, ¬ification_comm, sizeof(notification_comm)); if (ret) { goto end; } - size_before_payload = buf->size; + size_before_payload = payload->buffer.size; ret = lttng_condition_serialize(notification->condition, - buf); + payload); if (ret) { goto end; } - ret = lttng_evaluation_serialize(notification->evaluation, buf); + ret = lttng_evaluation_serialize(notification->evaluation, payload); if (ret) { goto end; } /* Update payload size. */ - header = (struct lttng_notification_comm *) ((char *) buf->data + header_offset); - header->length = (uint32_t) (buf->size - size_before_payload); + header = (typeof(header)) (payload->buffer.data + header_offset); + header->length = (uint32_t) (payload->buffer.size - size_before_payload); end: return ret; } LTTNG_HIDDEN -ssize_t lttng_notification_create_from_buffer( - const struct lttng_buffer_view *src_view, +ssize_t lttng_notification_create_from_payload( + struct lttng_payload_view *src_view, struct lttng_notification **notification) { ssize_t ret, notification_size = 0, condition_size, evaluation_size; const struct lttng_notification_comm *notification_comm; struct lttng_condition *condition; struct lttng_evaluation *evaluation; - struct lttng_buffer_view condition_view; - struct lttng_buffer_view evaluation_view; if (!src_view || !notification) { ret = -1; goto end; } - notification_comm = - (const struct lttng_notification_comm *) src_view->data; + notification_comm = (typeof(notification_comm)) src_view->buffer.data; notification_size += sizeof(*notification_comm); + { + /* struct lttng_condition */ + struct lttng_payload_view condition_view = + lttng_payload_view_from_view(src_view, + notification_size, -1); + + condition_size = lttng_condition_create_from_payload( + &condition_view, &condition); + } - /* struct lttng_condition */ - condition_view = lttng_buffer_view_from_view(src_view, - sizeof(*notification_comm), -1); - condition_size = lttng_condition_create_from_buffer(&condition_view, - &condition); if (condition_size < 0) { ret = condition_size; goto end; } + notification_size += condition_size; - /* struct lttng_evaluation */ - evaluation_view = lttng_buffer_view_from_view(&condition_view, - condition_size, -1); - evaluation_size = lttng_evaluation_create_from_buffer(&evaluation_view, - &evaluation); + { + /* struct lttng_evaluation */ + struct lttng_payload_view evaluation_view = + lttng_payload_view_from_view(src_view, + notification_size, -1); + + evaluation_size = lttng_evaluation_create_from_payload( + &evaluation_view, &evaluation); + } + if (evaluation_size < 0) { ret = evaluation_size; goto end; } + notification_size += evaluation_size; /* Unexpected size of inner-elements; the buffer is corrupted. */ diff --git a/src/common/session-consumed-size.c b/src/common/session-consumed-size.c index dfb72632e..046107343 100644 --- a/src/common/session-consumed-size.c +++ b/src/common/session-consumed-size.c @@ -65,7 +65,7 @@ end: static int lttng_condition_session_consumed_size_serialize( const struct lttng_condition *condition, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { int ret; size_t session_name_len; @@ -92,12 +92,13 @@ int lttng_condition_session_consumed_size_serialize( consumed->consumed_threshold_bytes.value; consumed_comm.session_name_len = (uint32_t) session_name_len; - ret = lttng_dynamic_buffer_append(buf, &consumed_comm, + ret = lttng_dynamic_buffer_append(&payload->buffer, &consumed_comm, sizeof(consumed_comm)); if (ret) { goto end; } - ret = lttng_dynamic_buffer_append(buf, consumed->session_name, + + ret = lttng_dynamic_buffer_append(&payload->buffer, consumed->session_name, session_name_len); if (ret) { goto end; @@ -155,8 +156,8 @@ struct lttng_condition *lttng_condition_session_consumed_size_create(void) } static -ssize_t init_condition_from_buffer(struct lttng_condition *condition, - const struct lttng_buffer_view *src_view) +ssize_t init_condition_from_payload(struct lttng_condition *condition, + struct lttng_payload_view *src_view) { ssize_t ret, condition_size; enum lttng_condition_status status; @@ -164,14 +165,14 @@ ssize_t init_condition_from_buffer(struct lttng_condition *condition, const char *session_name; struct lttng_buffer_view names_view; - if (src_view->size < sizeof(*condition_comm)) { + if (src_view->buffer.size < sizeof(*condition_comm)) { ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header"); ret = -1; goto end; } - condition_comm = (const struct lttng_condition_session_consumed_size_comm *) src_view->data; - names_view = lttng_buffer_view_from_view(src_view, + condition_comm = (typeof(condition_comm)) src_view->buffer.data; + names_view = lttng_buffer_view_from_view(&src_view->buffer, sizeof(*condition_comm), -1); if (condition_comm->session_name_len > LTTNG_NAME_MAX) { @@ -222,8 +223,8 @@ end: } LTTNG_HIDDEN -ssize_t lttng_condition_session_consumed_size_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_session_consumed_size_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **_condition) { ssize_t ret; @@ -235,7 +236,7 @@ ssize_t lttng_condition_session_consumed_size_create_from_buffer( goto error; } - ret = init_condition_from_buffer(condition, view); + ret = init_condition_from_payload(condition, view); if (ret < 0) { goto error; } @@ -248,14 +249,14 @@ error: } static -struct lttng_evaluation *create_evaluation_from_buffer( - const struct lttng_buffer_view *view) +struct lttng_evaluation *create_evaluation_from_payload( + const struct lttng_payload_view *view) { const struct lttng_evaluation_session_consumed_size_comm *comm = - (const struct lttng_evaluation_session_consumed_size_comm *) view->data; + (typeof(comm)) view->buffer.data; struct lttng_evaluation *evaluation = NULL; - if (view->size < sizeof(*comm)) { + if (view->buffer.size < sizeof(*comm)) { goto end; } @@ -266,8 +267,8 @@ end: } LTTNG_HIDDEN -ssize_t lttng_evaluation_session_consumed_size_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_session_consumed_size_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **_evaluation) { ssize_t ret; @@ -278,7 +279,7 @@ ssize_t lttng_evaluation_session_consumed_size_create_from_buffer( goto error; } - evaluation = create_evaluation_from_buffer(view); + evaluation = create_evaluation_from_payload(view); if (!evaluation) { ret = -1; goto error; @@ -393,15 +394,16 @@ end: static int lttng_evaluation_session_consumed_size_serialize( const struct lttng_evaluation *evaluation, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { 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); + consumed = container_of(evaluation, + struct lttng_evaluation_session_consumed_size, parent); comm.session_consumed = consumed->session_consumed; - return lttng_dynamic_buffer_append(buf, &comm, sizeof(comm)); + return lttng_dynamic_buffer_append( + &payload->buffer, &comm, sizeof(comm)); } static diff --git a/src/common/session-rotation.c b/src/common/session-rotation.c index f8d4439de..f6849d28a 100644 --- a/src/common/session-rotation.c +++ b/src/common/session-rotation.c @@ -19,7 +19,7 @@ bool lttng_condition_session_rotation_validate( static int lttng_condition_session_rotation_serialize( const struct lttng_condition *condition, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *payload); static bool lttng_condition_session_rotation_is_equal(const struct lttng_condition *_a, const struct lttng_condition *_b); @@ -39,7 +39,7 @@ struct lttng_condition rotation_condition_template = { static int lttng_evaluation_session_rotation_serialize( const struct lttng_evaluation *evaluation, - struct lttng_dynamic_buffer *buf); + struct lttng_payload *payload); static void lttng_evaluation_session_rotation_destroy( struct lttng_evaluation *evaluation); @@ -95,7 +95,7 @@ end: static int lttng_condition_session_rotation_serialize( const struct lttng_condition *condition, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { int ret; size_t session_name_len; @@ -118,13 +118,13 @@ int lttng_condition_session_rotation_serialize( } rotation_comm.session_name_len = session_name_len; - ret = lttng_dynamic_buffer_append(buf, &rotation_comm, + ret = lttng_dynamic_buffer_append(&payload->buffer, &rotation_comm, sizeof(rotation_comm)); if (ret) { goto end; } - ret = lttng_dynamic_buffer_append(buf, rotation->session_name, - session_name_len); + ret = lttng_dynamic_buffer_append(&payload->buffer, + rotation->session_name, session_name_len); if (ret) { goto end; } @@ -202,8 +202,8 @@ struct lttng_condition *lttng_condition_session_rotation_completed_create(void) } static -ssize_t init_condition_from_buffer(struct lttng_condition *condition, - const struct lttng_buffer_view *src_view) +ssize_t init_condition_from_payload(struct lttng_condition *condition, + struct lttng_payload_view *src_view) { ssize_t ret, condition_size; enum lttng_condition_status status; @@ -211,14 +211,14 @@ ssize_t init_condition_from_buffer(struct lttng_condition *condition, const char *session_name; struct lttng_buffer_view name_view; - if (src_view->size < sizeof(*condition_comm)) { + if (src_view->buffer.size < sizeof(*condition_comm)) { ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header"); ret = -1; goto end; } - condition_comm = (const struct lttng_condition_session_rotation_comm *) src_view->data; - name_view = lttng_buffer_view_from_view(src_view, + condition_comm = (typeof(condition_comm)) src_view->buffer.data; + name_view = lttng_buffer_view_from_view(&src_view->buffer, sizeof(*condition_comm), -1); if (condition_comm->session_name_len > LTTNG_NAME_MAX) { @@ -261,8 +261,8 @@ end: } static -ssize_t lttng_condition_session_rotation_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_session_rotation_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **_condition, enum lttng_condition_type type) { @@ -286,7 +286,7 @@ ssize_t lttng_condition_session_rotation_create_from_buffer( goto error; } - ret = init_condition_from_buffer(condition, view); + ret = init_condition_from_payload(condition, view); if (ret < 0) { goto error; } @@ -299,21 +299,21 @@ error: } LTTNG_HIDDEN -ssize_t lttng_condition_session_rotation_ongoing_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_session_rotation_ongoing_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **condition) { - return lttng_condition_session_rotation_create_from_buffer(view, + return lttng_condition_session_rotation_create_from_payload(view, condition, LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING); } LTTNG_HIDDEN -ssize_t lttng_condition_session_rotation_completed_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_condition_session_rotation_completed_create_from_payload( + struct lttng_payload_view *view, struct lttng_condition **condition) { - return lttng_condition_session_rotation_create_from_buffer(view, + return lttng_condition_session_rotation_create_from_payload(view, condition, LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED); } @@ -339,26 +339,26 @@ struct lttng_evaluation *lttng_evaluation_session_rotation_create( } static -ssize_t create_evaluation_from_buffer( +ssize_t create_evaluation_from_payload( enum lttng_condition_type type, - const struct lttng_buffer_view *view, + struct lttng_payload_view *view, struct lttng_evaluation **_evaluation) { ssize_t ret, size; struct lttng_evaluation *evaluation = NULL; struct lttng_trace_archive_location *location = NULL; const struct lttng_evaluation_session_rotation_comm *comm = - (const struct lttng_evaluation_session_rotation_comm *) view->data; - struct lttng_buffer_view location_view; + (typeof(comm)) view->buffer.data; + struct lttng_buffer_view location_view; - if (view->size < sizeof(*comm)) { + if (view->buffer.size < sizeof(*comm)) { goto error; } size = sizeof(*comm); if (comm->has_location) { - location_view = lttng_buffer_view_from_view(view, sizeof(*comm), - -1); + location_view = lttng_buffer_view_from_view( + &view->buffer, sizeof(*comm), -1); if (!location_view.data) { goto error; } @@ -387,9 +387,9 @@ error: } static -ssize_t lttng_evaluation_session_rotation_create_from_buffer( +ssize_t lttng_evaluation_session_rotation_create_from_payload( enum lttng_condition_type type, - const struct lttng_buffer_view *view, + struct lttng_payload_view *view, struct lttng_evaluation **_evaluation) { ssize_t ret; @@ -400,7 +400,7 @@ ssize_t lttng_evaluation_session_rotation_create_from_buffer( goto error; } - ret = create_evaluation_from_buffer(type, view, &evaluation); + ret = create_evaluation_from_payload(type, view, &evaluation); if (ret < 0) { goto error; } @@ -413,21 +413,21 @@ error: } LTTNG_HIDDEN -ssize_t lttng_evaluation_session_rotation_ongoing_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_session_rotation_ongoing_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **evaluation) { - return lttng_evaluation_session_rotation_create_from_buffer( + return lttng_evaluation_session_rotation_create_from_payload( LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING, view, evaluation); } LTTNG_HIDDEN -ssize_t lttng_evaluation_session_rotation_completed_create_from_buffer( - const struct lttng_buffer_view *view, +ssize_t lttng_evaluation_session_rotation_completed_create_from_payload( + struct lttng_payload_view *view, struct lttng_evaluation **evaluation) { - return lttng_evaluation_session_rotation_create_from_buffer( + return lttng_evaluation_session_rotation_create_from_payload( LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED, view, evaluation); } @@ -505,7 +505,7 @@ end: static int lttng_evaluation_session_rotation_serialize( const struct lttng_evaluation *evaluation, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { int ret; struct lttng_evaluation_session_rotation *rotation; @@ -515,7 +515,8 @@ int lttng_evaluation_session_rotation_serialize( struct lttng_evaluation_session_rotation, parent); comm.id = rotation->id; comm.has_location = !!rotation->location; - ret = lttng_dynamic_buffer_append(buf, &comm, sizeof(comm)); + ret = lttng_dynamic_buffer_append( + &payload->buffer, &comm, sizeof(comm)); if (ret) { goto end; } @@ -523,7 +524,7 @@ int lttng_evaluation_session_rotation_serialize( goto end; } ret = lttng_trace_archive_location_serialize(rotation->location, - buf); + &payload->buffer); end: return ret; } diff --git a/src/common/sessiond-comm/Makefile.am b/src/common/sessiond-comm/Makefile.am index d026651a6..0e7eb4922 100644 --- a/src/common/sessiond-comm/Makefile.am +++ b/src/common/sessiond-comm/Makefile.am @@ -4,4 +4,5 @@ noinst_LTLIBRARIES = libsessiond-comm.la libsessiond_comm_la_SOURCES = sessiond-comm.c sessiond-comm.h \ inet.c inet.h inet6.c inet6.h \ - relayd.h agent.h + relayd.h agent.h payload.h \ + payload.c payload-view.h payload-view.c diff --git a/src/common/sessiond-comm/payload-view.c b/src/common/sessiond-comm/payload-view.c new file mode 100644 index 000000000..fdfef6150 --- /dev/null +++ b/src/common/sessiond-comm/payload-view.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2020 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#include +#include "payload-view.h" +#include "payload.h" +#include + +LTTNG_HIDDEN +struct lttng_payload_view lttng_payload_view_from_payload( + const struct lttng_payload *payload, size_t offset, + ptrdiff_t len) +{ + return (struct lttng_payload_view) { + .buffer = lttng_buffer_view_from_dynamic_buffer( + &payload->buffer, offset, len), + ._fds = payload->_fds, + }; +} + +LTTNG_HIDDEN +struct lttng_payload_view lttng_payload_view_from_view( + struct lttng_payload_view *view, size_t offset, + ptrdiff_t len) +{ + return (struct lttng_payload_view) { + .buffer = lttng_buffer_view_from_view( + &view->buffer, offset, len), + ._fds = view->_fds, + ._iterator.p_fds_position = &view->_iterator.fds_position, + }; +} + +LTTNG_HIDDEN +struct lttng_payload_view lttng_payload_view_from_dynamic_buffer( + const struct lttng_dynamic_buffer *buffer, size_t offset, + ptrdiff_t len) +{ + return (struct lttng_payload_view) { + .buffer = lttng_buffer_view_from_dynamic_buffer( + buffer, offset, len) + }; +} + +LTTNG_HIDDEN +int lttng_payload_view_pop_fd(struct lttng_payload_view *view) +{ + int ret = 0; + size_t fd_count; + size_t *pos; + + if (!view) { + ret = -1; + goto end; + } + + fd_count = lttng_dynamic_array_get_count(&view->_fds); + pos = view->_iterator.p_fds_position ? view->_iterator.p_fds_position : + &view->_iterator.fds_position; + + if (*pos >= fd_count) { + ret = -1; + goto end; + } + + ret = *((int *) lttng_dynamic_array_get_element( + &view->_fds, *pos)); + (*pos)++; +end: + return ret; +} diff --git a/src/common/sessiond-comm/payload-view.h b/src/common/sessiond-comm/payload-view.h new file mode 100644 index 000000000..f125e8890 --- /dev/null +++ b/src/common/sessiond-comm/payload-view.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2020 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#ifndef LTTNG_PAYLOAD_VIEW_H +#define LTTNG_PAYLOAD_VIEW_H + +#include +#include + +struct lttng_payload; + +/* + * An lttng_payload_view references a payload and allows code to share + * a `const` version of a subset of a payload. + * + * A payload view is invalidated whenever its source (a payload, or another + * payload view) is modified. + * + * While a payload view does not allow users to modify the underlying bytes + * of the payload, it can be used to 'pop' file descriptors using an iterator + * belonging to the top-level payload view. + * + * Hence, a payload view created from a payload or a dynamic buffer contains + * an implicit file descriptor iterator. Any payload view created from another + * payload view will share the same underlying file descriptor iterator. + * + * The rationale for this is that a payload is never consumed directly, it + * must be consumed through a payload view. + * + * Typically, a payload view will be used to rebuild a previously serialized + * object hierarchy. Sharing an underlying iterator allows aggregate objects + * to provide a restricted view of the payload to their members, which will + * report the number of bytes consumed and `pop` the file descriptors they + * should own. In return, those objects can create an even narrower view for + * their children, allowing them to also consume file descriptors. + * + * Note that a payload view never assumes any ownership of the underlying + * payload. + */ +struct lttng_payload_view { + struct lttng_buffer_view buffer; + /* private */ + const struct lttng_dynamic_array _fds; + struct { + size_t *p_fds_position; + size_t fds_position; + } _iterator; +}; + +/** + * Return a payload view referencing a subset of a payload. + * + * @payload Source payload to reference + * @offset Offset to apply to the payload's buffer + * @len Length of the contents to reference. Passing -1 will + * cause the view to reference the whole payload from the + * offset provided. + */ +LTTNG_HIDDEN +struct lttng_payload_view lttng_payload_view_from_payload( + const struct lttng_payload *payload, size_t offset, + ptrdiff_t len); + +/** + * Return a payload view referencing a subset of a payload referenced by + * another payload view. + * + * @view Source payload view to reference + * @offset Offset to apply to the payload view's buffer view + * @len Length of the contents to reference. Passing -1 will + * cause the payload view to reference the whole payload view's + * buffer view from the offset provided. + */ +LTTNG_HIDDEN +struct lttng_payload_view lttng_payload_view_from_view( + struct lttng_payload_view *view, size_t offset, + ptrdiff_t len); + +/** + * Return a payload view referencing a subset of a dynamic buffer. + * + * Meant as an adapter for code paths that need to create a payload view + * from an existing dynamic buffer. + * + * @src Source dynamic buffer to reference + * @offset Offset to apply to the payload's buffer + * @len Length of the buffer contents to reference. Passing -1 will + * cause the payload view to reference the whole payload from the + * offset provided. + */ +LTTNG_HIDDEN +struct lttng_payload_view lttng_payload_view_from_dynamic_buffer( + const struct lttng_dynamic_buffer *buffer, size_t offset, + ptrdiff_t len); + +/** + * Pop an fd from a payload view. + * No ownership of the file descriptor is assumed by the payload. + * + * @payload Payload instance + * + * Returns a file descriptor on success, -1 on error. + */ +LTTNG_HIDDEN +int lttng_payload_view_pop_fd(struct lttng_payload_view *payload_view); + +#endif /* LTTNG_PAYLOAD_VIEW_H */ diff --git a/src/common/sessiond-comm/payload.c b/src/common/sessiond-comm/payload.c new file mode 100644 index 000000000..592964a51 --- /dev/null +++ b/src/common/sessiond-comm/payload.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2020 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#include "payload.h" + +LTTNG_HIDDEN +void lttng_payload_init(struct lttng_payload *payload) +{ + assert(payload); + lttng_dynamic_buffer_init(&payload->buffer); + lttng_dynamic_array_init(&payload->_fds, sizeof(int), NULL); +} + +LTTNG_HIDDEN +void lttng_payload_reset(struct lttng_payload *payload) +{ + if (!payload) { + return; + } + + lttng_dynamic_buffer_reset(&payload->buffer); + lttng_dynamic_array_reset(&payload->_fds); +} + +LTTNG_HIDDEN +int lttng_payload_push_fd(struct lttng_payload *payload, int fd) +{ + int ret; + + if (!payload) { + ret = -1; + goto end; + } + + ret = lttng_dynamic_array_add_element(&payload->_fds, &fd); +end: + return ret; +} diff --git a/src/common/sessiond-comm/payload.h b/src/common/sessiond-comm/payload.h new file mode 100644 index 000000000..3f1aa8cfd --- /dev/null +++ b/src/common/sessiond-comm/payload.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#ifndef LTTNG_PAYLOAD_H +#define LTTNG_PAYLOAD_H + +#include +#include + +/* + * An lttng_payload encompasses the 'data' (bytes) and any passed file + * descriptors as part of a message between liblttng-ctl and the session + * daemon. + */ +struct lttng_payload { + struct lttng_dynamic_buffer buffer; + /* private */ + struct lttng_dynamic_array _fds; +}; + +/* + * Initialize a payload. This performs no allocation and is meant + * to be used instead. + */ +LTTNG_HIDDEN +void lttng_payload_init(struct lttng_payload *payload); + +/* Release any memory used by the payload. */ +LTTNG_HIDDEN +void lttng_payload_reset(struct lttng_payload *payload); + +/** + * Add an fd to the payload. + * No ownership of the file descriptor is assumed by the payload. + * + * @payload Payload instance + * @fd File descriptor to add to the payload + * + * Returns 0 on success, -1 on allocation error. + */ +LTTNG_HIDDEN +int lttng_payload_push_fd(struct lttng_payload *payload, int fd); + +#endif /* LTTNG_PAYLOAD_H */ diff --git a/src/common/trigger.c b/src/common/trigger.c index dd161eb38..57f84d6a6 100644 --- a/src/common/trigger.c +++ b/src/common/trigger.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -84,16 +86,14 @@ void lttng_trigger_destroy(struct lttng_trigger *trigger) } LTTNG_HIDDEN -ssize_t lttng_trigger_create_from_buffer( - const struct lttng_buffer_view *src_view, +ssize_t lttng_trigger_create_from_payload( + struct lttng_payload_view *src_view, struct lttng_trigger **trigger) { ssize_t ret, offset = 0, condition_size, action_size; struct lttng_condition *condition = NULL; struct lttng_action *action = NULL; const struct lttng_trigger_comm *trigger_comm; - struct lttng_buffer_view condition_view; - struct lttng_buffer_view action_view; if (!src_view || !trigger) { ret = -1; @@ -101,23 +101,33 @@ ssize_t lttng_trigger_create_from_buffer( } /* lttng_trigger_comm header */ - trigger_comm = (const struct lttng_trigger_comm *) src_view->data; + trigger_comm = (typeof(trigger_comm)) src_view->buffer.data; offset += sizeof(*trigger_comm); + { + /* struct lttng_condition */ + struct lttng_payload_view condition_view = + lttng_payload_view_from_view( + src_view, offset, -1); + + condition_size = lttng_condition_create_from_payload(&condition_view, + &condition); + } - condition_view = lttng_buffer_view_from_view(src_view, offset, -1); - - /* struct lttng_condition */ - condition_size = lttng_condition_create_from_buffer(&condition_view, - &condition); if (condition_size < 0) { ret = condition_size; goto end; } + offset += condition_size; + { + /* struct lttng_action */ + struct lttng_payload_view action_view = + lttng_payload_view_from_view( + src_view, offset, -1); + + action_size = lttng_action_create_from_payload(&action_view, &action); + } - /* struct lttng_action */ - action_view = lttng_buffer_view_from_view(src_view, offset, -1); - action_size = lttng_action_create_from_buffer(&action_view, &action); if (action_size < 0) { ret = action_size; goto end; @@ -135,6 +145,7 @@ ssize_t lttng_trigger_create_from_buffer( ret = -1; goto error; } + ret = offset; end: return ret; @@ -150,34 +161,34 @@ error: */ LTTNG_HIDDEN int lttng_trigger_serialize(struct lttng_trigger *trigger, - struct lttng_dynamic_buffer *buf) + struct lttng_payload *payload) { int ret; size_t header_offset, size_before_payload; - struct lttng_trigger_comm trigger_comm = { 0 }; + struct lttng_trigger_comm trigger_comm = {}; struct lttng_trigger_comm *header; - header_offset = buf->size; - ret = lttng_dynamic_buffer_append(buf, &trigger_comm, + header_offset = payload->buffer.size; + ret = lttng_dynamic_buffer_append(&payload->buffer, &trigger_comm, sizeof(trigger_comm)); if (ret) { goto end; } - size_before_payload = buf->size; - ret = lttng_condition_serialize(trigger->condition, buf); + size_before_payload = payload->buffer.size; + ret = lttng_condition_serialize(trigger->condition, payload); if (ret) { goto end; } - ret = lttng_action_serialize(trigger->action, buf); + ret = lttng_action_serialize(trigger->action, payload); if (ret) { goto end; } /* Update payload size. */ - header = (struct lttng_trigger_comm *) ((char *) buf->data + header_offset); - header->length = buf->size - size_before_payload; + header = (typeof(header)) (payload->buffer.data + header_offset); + header->length = payload->buffer.size - size_before_payload; end: return ret; } diff --git a/src/lib/lttng-ctl/channel.c b/src/lib/lttng-ctl/channel.c index f2a65885d..16bd298be 100644 --- a/src/lib/lttng-ctl/channel.c +++ b/src/lib/lttng-ctl/channel.c @@ -97,17 +97,22 @@ struct lttng_notification *create_notification_from_current_message( { ssize_t ret; struct lttng_notification *notification = NULL; - struct lttng_buffer_view view; if (channel->reception_buffer.size <= sizeof(struct lttng_notification_channel_message)) { goto end; } - view = lttng_buffer_view_from_dynamic_buffer(&channel->reception_buffer, - sizeof(struct lttng_notification_channel_message), -1); + { + struct lttng_payload_view view = lttng_payload_view_from_dynamic_buffer( + &channel->reception_buffer, + sizeof(struct lttng_notification_channel_message), + -1); + + ret = lttng_notification_create_from_payload( + &view, ¬ification); + } - ret = lttng_notification_create_from_buffer(&view, ¬ification); if (ret != channel->reception_buffer.size - sizeof(struct lttng_notification_channel_message)) { lttng_notification_destroy(notification); @@ -603,12 +608,12 @@ enum lttng_notification_channel_status send_condition_command( ssize_t ret; enum lttng_notification_channel_status status = LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; - struct lttng_dynamic_buffer buffer; + struct lttng_payload payload; struct lttng_notification_channel_message cmd_header = { .type = (int8_t) type, }; - lttng_dynamic_buffer_init(&buffer); + lttng_payload_init(&payload); if (!channel) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID; @@ -625,24 +630,25 @@ enum lttng_notification_channel_status send_condition_command( goto end_unlock; } - ret = lttng_dynamic_buffer_append(&buffer, &cmd_header, + ret = lttng_dynamic_buffer_append(&payload.buffer, &cmd_header, sizeof(cmd_header)); if (ret) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_unlock; } - ret = lttng_condition_serialize(condition, &buffer); + ret = lttng_condition_serialize(condition, &payload); if (ret) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID; goto end_unlock; } /* Update payload length. */ - ((struct lttng_notification_channel_message *) buffer.data)->size = - (uint32_t) (buffer.size - sizeof(cmd_header)); + ((struct lttng_notification_channel_message *) payload.buffer.data)->size = + (uint32_t) (payload.buffer.size - sizeof(cmd_header)); - ret = lttcomm_send_unix_sock(socket, buffer.data, buffer.size); + ret = lttcomm_send_unix_sock( + socket, payload.buffer.data, payload.buffer.size); if (ret < 0) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_unlock; @@ -656,7 +662,7 @@ enum lttng_notification_channel_status send_condition_command( end_unlock: pthread_mutex_unlock(&channel->lock); end: - lttng_dynamic_buffer_reset(&buffer); + lttng_payload_reset(&payload); return status; } diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c index 7622a5137..b74c78749 100644 --- a/src/lib/lttng-ctl/lttng-ctl.c +++ b/src/lib/lttng-ctl/lttng-ctl.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -2889,9 +2891,9 @@ int lttng_register_trigger(struct lttng_trigger *trigger) { int ret; struct lttcomm_session_msg lsm; - struct lttng_dynamic_buffer buffer; + struct lttng_payload payload; - lttng_dynamic_buffer_init(&buffer); + lttng_payload_init(&payload); if (!trigger) { ret = -LTTNG_ERR_INVALID; goto end; @@ -2902,7 +2904,7 @@ int lttng_register_trigger(struct lttng_trigger *trigger) goto end; } - ret = lttng_trigger_serialize(trigger, &buffer); + ret = lttng_trigger_serialize(trigger, &payload); if (ret < 0) { ret = -LTTNG_ERR_UNK; goto end; @@ -2910,11 +2912,11 @@ int lttng_register_trigger(struct lttng_trigger *trigger) memset(&lsm, 0, sizeof(lsm)); lsm.cmd_type = LTTNG_REGISTER_TRIGGER; - lsm.u.trigger.length = (uint32_t) buffer.size; - ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, buffer.data, - buffer.size, NULL); + lsm.u.trigger.length = (uint32_t) payload.buffer.size; + ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header( + &lsm, payload.buffer.data, payload.buffer.size, NULL); end: - lttng_dynamic_buffer_reset(&buffer); + lttng_payload_reset(&payload); return ret; } @@ -2922,9 +2924,9 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) { int ret; struct lttcomm_session_msg lsm; - struct lttng_dynamic_buffer buffer; + struct lttng_payload payload; - lttng_dynamic_buffer_init(&buffer); + lttng_payload_init(&payload); if (!trigger) { ret = -LTTNG_ERR_INVALID; goto end; @@ -2935,7 +2937,7 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) goto end; } - ret = lttng_trigger_serialize(trigger, &buffer); + ret = lttng_trigger_serialize(trigger, &payload); if (ret < 0) { ret = -LTTNG_ERR_UNK; goto end; @@ -2943,11 +2945,11 @@ int lttng_unregister_trigger(struct lttng_trigger *trigger) memset(&lsm, 0, sizeof(lsm)); lsm.cmd_type = LTTNG_UNREGISTER_TRIGGER; - lsm.u.trigger.length = (uint32_t) buffer.size; - ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, buffer.data, - buffer.size, NULL); + lsm.u.trigger.length = (uint32_t) payload.buffer.size; + ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header( + &lsm, payload.buffer.data, payload.buffer.size, NULL); end: - lttng_dynamic_buffer_reset(&buffer); + lttng_payload_reset(&payload); return ret; } diff --git a/tests/regression/tools/notification/Makefile.am b/tests/regression/tools/notification/Makefile.am index bc2c9123c..f1f2a1667 100644 --- a/tests/regression/tools/notification/Makefile.am +++ b/tests/regression/tools/notification/Makefile.am @@ -21,6 +21,7 @@ FORCE_SHARED_LIB_OPTIONS = -module -shared -avoid-version \ libpause_consumer_la_SOURCES = consumer_testpoints.c libpause_consumer_la_LIBADD = \ + $(top_builddir)/src/common/sessiond-comm/libsessiond-comm.la \ $(top_builddir)/src/common/libcommon.la \ $(top_builddir)/src/lib/lttng-ctl/liblttng-ctl.la \ $(DL_LIBS) diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index e2c57bc8e..74027aba3 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -22,7 +22,8 @@ TESTS = test_kernel_data \ ini_config/test_ini_config \ test_fd_tracker \ test_uuid \ - test_buffer_view + test_buffer_view \ + test_payload LIBTAP=$(top_builddir)/tests/utils/tap/libtap.la @@ -41,7 +42,8 @@ noinst_PROGRAMS = test_uri test_session test_kernel_data \ test_string_utils test_notification test_directory_handle \ test_relayd_backward_compat_group_by_session \ test_fd_tracker test_uuid \ - test_buffer_view + test_buffer_view \ + test_payload if HAVE_LIBLTTNG_UST_CTL noinst_PROGRAMS += test_ust_data @@ -201,3 +203,7 @@ test_uuid_LDADD = $(LIBTAP) $(LIBCOMMON) # buffer view unit test test_buffer_view_SOURCES = test_buffer_view.c test_buffer_view_LDADD = $(LIBTAP) $(LIBCOMMON) + +# payload unit test +test_payload_SOURCES = test_payload.c +test_payload_LDADD = $(LIBTAP) $(LIBSESSIOND_COMM) $(LIBCOMMON) diff --git a/tests/unit/test_payload.c b/tests/unit/test_payload.c new file mode 100644 index 000000000..50f08cd75 --- /dev/null +++ b/tests/unit/test_payload.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2020 Jérémie Galarneau + * + * SPDX-License-Identifier: LGPL-2.1-only + * + */ + +#include +#include +#include + +static const int TEST_COUNT = 5; + +/* For error.h */ +int lttng_opt_quiet = 1; +int lttng_opt_verbose; +int lttng_opt_mi; + +static void test_fd_push_pop_order(void) +{ + int ret, i; + struct lttng_payload payload; + + lttng_payload_init(&payload); + + diag("Validating fd push/pop order"); + for (i = 0; i < 3; i++) { + ret = lttng_payload_push_fd(&payload, i); + if (ret) { + break; + } + } + ok(ret == 0, "Added three file descriptors to an lttng_payload"); + + { + bool fail_pop = false; + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + for (i = 0; i < 3; i++) { + ret = lttng_payload_view_pop_fd(&view); + fail_pop |= ret != i; + } + + ok(!fail_pop, "File descriptors are popped from a payload view in the order of insertion"); + } + + lttng_payload_reset(&payload); +} + +static void test_fd_push_pop_imbalance(void) +{ + int ret, i; + struct lttng_payload payload; + const char * const test_description = "Error reported when popping more file descriptors than were pushed"; + + lttng_payload_init(&payload); + + diag("Validating fd pop imbalance"); + for (i = 0; i < 10; i++) { + ret = lttng_payload_push_fd(&payload, i); + if (ret) { + break; + } + } + + { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + for (i = 0; i < 10; i++) { + ret = lttng_payload_view_pop_fd(&view); + if (ret == -1) { + goto fail; + } + } + + ret = lttng_payload_view_pop_fd(&view); + ok(ret == -1, test_description); + } + + lttng_payload_reset(&payload); + return; +fail: + fail(test_description); + lttng_payload_reset(&payload); +} + +static void test_fd_pop_fd_root_views(void) +{ + int ret, i; + const int fd = 42; + struct lttng_payload payload; + const char * const test_description = "Same file descriptor returned when popping from different top-level views"; + + lttng_payload_init(&payload); + + diag("Validating root view fd pop behaviour"); + ret = lttng_payload_push_fd(&payload, fd); + if (ret) { + goto fail; + } + + for (i = 0; i < 5; i++) { + struct lttng_payload_view view = + lttng_payload_view_from_payload( + &payload, 0, -1); + + ret = lttng_payload_view_pop_fd(&view); + if (ret != fd) { + goto fail; + } + } + + lttng_payload_reset(&payload); + pass(test_description); + return; +fail: + lttng_payload_reset(&payload); + fail(test_description); +} + +static void test_fd_pop_fd_descendant_views(void) +{ + int ret; + const int fd1 = 42, fd2 = 1837; + struct lttng_payload payload; + const char * const test_description = "Different file descriptors returned when popping from descendant views"; + + lttng_payload_init(&payload); + + diag("Validating descendant view fd pop behaviour"); + ret = lttng_payload_push_fd(&payload, fd1); + if (ret) { + goto fail; + } + + ret = lttng_payload_push_fd(&payload, fd2); + if (ret) { + goto fail; + } + + { + struct lttng_payload_view view1 = + lttng_payload_view_from_payload( + &payload, 0, -1); + struct lttng_payload_view view2 = + lttng_payload_view_from_view( + &view1, 0, -1); + + ret = lttng_payload_view_pop_fd(&view1); + if (ret != fd1) { + goto fail; + } + + ret = lttng_payload_view_pop_fd(&view2); + if (ret != fd2) { + goto fail; + } + } + + lttng_payload_reset(&payload); + pass(test_description); + return; +fail: + lttng_payload_reset(&payload); + fail(test_description); +} + +int main(void) +{ + plan_tests(TEST_COUNT); + + test_fd_push_pop_order(); + test_fd_push_pop_imbalance(); + test_fd_pop_fd_root_views(); + test_fd_pop_fd_descendant_views(); + + return exit_status(); +}