*/
#define _LGPL_SOURCE
+#include <errno.h>
+#include <fcntl.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <common/sessiond-comm/sessiond-comm.h>
#include "buffer-registry.h"
+#include "condition-internal.h"
#include "fd-limit.h"
#include "health-sessiond.h"
#include "ust-app.h"
#include "notification-thread-commands.h"
#include "rotate.h"
#include "event.h"
+#include "event-notifier-error-accounting.h"
+
struct lttng_ht *ust_app_ht;
struct lttng_ht *ust_app_ht_by_sock;
*/
if (app->event_notifier_group.object) {
enum lttng_error_code ret_code;
+ enum event_notifier_error_accounting_status status;
+
const int event_notifier_read_fd = lttng_pipe_get_readfd(
app->event_notifier_group.event_pipe);
ret_code = notification_thread_command_remove_tracer_event_source(
- notification_thread_handle,
+ the_notification_thread_handle,
event_notifier_read_fd);
if (ret_code != LTTNG_OK) {
ERR("Failed to remove application tracer event source from notification thread");
}
+ status = event_notifier_error_accounting_unregister_app(app);
+ if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
+ ERR("Error unregistering app from event notifier error accounting");
+ }
+
ustctl_release_object(sock, app->event_notifier_group.object);
free(app->event_notifier_group.object);
}
init_ust_event_notifier_from_event_rule(event_rule, &event_notifier);
event_notifier.event.token = ua_event_notifier_rule->token;
+ event_notifier.error_counter_index = ua_event_notifier_rule->error_counter_index;
/* Create UST event notifier against the tracer. */
pthread_mutex_lock(&app->sock_lock);
health_code_update();
/*
- * Now get the channel from the consumer. This call wil populate the stream
+ * Now get the channel from the consumer. This call will populate the stream
* list of that channel and set the ust objects.
*/
if (usess->consumer->enabled) {
pthread_mutex_unlock(®_uid->registry->reg.ust->lock);
notification_ret = notification_thread_command_add_channel(
- notification_thread_handle, session->name,
- lttng_credentials_get_uid(&ua_sess->effective_credentials),
- lttng_credentials_get_gid(&ua_sess->effective_credentials),
- ua_chan->name,
- ua_chan->key, LTTNG_DOMAIN_UST,
+ the_notification_thread_handle, session->name,
+ lttng_credentials_get_uid(
+ &ua_sess->effective_credentials),
+ lttng_credentials_get_gid(
+ &ua_sess->effective_credentials),
+ ua_chan->name, ua_chan->key, LTTNG_DOMAIN_UST,
ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf);
if (notification_ret != LTTNG_OK) {
ret = - (int) notification_ret;
pthread_mutex_unlock(®istry->lock);
cmd_ret = notification_thread_command_add_channel(
- notification_thread_handle, session->name,
- lttng_credentials_get_uid(&ua_sess->effective_credentials),
- lttng_credentials_get_gid(&ua_sess->effective_credentials),
- ua_chan->name,
- ua_chan->key, LTTNG_DOMAIN_UST,
+ the_notification_thread_handle, session->name,
+ lttng_credentials_get_uid(
+ &ua_sess->effective_credentials),
+ lttng_credentials_get_gid(
+ &ua_sess->effective_credentials),
+ ua_chan->name, ua_chan->key, LTTNG_DOMAIN_UST,
ua_chan->attr.subbuf_size * ua_chan->attr.num_subbuf);
if (cmd_ret != LTTNG_OK) {
ret = - (int) cmd_ret;
DBG2("UST app create token event rule completed: app = '%s' (ppid: %d), token = %" PRIu64,
app->name, app->ppid, lttng_trigger_get_tracer_token(trigger));
-end:
- return ret;
+ goto end;
error:
/* The RCU read side lock is already being held by the caller. */
delete_ust_app_event_notifier_rule(-1, ua_event_notifier_rule, app);
+end:
return ret;
}
DBG3("UST app creating application for socket %d", sock);
if ((msg->bits_per_long == 64 &&
- (uatomic_read(&ust_consumerd64_fd) == -EINVAL))
- || (msg->bits_per_long == 32 &&
- (uatomic_read(&ust_consumerd32_fd) == -EINVAL))) {
+ (uatomic_read(&the_ust_consumerd64_fd) ==
+ -EINVAL)) ||
+ (msg->bits_per_long == 32 &&
+ (uatomic_read(&the_ust_consumerd32_fd) ==
+ -EINVAL))) {
ERR("Registration failed: application \"%s\" (pid: %d) has "
"%d-bit long, but no consumerd for this size is available.\n",
msg->name, msg->pid, msg->bits_per_long);
int event_pipe_write_fd;
struct lttng_ust_abi_object_data *event_notifier_group = NULL;
enum lttng_error_code lttng_ret;
+ enum event_notifier_error_accounting_status event_notifier_error_accounting_status;
assert(app);
lttng_fd_put(LTTNG_FD_APPS, 1);
lttng_ret = notification_thread_command_add_tracer_event_source(
- notification_thread_handle,
- lttng_pipe_get_readfd(app->event_notifier_group.event_pipe),
+ the_notification_thread_handle,
+ lttng_pipe_get_readfd(
+ app->event_notifier_group.event_pipe),
LTTNG_DOMAIN_UST);
if (lttng_ret != LTTNG_OK) {
ERR("Failed to add tracer event source to notification thread");
/* Assign handle only when the complete setup is valid. */
app->event_notifier_group.object = event_notifier_group;
+
+ event_notifier_error_accounting_status = event_notifier_error_accounting_register_app(app);
+ if (event_notifier_error_accounting_status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
+ ERR("Failed to setup event notifier error accounting for app");
+ ret = -1;
+ goto error;
+ }
+
return ret;
error:
ustctl_release_object(app->sock, app->event_notifier_group.object);
free(app->event_notifier_group.object);
+ app->event_notifier_group.object = NULL;
return ret;
}
/* Get all triggers using uid 0 (root) */
ret_code = notification_thread_command_list_triggers(
- notification_thread_handle, 0, &triggers);
+ the_notification_thread_handle, 0, &triggers);
if (ret_code != LTTNG_OK) {
ret = -1;
goto end;
rcu_read_unlock();
}
+void ust_app_update_event_notifier_error_count(struct lttng_trigger *trigger)
+{
+ uint64_t error_count = 0;
+ enum event_notifier_error_accounting_status status;
+ struct lttng_condition *condition = lttng_trigger_get_condition(trigger);
+
+ status = event_notifier_error_accounting_get_count(trigger, &error_count);
+ if (status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
+ ERR("Error getting trigger error count.");
+ }
+
+ lttng_condition_on_event_set_error_count(condition, error_count);
+}
+
/*
* Add context to a specific channel for global UST domain.
*/
struct buffer_reg_channel *buf_reg_chan;
struct consumer_socket *socket;
- if (!reg->registry->reg.ust->metadata_key) {
- /* Skip since no metadata is present */
- continue;
- }
-
/* Get consumer socket to use to push the metadata.*/
socket = consumer_find_socket_by_bitness(reg->bits_per_long,
usess->consumer);
}
}
+ /*
+ * The metadata channel might not be present.
+ *
+ * Consumer stream allocation can be done
+ * asynchronously and can fail on intermediary
+ * operations (i.e add context) and lead to data
+ * channels created with no metadata channel.
+ */
+ if (!reg->registry->reg.ust->metadata_key) {
+ /* Skip since no metadata is present. */
+ continue;
+ }
+
(void) push_metadata(reg->registry->reg.ust, usess->consumer);
ret = consumer_rotate_channel(socket,