X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fnotification-thread-internal.h;h=eb23d1f78fa2df8d106cdb9fe4caddf1177bb90d;hp=75d052b07122ce9af15ff29fb751267298bbaee5;hb=882093eef6fdd658833928a62be5d42fc0cdcb00;hpb=ea9a44f03f3f6e144b5f7f312eee2a5f7a849ecb diff --git a/src/bin/lttng-sessiond/notification-thread-internal.h b/src/bin/lttng-sessiond/notification-thread-internal.h index 75d052b07..eb23d1f78 100644 --- a/src/bin/lttng-sessiond/notification-thread-internal.h +++ b/src/bin/lttng-sessiond/notification-thread-internal.h @@ -1,26 +1,27 @@ /* - * Copyright (C) 2017 - Jérémie Galarneau + * Copyright (C) 2017 Jérémie Galarneau * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License, version 2 only, as - * published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef NOTIFICATION_THREAD_INTERNAL_H #define NOTIFICATION_THREAD_INTERNAL_H +#include +#include +#include +#include #include -#include +#include #include +#include +#include +#include +#include "notification-thread.h" + +struct lttng_evaluation; +struct notification_thread_handle; struct channel_key { uint64_t key; @@ -33,7 +34,7 @@ struct session_info { uid_t uid; gid_t gid; /* - * Back-ref (weak) to all channels in this session. + * Hashtable containing back-refs (weak) to all channels in this session. * The hashtable's key is a hash of (struct channel_key) and * the value is of type (struct channel_info *). */ @@ -41,7 +42,20 @@ struct session_info { struct lttng_session_trigger_list *trigger_list; /* Node in the notification thread state's sessions_ht. */ struct cds_lfht_node sessions_ht_node; + /* + * Weak reference to the thread state's sessions_ht. Used for removal on + * destruction. + */ + struct cds_lfht *sessions_ht; uint64_t consumed_data_size; + struct { + /* Whether a rotation is ongoing for this session. */ + bool ongoing; + /* Identifier of the currently ongoing rotation. */ + uint64_t id; + } rotation; + /* call_rcu delayed reclaim. */ + struct rcu_head rcu_node; }; struct channel_info { @@ -57,6 +71,172 @@ struct channel_info { struct cds_lfht_node channels_ht_node; /* Node in the session_info's channels_ht. */ struct cds_lfht_node session_info_channels_ht_node; + /* call_rcu delayed reclaim. */ + struct rcu_head rcu_node; +}; + +struct notification_client_list_element { + struct notification_client *client; + struct cds_list_head node; +}; + +/* + * Thread safety of notification_client and notification_client_list. + * + * The notification thread (main thread) and the action executor + * interact through client lists. Hence, when the action executor + * thread looks-up the list of clients subscribed to a given + * condition, it will acquire a reference to the list and lock it + * while attempting to communicate with the various clients. + * + * It is not necessary to reference-count clients as they are guaranteed + * to be 'alive' if they are present in a list and that list is locked. Indeed, + * removing references to the client from those subscription lists is part of + * the work performed on destruction of a client. + * + * No provision for other access scenarios are taken into account; + * this is the bare minimum to make these accesses safe and the + * notification thread's state is _not_ "thread-safe" in any general + * sense. + */ +struct notification_client_list { + pthread_mutex_t lock; + struct urcu_ref ref; + const struct lttng_trigger *trigger; + struct cds_list_head list; + /* Weak reference to container. */ + struct cds_lfht *notification_trigger_clients_ht; + struct cds_lfht_node notification_trigger_clients_ht_node; + /* call_rcu delayed reclaim. */ + struct rcu_head rcu_node; +}; + +struct notification_client { + /* + * Nests within the notification_client_list lock. + * + * Protects the outbound communication and the active flag which + * is used by both the notification and action executor threads. + * + * The remaining fields of the object can be used without any + * synchronization as they are either immutable (id, creds, version) or + * only accessed by the notification thread. + */ + pthread_mutex_t lock; + notification_client_id id; + int socket; + /* Client protocol version. */ + uint8_t major, minor; + uid_t uid; + gid_t gid; + /* + * Indicates if the credentials and versions of the client have been + * checked. + */ + bool validated; + /* + * Conditions to which the client's notification channel is subscribed. + * List of struct lttng_condition_list_node. The condition member is + * owned by the client. + */ + struct cds_list_head condition_list; + struct cds_lfht_node client_socket_ht_node; + struct cds_lfht_node client_id_ht_node; + struct { + /* + * If a client's communication is inactive, it means that a + * fatal error has occurred (could be either a protocol error or + * the socket API returned a fatal error). No further + * communication should be attempted; the client is queued for + * clean-up. + */ + bool active; + struct { + /* + * During the reception of a message, the reception + * buffers' "size" is set to contain the current + * message's complete payload. + */ + struct lttng_payload payload; + /* Bytes left to receive for the current message. */ + size_t bytes_to_receive; + /* FDs left to receive for the current message. */ + int fds_to_receive; + /* Type of the message being received. */ + enum lttng_notification_channel_message_type msg_type; + /* + * Indicates whether or not credentials are expected + * from the client. + */ + bool expect_creds; + /* + * Indicates whether or not credentials were received + * from the client. + */ + bool creds_received; + /* Only used during credentials reception. */ + lttng_sock_cred creds; + } inbound; + struct { + /* + * Indicates whether or not a notification addressed to + * this client was dropped because a command reply was + * already buffered. + * + * A notification is dropped whenever the buffer is not + * empty. + */ + bool dropped_notification; + /* + * Indicates whether or not a command reply is already + * buffered. In this case, it means that the client is + * not consuming command replies before emitting a new + * one. This could be caused by a protocol error or a + * misbehaving/malicious client. + */ + bool queued_command_reply; + struct lttng_payload payload; + } outbound; + } communication; + /* call_rcu delayed reclaim. */ + struct rcu_head rcu_node; +}; + +enum client_transmission_status { + CLIENT_TRANSMISSION_STATUS_COMPLETE, + CLIENT_TRANSMISSION_STATUS_QUEUED, + /* Communication failure. */ + CLIENT_TRANSMISSION_STATUS_FAIL, + /* Fatal error. */ + CLIENT_TRANSMISSION_STATUS_ERROR, }; +LTTNG_HIDDEN +bool notification_client_list_get(struct notification_client_list *list); + +LTTNG_HIDDEN +void notification_client_list_put(struct notification_client_list *list); + +/* Only returns a non-zero value if a fatal error occurred. */ +typedef int (*report_client_transmission_result_cb)( + struct notification_client *client, + enum client_transmission_status status, + void *user_data); + +LTTNG_HIDDEN +int notification_client_list_send_evaluation( + struct notification_client_list *list, + const struct lttng_condition *condition, + const struct lttng_evaluation *evaluation, + const struct lttng_credentials *trigger_creds, + const struct lttng_credentials *source_object_creds, + report_client_transmission_result_cb client_report, + void *user_data); + +LTTNG_HIDDEN +int notification_thread_client_communication_update( + struct notification_thread_handle *handle, + notification_client_id id, + enum client_transmission_status transmission_status); + #endif /* NOTIFICATION_THREAD_INTERNAL_H */