X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Flib%2Flttng-ctl%2Fchannel.cpp;h=d8827c67046d88feca8b0eb933871e504f9c955e;hb=28ab034a2c3582d07d3423d2d746731f87d3969f;hp=080dbb4439659a33c10dc052e81f21b56251b4c9;hpb=c9e313bc594f40a86eed237dce222c0fc99c957f;p=lttng-tools.git diff --git a/src/lib/lttng-ctl/channel.cpp b/src/lib/lttng-ctl/channel.cpp index 080dbb443..d8827c670 100644 --- a/src/lib/lttng-ctl/channel.cpp +++ b/src/lib/lttng-ctl/channel.cpp @@ -5,30 +5,29 @@ * */ -#include -#include -#include -#include +#include "lttng-ctl-helper.hpp" + +#include #include -#include #include -#include -#include -#include +#include #include +#include #include -#include "lttng-ctl-helper.hpp" -#include +#include -static -int handshake(struct lttng_notification_channel *channel); +#include +#include +#include +#include + +static int handshake(struct lttng_notification_channel *channel); /* * Populates the reception buffer with the next complete message. * The caller must acquire the channel's lock. */ -static -int receive_message(struct lttng_notification_channel *channel) +static int receive_message(struct lttng_notification_channel *channel) { ssize_t ret; struct lttng_notification_channel_message msg; @@ -47,31 +46,35 @@ int receive_message(struct lttng_notification_channel *channel) } /* Add message header at buffer's start. */ - ret = lttng_dynamic_buffer_append(&channel->reception_payload.buffer, &msg, - sizeof(msg)); + ret = lttng_dynamic_buffer_append(&channel->reception_payload.buffer, &msg, sizeof(msg)); if (ret) { goto error; } + if (msg.size == 0) { + goto skip_payload; + } + /* Reserve space for the payload. */ ret = lttng_dynamic_buffer_set_size(&channel->reception_payload.buffer, - channel->reception_payload.buffer.size + msg.size); + channel->reception_payload.buffer.size + msg.size); if (ret) { goto error; } /* Receive message payload. */ - ret = lttcomm_recv_unix_sock(channel->socket, - channel->reception_payload.buffer.data + sizeof(msg), msg.size); + ret = lttcomm_recv_unix_sock( + channel->socket, channel->reception_payload.buffer.data + sizeof(msg), msg.size); if (ret < (ssize_t) msg.size) { ret = -1; goto error; } +skip_payload: /* Receive message fds. */ if (msg.fds != 0) { - ret = lttcomm_recv_payload_fds_unix_sock(channel->socket, - msg.fds, &channel->reception_payload); + ret = lttcomm_recv_payload_fds_unix_sock( + channel->socket, msg.fds, &channel->reception_payload); if (ret < sizeof(int) * msg.fds) { ret = -1; goto error; @@ -85,43 +88,40 @@ error: goto end; } -static -enum lttng_notification_channel_message_type get_current_message_type( - struct lttng_notification_channel *channel) +static enum lttng_notification_channel_message_type +get_current_message_type(struct lttng_notification_channel *channel) { struct lttng_notification_channel_message *msg; LTTNG_ASSERT(channel->reception_payload.buffer.size >= sizeof(*msg)); - msg = (struct lttng_notification_channel_message *) - channel->reception_payload.buffer.data; + msg = (struct lttng_notification_channel_message *) channel->reception_payload.buffer.data; return (enum lttng_notification_channel_message_type) msg->type; } -static -struct lttng_notification *create_notification_from_current_message( - struct lttng_notification_channel *channel) +static struct lttng_notification * +create_notification_from_current_message(struct lttng_notification_channel *channel) { ssize_t ret; struct lttng_notification *notification = NULL; if (channel->reception_payload.buffer.size <= - sizeof(struct lttng_notification_channel_message)) { + sizeof(struct lttng_notification_channel_message)) { goto end; } { struct lttng_payload_view view = lttng_payload_view_from_payload( - &channel->reception_payload, - sizeof(struct lttng_notification_channel_message), - -1); + &channel->reception_payload, + sizeof(struct lttng_notification_channel_message), + -1); - ret = lttng_notification_create_from_payload( - &view, ¬ification); + ret = lttng_notification_create_from_payload(&view, ¬ification); } - if (ret != channel->reception_payload.buffer.size - - sizeof(struct lttng_notification_channel_message)) { + if (ret != + channel->reception_payload.buffer.size - + sizeof(struct lttng_notification_channel_message)) { lttng_notification_destroy(notification); notification = NULL; goto end; @@ -130,25 +130,24 @@ end: return notification; } -struct lttng_notification_channel *lttng_notification_channel_create( - struct lttng_endpoint *endpoint) +struct lttng_notification_channel * +lttng_notification_channel_create(struct lttng_endpoint *endpoint) { int fd, ret; bool is_in_tracing_group = false, is_root = false; char *sock_path = NULL; struct lttng_notification_channel *channel = NULL; - if (!endpoint || - endpoint != lttng_session_daemon_notification_endpoint) { + if (!endpoint || endpoint != lttng_session_daemon_notification_endpoint) { goto end; } - sock_path = (char *) zmalloc(LTTNG_PATH_MAX); + sock_path = calloc(LTTNG_PATH_MAX); if (!sock_path) { goto end; } - channel = (lttng_notification_channel *) zmalloc(sizeof(struct lttng_notification_channel)); + channel = zmalloc(); if (!channel) { goto end; } @@ -163,9 +162,8 @@ struct lttng_notification_channel *lttng_notification_channel_create( } if (is_root || is_in_tracing_group) { - ret = lttng_strncpy(sock_path, - DEFAULT_GLOBAL_NOTIFICATION_CHANNEL_UNIX_SOCK, - LTTNG_PATH_MAX); + ret = lttng_strncpy( + sock_path, DEFAULT_GLOBAL_NOTIFICATION_CHANNEL_UNIX_SOCK, LTTNG_PATH_MAX); if (ret) { ret = -LTTNG_ERR_INVALID; goto error; @@ -179,9 +177,10 @@ struct lttng_notification_channel *lttng_notification_channel_create( } /* Fallback to local session daemon. */ - ret = snprintf(sock_path, LTTNG_PATH_MAX, - DEFAULT_HOME_NOTIFICATION_CHANNEL_UNIX_SOCK, - utils_get_home_dir()); + ret = snprintf(sock_path, + LTTNG_PATH_MAX, + DEFAULT_HOME_NOTIFICATION_CHANNEL_UNIX_SOCK, + utils_get_home_dir()); if (ret < 0 || ret >= LTTNG_PATH_MAX) { goto error; } @@ -209,14 +208,12 @@ error: } enum lttng_notification_channel_status -lttng_notification_channel_get_next_notification( - struct lttng_notification_channel *channel, - struct lttng_notification **_notification) +lttng_notification_channel_get_next_notification(struct lttng_notification_channel *channel, + struct lttng_notification **_notification) { int ret; struct lttng_notification *notification = NULL; - enum lttng_notification_channel_status status = - LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; + enum lttng_notification_channel_status status = LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; struct lttng_poll_event events; if (!channel || !_notification) { @@ -233,9 +230,7 @@ lttng_notification_channel_get_next_notification( /* Deliver one of the pending notifications. */ pending_notification = cds_list_first_entry( - &channel->pending_notifications.list, - struct pending_notification, - node); + &channel->pending_notifications.list, struct pending_notification, node); notification = pending_notification->notification; if (!notification) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED; @@ -263,7 +258,7 @@ lttng_notification_channel_get_next_notification( status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_unlock; } - ret = lttng_poll_add(&events, channel->socket, LPOLLIN | LPOLLERR); + ret = lttng_poll_add(&events, channel->socket, LPOLLIN); if (ret < 0) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_clean_poll; @@ -284,8 +279,7 @@ lttng_notification_channel_get_next_notification( switch (get_current_message_type(channel)) { case LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_NOTIFICATION: - notification = create_notification_from_current_message( - channel); + notification = create_notification_from_current_message(channel); if (!notification) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_clean_poll; @@ -310,17 +304,13 @@ end: return status; } -static -int enqueue_dropped_notification( - struct lttng_notification_channel *channel) +static int enqueue_dropped_notification(struct lttng_notification_channel *channel) { int ret = 0; struct pending_notification *pending_notification; - struct cds_list_head *last_element = - channel->pending_notifications.list.prev; + struct cds_list_head *last_element = channel->pending_notifications.list.prev; - pending_notification = caa_container_of(last_element, - struct pending_notification, node); + pending_notification = caa_container_of(last_element, struct pending_notification, node); if (!pending_notification->notification) { /* * The last enqueued notification indicates dropped @@ -330,48 +320,42 @@ int enqueue_dropped_notification( goto end; } - if (channel->pending_notifications.count >= - DEFAULT_CLIENT_MAX_QUEUED_NOTIFICATIONS_COUNT && - pending_notification->notification) { + if (channel->pending_notifications.count >= DEFAULT_CLIENT_MAX_QUEUED_NOTIFICATIONS_COUNT && + pending_notification->notification) { /* * Discard the last enqueued notification to indicate * that notifications were dropped at this point. */ - lttng_notification_destroy( - pending_notification->notification); + lttng_notification_destroy(pending_notification->notification); pending_notification->notification = NULL; goto end; } - pending_notification = (struct pending_notification *) zmalloc(sizeof(*pending_notification)); + pending_notification = zmalloc(); if (!pending_notification) { ret = -1; goto end; } CDS_INIT_LIST_HEAD(&pending_notification->node); - cds_list_add(&pending_notification->node, - &channel->pending_notifications.list); + cds_list_add(&pending_notification->node, &channel->pending_notifications.list); channel->pending_notifications.count++; end: return ret; } -static -int enqueue_notification_from_current_message( - struct lttng_notification_channel *channel) +static int enqueue_notification_from_current_message(struct lttng_notification_channel *channel) { int ret = 0; struct lttng_notification *notification; struct pending_notification *pending_notification; - if (channel->pending_notifications.count >= - DEFAULT_CLIENT_MAX_QUEUED_NOTIFICATIONS_COUNT) { + if (channel->pending_notifications.count >= DEFAULT_CLIENT_MAX_QUEUED_NOTIFICATIONS_COUNT) { /* Drop the notification. */ ret = enqueue_dropped_notification(channel); goto end; } - pending_notification = (struct pending_notification *) zmalloc(sizeof(*pending_notification)); + pending_notification = zmalloc(); if (!pending_notification) { ret = -1; goto error; @@ -385,8 +369,7 @@ int enqueue_notification_from_current_message( } pending_notification->notification = notification; - cds_list_add(&pending_notification->node, - &channel->pending_notifications.list); + cds_list_add(&pending_notification->node, &channel->pending_notifications.list); channel->pending_notifications.count++; end: return ret; @@ -396,13 +379,11 @@ error: } enum lttng_notification_channel_status -lttng_notification_channel_has_pending_notification( - struct lttng_notification_channel *channel, - bool *_notification_pending) +lttng_notification_channel_has_pending_notification(struct lttng_notification_channel *channel, + bool *_notification_pending) { int ret; - enum lttng_notification_channel_status status = - LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; + enum lttng_notification_channel_status status = LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; struct lttng_poll_event events; if (!channel || !_notification_pending) { @@ -443,7 +424,7 @@ lttng_notification_channel_has_pending_notification( status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_unlock; } - ret = lttng_poll_add(&events, channel->socket, LPOLLIN | LPOLLERR); + ret = lttng_poll_add(&events, channel->socket, LPOLLIN); if (ret < 0) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_clean_poll; @@ -495,9 +476,8 @@ end: return status; } -static -int receive_command_reply(struct lttng_notification_channel *channel, - enum lttng_notification_channel_status *status) +static int receive_command_reply(struct lttng_notification_channel *channel, + enum lttng_notification_channel_status *status) { int ret; struct lttng_notification_channel_command_reply *reply; @@ -515,8 +495,7 @@ int receive_command_reply(struct lttng_notification_channel *channel, case LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_COMMAND_REPLY: goto exit_loop; case LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_NOTIFICATION: - ret = enqueue_notification_from_current_message( - channel); + ret = enqueue_notification_from_current_message(channel); if (ret) { goto end; } @@ -531,9 +510,9 @@ int receive_command_reply(struct lttng_notification_channel *channel, { struct lttng_notification_channel_command_handshake *handshake; - handshake = (struct lttng_notification_channel_command_handshake *) - (channel->reception_payload.buffer.data + - sizeof(struct lttng_notification_channel_message)); + handshake = (struct lttng_notification_channel_command_handshake + *) (channel->reception_payload.buffer.data + + sizeof(struct lttng_notification_channel_message)); channel->version.major = handshake->major; channel->version.minor = handshake->minor; channel->version.set = true; @@ -547,45 +526,41 @@ int receive_command_reply(struct lttng_notification_channel *channel, exit_loop: if (channel->reception_payload.buffer.size < - (sizeof(struct lttng_notification_channel_message) + - sizeof(*reply))) { + (sizeof(struct lttng_notification_channel_message) + sizeof(*reply))) { /* Invalid message received. */ ret = -1; goto end; } - reply = (struct lttng_notification_channel_command_reply *) - (channel->reception_payload.buffer.data + - sizeof(struct lttng_notification_channel_message)); + reply = (struct lttng_notification_channel_command_reply + *) (channel->reception_payload.buffer.data + + sizeof(struct lttng_notification_channel_message)); *status = (enum lttng_notification_channel_status) reply->status; end: return ret; } -static -int handshake(struct lttng_notification_channel *channel) +static int handshake(struct lttng_notification_channel *channel) { ssize_t ret; - enum lttng_notification_channel_status status = - LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; + enum lttng_notification_channel_status status = LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; struct lttng_notification_channel_command_handshake handshake = { .major = LTTNG_NOTIFICATION_CHANNEL_VERSION_MAJOR, .minor = LTTNG_NOTIFICATION_CHANNEL_VERSION_MINOR, }; - struct lttng_notification_channel_message msg_header = { - .type = LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_HANDSHAKE, - .size = sizeof(handshake), - .fds = 0, - }; + struct lttng_notification_channel_message msg_header; char send_buffer[sizeof(msg_header) + sizeof(handshake)]; + msg_header.type = LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_HANDSHAKE; + msg_header.size = sizeof(handshake); + msg_header.fds = 0; + memcpy(send_buffer, &msg_header, sizeof(msg_header)); memcpy(send_buffer + sizeof(msg_header), &handshake, sizeof(handshake)); pthread_mutex_lock(&channel->lock); - ret = lttcomm_send_creds_unix_sock(channel->socket, send_buffer, - sizeof(send_buffer)); + ret = lttcomm_send_creds_unix_sock(channel->socket, send_buffer, sizeof(send_buffer)); if (ret < 0) { goto end_unlock; } @@ -611,22 +586,20 @@ end_unlock: return ret; } -static -enum lttng_notification_channel_status send_condition_command( - struct lttng_notification_channel *channel, - enum lttng_notification_channel_message_type type, - const struct lttng_condition *condition) +static enum lttng_notification_channel_status +send_condition_command(struct lttng_notification_channel *channel, + enum lttng_notification_channel_message_type type, + const struct lttng_condition *condition) { int socket; ssize_t ret; - enum lttng_notification_channel_status status = - LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; + enum lttng_notification_channel_status status = LTTNG_NOTIFICATION_CHANNEL_STATUS_OK; struct lttng_payload payload; - struct lttng_notification_channel_message cmd_header = { - .type = (int8_t) type, - .size =0, - .fds = 0, - }; + struct lttng_notification_channel_message cmd_header; + + cmd_header.type = (int8_t) type; + cmd_header.size = 0; + cmd_header.fds = 0; lttng_payload_init(&payload); @@ -636,7 +609,7 @@ enum lttng_notification_channel_status send_condition_command( } LTTNG_ASSERT(type == LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_SUBSCRIBE || - type == LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_UNSUBSCRIBE); + type == LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_UNSUBSCRIBE); pthread_mutex_lock(&channel->lock); socket = channel->socket; @@ -646,8 +619,7 @@ enum lttng_notification_channel_status send_condition_command( goto end_unlock; } - ret = lttng_dynamic_buffer_append(&payload.buffer, &cmd_header, - sizeof(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; @@ -661,21 +633,17 @@ enum lttng_notification_channel_status send_condition_command( /* Update payload length. */ ((struct lttng_notification_channel_message *) payload.buffer.data)->size = - (uint32_t) (payload.buffer.size - sizeof(cmd_header)); + (uint32_t) (payload.buffer.size - sizeof(cmd_header)); { - struct lttng_payload_view pv = - lttng_payload_view_from_payload( - &payload, 0, -1); - const int fd_count = - lttng_payload_view_get_fd_handle_count(&pv); + struct lttng_payload_view pv = lttng_payload_view_from_payload(&payload, 0, -1); + const int fd_count = lttng_payload_view_get_fd_handle_count(&pv); /* Update fd count. */ ((struct lttng_notification_channel_message *) payload.buffer.data)->fds = (uint32_t) fd_count; - ret = lttcomm_send_unix_sock( - socket, pv.buffer.data, pv.buffer.size); + ret = lttcomm_send_unix_sock(socket, pv.buffer.data, pv.buffer.size); if (ret < 0) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_unlock; @@ -683,8 +651,7 @@ enum lttng_notification_channel_status send_condition_command( /* Pass fds if present. */ if (fd_count > 0) { - ret = lttcomm_send_payload_view_fds_unix_sock(socket, - &pv); + ret = lttcomm_send_payload_view_fds_unix_sock(socket, &pv); if (ret < 0) { status = LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR; goto end_unlock; @@ -704,26 +671,23 @@ end: return status; } -enum lttng_notification_channel_status lttng_notification_channel_subscribe( - struct lttng_notification_channel *channel, - const struct lttng_condition *condition) +enum lttng_notification_channel_status +lttng_notification_channel_subscribe(struct lttng_notification_channel *channel, + const struct lttng_condition *condition) { - return send_condition_command(channel, - LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_SUBSCRIBE, - condition); + return send_condition_command( + channel, LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_SUBSCRIBE, condition); } -enum lttng_notification_channel_status lttng_notification_channel_unsubscribe( - struct lttng_notification_channel *channel, - const struct lttng_condition *condition) +enum lttng_notification_channel_status +lttng_notification_channel_unsubscribe(struct lttng_notification_channel *channel, + const struct lttng_condition *condition) { - return send_condition_command(channel, - LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_UNSUBSCRIBE, - condition); + return send_condition_command( + channel, LTTNG_NOTIFICATION_CHANNEL_MESSAGE_TYPE_UNSUBSCRIBE, condition); } -void lttng_notification_channel_destroy( - struct lttng_notification_channel *channel) +void lttng_notification_channel_destroy(struct lttng_notification_channel *channel) { if (!channel) { return;