#include <time.h>
#include <unistd.h>
-#include <assert.h>
#include <inttypes.h>
#include <fcntl.h>
struct notification_client_list *client_list;
const struct lttng_condition *condition;
- assert(condition_key);
+ LTTNG_ASSERT(condition_key);
client_list = caa_container_of(node, struct notification_client_list,
notification_trigger_clients_ht_node);
struct session_info *session_info = _data;
int ret;
- assert(session_info);
+ LTTNG_ASSERT(session_info);
if (session_info->channel_infos_ht) {
ret = cds_lfht_destroy(session_info->channel_infos_ht, NULL);
if (ret) {
{
struct session_info *session_info;
- assert(name);
+ LTTNG_ASSERT(name);
session_info = zmalloc(sizeof(*session_info));
if (!session_info) {
free(client_list_element);
}
- assert(cds_list_empty(&list->triggers_list));
+ LTTNG_ASSERT(cds_list_empty(&list->triggers_list));
pthread_mutex_destroy(&list->lock);
call_rcu(&list->rcu_node, free_notification_client_list_rcu);
lttng_trigger_get_const_condition(
element->trigger);
- assert(current_condition);
+ LTTNG_ASSERT(current_condition);
if (!lttng_condition_is_equal(condition,
current_condition)) {
continue;
channel_key,
&iter);
node = cds_lfht_iter_get_node(&iter);
- assert(node);
+ LTTNG_ASSERT(node);
channel_info = caa_container_of(node, struct channel_info,
channels_ht_node);
uid_t object_uid = 0;
gid_t object_gid = 0;
- assert(trigger);
- assert(condition);
- assert(client);
- assert(state);
+ LTTNG_ASSERT(trigger);
+ LTTNG_ASSERT(condition);
+ LTTNG_ASSERT(client);
+ LTTNG_ASSERT(state);
switch (get_condition_binding_object(condition)) {
case LTTNG_OBJECT_TYPE_SESSION:
status = lttng_condition_buffer_usage_get_domain_type(condition,
&condition_domain);
- assert(status == LTTNG_CONDITION_STATUS_OK);
+ LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
if (channel_info->key.domain != condition_domain) {
goto fail;
}
status = lttng_condition_buffer_usage_get_session_name(
condition, &condition_session_name);
- assert((status == LTTNG_CONDITION_STATUS_OK) && condition_session_name);
+ LTTNG_ASSERT((status == LTTNG_CONDITION_STATUS_OK) && condition_session_name);
status = lttng_condition_buffer_usage_get_channel_name(
condition, &condition_channel_name);
- assert((status == LTTNG_CONDITION_STATUS_OK) && condition_channel_name);
+ LTTNG_ASSERT((status == LTTNG_CONDITION_STATUS_OK) && condition_channel_name);
if (strcmp(channel_info->session_info->name, condition_session_name)) {
goto fail;
status = lttng_condition_session_consumed_size_get_session_name(
condition, &condition_session_name);
- assert((status == LTTNG_CONDITION_STATUS_OK) && condition_session_name);
+ LTTNG_ASSERT((status == LTTNG_CONDITION_STATUS_OK) && condition_session_name);
if (strcmp(channel_info->session_info->name, condition_session_name)) {
goto fail;
goto end;
}
- assert(condition_session_name);
+ LTTNG_ASSERT(condition_session_name);
applies = !strcmp(condition_session_name, session_name);
break;
}
name, uid, gid);
session = caa_container_of(node, struct session_info,
sessions_ht_node);
- assert(session->uid == uid);
- assert(session->gid == gid);
+ LTTNG_ASSERT(session->uid == uid);
+ LTTNG_ASSERT(session->gid == gid);
session_info_get(session);
goto end;
}
&key,
&iter);
node = cds_lfht_iter_get_node(&iter);
- assert(node);
+ LTTNG_ASSERT(node);
channel_info = caa_container_of(node, struct channel_info,
channels_ht_node);
cds_lfht_del(state->channels_ht, node);
trigger = trigger_list_element->trigger;
condition = lttng_trigger_get_const_condition(trigger);
- assert(condition);
+ LTTNG_ASSERT(condition);
condition_type = lttng_condition_get_type(condition);
if (condition_type == LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING &&
}
static
-int handle_notification_thread_command_remove_tracer_event_source(
- struct notification_thread_state *state,
- int tracer_event_source_fd,
- enum lttng_error_code *_cmd_result)
+struct notification_event_tracer_event_source_element *
+find_tracer_event_source_element(struct notification_thread_state *state,
+ int tracer_event_source_fd)
{
- int ret = 0;
- bool found = false;
- enum lttng_error_code cmd_result = LTTNG_OK;
- struct notification_event_tracer_event_source_element *source_element = NULL, *tmp;
+ struct notification_event_tracer_event_source_element *source_element;
- cds_list_for_each_entry_safe(source_element, tmp,
+ cds_list_for_each_entry(source_element,
&state->tracer_event_sources_list, node) {
- if (source_element->fd != tracer_event_source_fd) {
- continue;
+ if (source_element->fd == tracer_event_source_fd) {
+ goto end;
}
-
- DBG("Removed tracer event source from poll set: tracer_event_source_fd = %d, domain = '%s'",
- tracer_event_source_fd,
- lttng_domain_type_str(source_element->domain));
- cds_list_del(&source_element->node);
- found = true;
- break;
}
- if (!found) {
- /*
- * This is temporarily allowed since the poll activity set is
- * not properly cleaned-up for the moment. This is adressed in
- * an upcoming fix.
- */
- source_element = NULL;
- goto end;
- }
+ source_element = NULL;
+end:
+ return source_element;
+}
- if (!source_element->is_fd_in_poll_set) {
- /* Skip the poll set removal. */
- goto end;
- }
+static
+int remove_tracer_event_source_from_pollset(
+ struct notification_thread_state *state,
+ struct notification_event_tracer_event_source_element *source_element)
+{
+ int ret = 0;
+
+ LTTNG_ASSERT(source_element->is_fd_in_poll_set);
DBG3("Removing tracer event source from poll set: tracer_event_source_fd = %d, domain = '%s'",
- tracer_event_source_fd,
+ source_element->fd,
lttng_domain_type_str(source_element->domain));
/* Removing the fd from the event poll set. */
- ret = lttng_poll_del(&state->events, tracer_event_source_fd);
+ ret = lttng_poll_del(&state->events, source_element->fd);
if (ret < 0) {
ERR("Failed to remove tracer event source from poll set: tracer_event_source_fd = %d, domain = '%s'",
- tracer_event_source_fd,
+ source_element->fd,
lttng_domain_type_str(source_element->domain));
- cmd_result = LTTNG_ERR_FATAL;
+ ret = -1;
goto end;
}
source_element->is_fd_in_poll_set = false;
- ret = drain_event_notifier_notification_pipe(state, tracer_event_source_fd,
+ ret = drain_event_notifier_notification_pipe(state, source_element->fd,
source_element->domain);
if (ret) {
ERR("Error draining event notifier notification: tracer_event_source_fd = %d, domain = %s",
- tracer_event_source_fd,
+ source_element->fd,
lttng_domain_type_str(source_element->domain));
- cmd_result = LTTNG_ERR_FATAL;
+ ret = -1;
goto end;
}
- /*
- * The drain_event_notifier_notification_pipe() call might have read
- * data from an fd that we received in event in the latest _poll_wait()
- * call. Make sure the thread call poll_wait() again to ensure we have
- * a clean state.
- */
- state->restart_poll = true;
-
end:
- free(source_element);
- *_cmd_result = cmd_result;
return ret;
}
-int handle_notification_thread_remove_tracer_event_source_no_result(
+int handle_notification_thread_tracer_event_source_died(
struct notification_thread_state *state,
int tracer_event_source_fd)
{
- int ret;
- enum lttng_error_code cmd_result;
+ int ret = 0;
+ struct notification_event_tracer_event_source_element *source_element;
+
+ source_element = find_tracer_event_source_element(state,
+ tracer_event_source_fd);
+
+ LTTNG_ASSERT(source_element);
+
+ ret = remove_tracer_event_source_from_pollset(state, source_element);
+ if (ret) {
+ ERR("Failed to remove dead tracer event source from poll set");
+ }
+
+ return ret;
+}
+
+static
+int handle_notification_thread_command_remove_tracer_event_source(
+ struct notification_thread_state *state,
+ int tracer_event_source_fd,
+ enum lttng_error_code *_cmd_result)
+{
+ int ret = 0;
+ enum lttng_error_code cmd_result = LTTNG_OK;
+ struct notification_event_tracer_event_source_element *source_element = NULL;
+
+ source_element = find_tracer_event_source_element(state,
+ tracer_event_source_fd);
- ret = handle_notification_thread_command_remove_tracer_event_source(
- state, tracer_event_source_fd, &cmd_result);
- (void) cmd_result;
+ LTTNG_ASSERT(source_element);
+
+ /* Remove the tracer source from the list. */
+ cds_list_del(&source_element->node);
+
+ if (!source_element->is_fd_in_poll_set) {
+ /* Skip the poll set removal. */
+ goto end;
+ }
+
+ ret = remove_tracer_event_source_from_pollset(state, source_element);
+ if (ret) {
+ ERR("Failed to remove tracer event source from poll set");
+ cmd_result = LTTNG_ERR_FATAL;
+ }
+
+end:
+ free(source_element);
+ *_cmd_result = cmd_result;
return ret;
}
trigger_status = lttng_trigger_get_owner_uid(trigger,
trigger_owner_uid);
- assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
+ LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
}
static int handle_notification_thread_command_get_trigger(
ret = lttng_condition_buffer_usage_get_domain_type(condition,
&domain);
- assert(ret == 0);
+ LTTNG_ASSERT(ret == 0);
if (domain != LTTNG_DOMAIN_KERNEL) {
is_supported = true;
lttng_condition_event_rule_matches_get_rule(
condition, &event_rule);
- assert(status == LTTNG_CONDITION_STATUS_OK);
+ LTTNG_ASSERT(status == LTTNG_CONDITION_STATUS_OK);
domain = lttng_event_rule_get_domain_type(event_rule);
if (domain != LTTNG_DOMAIN_KERNEL) {
&channel->key,
&lookup_iter);
node = cds_lfht_iter_get_node(&lookup_iter);
- assert(node);
+ LTTNG_ASSERT(node);
trigger_list = caa_container_of(node,
struct lttng_channel_trigger_list,
channel_triggers_ht_node);
lttng_trigger_get_const_action(trigger);
enum lttng_action_type action_type;
- assert(action);
+ LTTNG_ASSERT(action);
action_type = lttng_action_get_type(action);
if (action_type == LTTNG_ACTION_TYPE_NOTIFY) {
is_notify = true;
}
action_status = lttng_action_list_get_count(action, &count);
- assert(action_status == LTTNG_ACTION_STATUS_OK);
+ LTTNG_ASSERT(action_status == LTTNG_ACTION_STATUS_OK);
for (i = 0; i < count; i++) {
const struct lttng_action *inner_action =
}
status = lttng_trigger_get_name(trigger, name);
- assert(status == LTTNG_TRIGGER_STATUS_OK);
+ LTTNG_ASSERT(status == LTTNG_TRIGGER_STATUS_OK);
taken = trigger_name_taken(state, trigger);
} while (taken || state->trigger_id.name_offset == UINT64_MAX);
struct notification_thread_state *state,
struct lttng_trigger_ht_element *trigger_ht_element)
{
- assert(state);
- assert(trigger_ht_element);
+ LTTNG_ASSERT(state);
+ LTTNG_ASSERT(trigger_ht_element);
cds_lfht_del(state->triggers_ht, &trigger_ht_element->node);
cds_lfht_del(state->triggers_by_name_uid_ht, &trigger_ht_element->node_by_name_uid);
}
condition = lttng_trigger_get_condition(trigger);
- assert(condition);
+ LTTNG_ASSERT(condition);
/* Some conditions require tracers to implement a minimal ABI version. */
if (!condition_is_supported(condition)) {
* notification_trigger_clients_ht.
*/
client_list = get_client_list_from_condition(state, condition);
- assert(client_list);
+ LTTNG_ASSERT(client_list);
pthread_mutex_lock(&client_list->lock);
cds_list_del(&trigger_ht_element->client_list_trigger_node);
* If both data and fds are equal to zero, we are in an invalid
* state.
*/
- assert(fds_to_send_count != 0);
+ LTTNG_ASSERT(fds_to_send_count != 0);
goto send_fds;
}
*/
const struct lttng_notification_channel_message *msg;
- assert(sizeof(*msg) == client->communication.inbound.payload.buffer.size);
+ LTTNG_ASSERT(sizeof(*msg) == client->communication.inbound.payload.buffer.size);
msg = (const struct lttng_notification_channel_message *)
client->communication.inbound.payload.buffer.data;
&client->communication.inbound.creds);
client->gid = LTTNG_SOCK_GET_GID_CRED(
&client->communication.inbound.creds);
- DBG("Received handshake from client (uid = %u, gid = %u) with version %i.%i",
+ client->is_sessiond = LTTNG_SOCK_GET_PID_CRED(&client->communication.inbound.creds) == getpid();
+ DBG("Received handshake from client: uid = %u, gid = %u, protocol version = %i.%i, client is sessiond = %s",
client->uid, client->gid, (int) client->major,
- (int) client->minor);
+ (int) client->minor,
+ client->is_sessiond ? "true" : "false");
if (handshake_client->major !=
LTTNG_NOTIFICATION_CHANNEL_VERSION_MAJOR) {
}
receive_fds:
- assert(client->communication.inbound.bytes_to_receive == 0);
+ LTTNG_ASSERT(client->communication.inbound.bytes_to_receive == 0);
/* Receive fds. */
if (client->communication.inbound.fds_to_receive != 0) {
expected_size = sizeof(int) *
client->communication.inbound
.fds_to_receive;
- assert(ret == expected_size);
+ LTTNG_ASSERT(ret == expected_size);
client->communication.inbound.fds_to_receive = 0;
} else if (ret == 0) {
/* Received nothing. */
}
/* At this point the message is complete.*/
- assert(client->communication.inbound.bytes_to_receive == 0 &&
+ LTTNG_ASSERT(client->communication.inbound.bytes_to_receive == 0 &&
client->communication.inbound.fds_to_receive == 0);
ret = client_dispatch_message(client, state);
if (ret) {
goto skip_client;
}
+ if (lttng_trigger_is_hidden(trigger) && !client->is_sessiond) {
+ /*
+ * Notifications resulting from an hidden trigger are
+ * only sent to the session daemon.
+ */
+ DBG("Skipping client as the trigger is hidden and the client is not the session daemon");
+ goto skip_client;
+ }
+
if (source_object_creds) {
if (client->uid != lttng_credentials_get_uid(source_object_creds) &&
client->gid != lttng_credentials_get_gid(source_object_creds) &&
notification->capture_buf_size, false);
if (evaluation == NULL) {
- ERR("Failed to create event rule hit evaluation while creating and enqueuing action executor job");
+ ERR("Failed to create event rule matches evaluation while creating and enqueuing action executor job");
ret = -1;
goto end_unlock;
}
+
client_list = get_client_list_from_condition(state,
lttng_trigger_get_const_condition(element->trigger));
executor_status = action_executor_enqueue_trigger(state->executor,
ret = 0;
trigger = trigger_list_element->trigger;
condition = lttng_trigger_get_const_condition(trigger);
- assert(condition);
+ LTTNG_ASSERT(condition);
/*
* Check if any client is subscribed to the result of this