sessiond: setup event notifier group for registering app
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index 8372a5dc51f61b89fa372e13688ccb152258f0c2..b30089dbc2fd6029f590adf8c05752ddda2d3225 100644 (file)
@@ -921,6 +921,28 @@ void delete_ust_app(struct ust_app *app)
        ht_cleanup_push(app->ust_sessions_objd);
        ht_cleanup_push(app->ust_objd);
 
+       /*
+        * This could be NULL if the event notifier setup failed (e.g the app
+        * was killed or the tracer does not support this feature).
+        */
+       if (app->event_notifier_group.object) {
+               enum lttng_error_code ret_code;
+               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,
+                               event_notifier_read_fd);
+               if (ret_code != LTTNG_OK) {
+                       ERR("Failed to remove application tracer event source from notification thread");
+               }
+
+               ustctl_release_object(sock, app->event_notifier_group.object);
+               free(app->event_notifier_group.object);
+       }
+
+       lttng_pipe_destroy(app->event_notifier_group.event_pipe);
+
        /*
         * Wait until we have deleted the application from the sock hash table
         * before closing this socket, otherwise an application could re-use the
@@ -1387,7 +1409,7 @@ error:
 
 static
 struct lttng_ust_event_exclusion *create_ust_exclusion_from_exclusion(
-               struct lttng_event_exclusion *exclusion)
+               const struct lttng_event_exclusion *exclusion)
 {
        struct lttng_ust_event_exclusion *ust_exclusion = NULL;
        size_t exclusion_alloc_size = sizeof(struct lttng_ust_event_exclusion) +
@@ -1409,33 +1431,30 @@ end:
 /*
  * Set event exclusions on the tracer.
  */
-static
-int set_ust_event_exclusion(struct ust_app_event *ua_event,
-               struct ust_app *app)
+static int set_ust_object_exclusions(struct ust_app *app,
+               const struct lttng_event_exclusion *exclusions,
+               struct lttng_ust_object_data *ust_object)
 {
        int ret;
-       struct lttng_ust_event_exclusion *ust_exclusion = NULL;
+       struct lttng_ust_event_exclusion *ust_exclusions = NULL;
 
-       health_code_update();
+       assert(exclusions && exclusions->count > 0);
 
-       if (!ua_event->exclusion || !ua_event->exclusion->count) {
-               ret = 0;
-               goto error;
-       }
+       health_code_update();
 
-       ust_exclusion = create_ust_exclusion_from_exclusion(
-                       ua_event->exclusion);
-       if (!ust_exclusion) {
+       ust_exclusions = create_ust_exclusion_from_exclusion(
+                       exclusions);
+       if (!ust_exclusions) {
                ret = -LTTNG_ERR_NOMEM;
                goto error;
        }
        pthread_mutex_lock(&app->sock_lock);
-       ret = ustctl_set_exclusion(app->sock, ust_exclusion, ua_event->obj);
+       ret = ustctl_set_exclusion(app->sock, ust_exclusions, ust_object);
        pthread_mutex_unlock(&app->sock_lock);
        if (ret < 0) {
                if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-                       ERR("UST app event %s exclusions failed for app (pid: %d) "
-                                       "with ret %d", ua_event->attr.name, app->pid, ret);
+                       ERR("Failed to set UST app exclusions for object %p of app (pid: %d) "
+                                       "with ret %d", ust_object, app->pid, ret);
                } else {
                        /*
                         * This is normal behavior, an application can die during the
@@ -1443,37 +1462,36 @@ int set_ust_event_exclusion(struct ust_app_event *ua_event,
                         * continue normally.
                         */
                        ret = 0;
-                       DBG3("UST app event exclusion failed. Application is dead.");
+                       DBG3("Failed to set UST app object exclusions. Application is dead.");
                }
                goto error;
        }
 
-       DBG2("UST exclusion set successfully for event %s", ua_event->name);
+       DBG2("UST exclusions set successfully for object %p", ust_object);
 
 error:
        health_code_update();
-       free(ust_exclusion);
+       free(ust_exclusions);
        return ret;
 }
 
 /*
  * Disable the specified event on to UST tracer for the UST session.
  */
-static int disable_ust_event(struct ust_app *app,
-               struct ust_app_session *ua_sess, struct ust_app_event *ua_event)
+static int disable_ust_object(struct ust_app *app,
+               struct lttng_ust_object_data *object)
 {
        int ret;
 
        health_code_update();
 
        pthread_mutex_lock(&app->sock_lock);
-       ret = ustctl_disable(app->sock, ua_event->obj);
+       ret = ustctl_disable(app->sock, object);
        pthread_mutex_unlock(&app->sock_lock);
        if (ret < 0) {
                if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-                       ERR("UST app event %s disable failed for app (pid: %d) "
-                                       "and session handle %d with ret %d",
-                                       ua_event->attr.name, app->pid, ua_sess->handle, ret);
+                       ERR("Failed to disable UST app object %p app (pid: %d) with ret %d",
+                                       object, app->pid, ret);
                } else {
                        /*
                         * This is normal behavior, an application can die during the
@@ -1481,13 +1499,13 @@ static int disable_ust_event(struct ust_app *app,
                         * continue normally.
                         */
                        ret = 0;
-                       DBG3("UST app disable event failed. Application is dead.");
+                       DBG3("Failed to disable UST app object. Application is dead.");
                }
                goto error;
        }
 
-       DBG2("UST app event %s disabled successfully for app (pid: %d)",
-                       ua_event->attr.name, app->pid);
+       DBG2("UST app object %p disabled successfully for app (pid: %d)",
+                       object, app->pid);
 
 error:
        health_code_update();
@@ -1575,21 +1593,20 @@ error:
 /*
  * Enable the specified event on to UST tracer for the UST session.
  */
-static int enable_ust_event(struct ust_app *app,
-               struct ust_app_session *ua_sess, struct ust_app_event *ua_event)
+static int enable_ust_object(
+               struct ust_app *app, struct lttng_ust_object_data *ust_object)
 {
        int ret;
 
        health_code_update();
 
        pthread_mutex_lock(&app->sock_lock);
-       ret = ustctl_enable(app->sock, ua_event->obj);
+       ret = ustctl_enable(app->sock, ust_object);
        pthread_mutex_unlock(&app->sock_lock);
        if (ret < 0) {
                if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-                       ERR("UST app event %s enable failed for app (pid: %d) "
-                                       "and session handle %d with ret %d",
-                                       ua_event->attr.name, app->pid, ua_sess->handle, ret);
+                       ERR("UST app enable failed for object %p app (pid: %d) with ret %d",
+                                       ust_object, app->pid, ret);
                } else {
                        /*
                         * This is normal behavior, an application can die during the
@@ -1597,13 +1614,13 @@ static int enable_ust_event(struct ust_app *app,
                         * continue normally.
                         */
                        ret = 0;
-                       DBG3("UST app enable event failed. Application is dead.");
+                       DBG3("Failed to enable UST app object. Application is dead.");
                }
                goto error;
        }
 
-       DBG2("UST app event %s enabled successfully for app (pid: %d)",
-                       ua_event->attr.name, app->pid);
+       DBG2("UST app object %p enabled successfully for app (pid: %d)",
+                       ust_object, app->pid);
 
 error:
        health_code_update();
@@ -1699,8 +1716,8 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess,
 
        ua_event->handle = ua_event->obj->handle;
 
-       DBG2("UST app event %s created successfully for pid:%d",
-                       ua_event->attr.name, app->pid);
+       DBG2("UST app event %s created successfully for pid:%d object: %p",
+                       ua_event->attr.name, app->pid, ua_event->obj);
 
        health_code_update();
 
@@ -1714,7 +1731,7 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess,
 
        /* Set exclusions for the event */
        if (ua_event->exclusion) {
-               ret = set_ust_event_exclusion(ua_event, app);
+               ret = set_ust_object_exclusions(app, ua_event->exclusion, ua_event->obj);
                if (ret < 0) {
                        goto error;
                }
@@ -1726,7 +1743,7 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess,
                 * We now need to explicitly enable the event, since it
                 * is now disabled at creation.
                 */
-               ret = enable_ust_event(app, ua_sess, ua_event);
+               ret = enable_ust_object(app, ua_event->obj);
                if (ret < 0) {
                        /*
                         * If we hit an EPERM, something is wrong with our enable call. If
@@ -2337,7 +2354,7 @@ int enable_ust_app_event(struct ust_app_session *ua_sess,
 {
        int ret;
 
-       ret = enable_ust_event(app, ua_sess, ua_event);
+       ret = enable_ust_object(app, ua_event->obj);
        if (ret < 0) {
                goto error;
        }
@@ -2356,7 +2373,7 @@ static int disable_ust_app_event(struct ust_app_session *ua_sess,
 {
        int ret;
 
-       ret = disable_ust_event(app, ua_sess, ua_event);
+       ret = disable_ust_object(app, ua_event->obj);
        if (ret < 0) {
                goto error;
        }
@@ -3317,6 +3334,7 @@ error:
 struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock)
 {
        struct ust_app *lta = NULL;
+       struct lttng_pipe *event_notifier_event_source_pipe = NULL;
 
        assert(msg);
        assert(sock >= 0);
@@ -3333,12 +3351,21 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock)
                goto error;
        }
 
+       event_notifier_event_source_pipe = lttng_pipe_open(FD_CLOEXEC);
+       if (!event_notifier_event_source_pipe) {
+               PERROR("Failed to open application event source pipe: '%s' (ppid = %d)",
+                               msg->name, msg->ppid);
+               goto error;
+       }
+
        lta = zmalloc(sizeof(struct ust_app));
        if (lta == NULL) {
                PERROR("malloc");
-               goto error;
+               goto error_free_pipe;
        }
 
+       lta->event_notifier_group.event_pipe = event_notifier_event_source_pipe;
+
        lta->ppid = msg->ppid;
        lta->uid = msg->uid;
        lta->gid = msg->gid;
@@ -3376,8 +3403,12 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock)
        lttng_ht_node_init_ulong(&lta->sock_n, (unsigned long) lta->sock);
 
        CDS_INIT_LIST_HEAD(&lta->teardown_head);
-error:
        return lta;
+
+error_free_pipe:
+       lttng_pipe_destroy(event_notifier_event_source_pipe);
+error:
+       return NULL;
 }
 
 /*
@@ -3443,6 +3474,61 @@ int ust_app_version(struct ust_app *app)
        return ret;
 }
 
+/*
+ * Setup the base event notifier group.
+ *
+ * Return 0 on success else a negative value either an errno code or a
+ * LTTng-UST error code.
+ */
+int ust_app_setup_event_notifier_group(struct ust_app *app)
+{
+       int ret;
+       int event_pipe_write_fd;
+       struct lttng_ust_object_data *event_notifier_group = NULL;
+       enum lttng_error_code lttng_ret;
+
+       assert(app);
+
+       /* Get the write side of the pipe. */
+       event_pipe_write_fd = lttng_pipe_get_writefd(
+                       app->event_notifier_group.event_pipe);
+
+       pthread_mutex_lock(&app->sock_lock);
+       ret = ustctl_create_event_notifier_group(app->sock,
+                       event_pipe_write_fd, &event_notifier_group);
+       pthread_mutex_unlock(&app->sock_lock);
+       if (ret < 0) {
+               if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
+                       ERR("Failed to create application event notifier group: ret = %d, app socket fd = %d, event_pipe_write_fd = %d",
+                                       ret, app->sock, event_pipe_write_fd);
+               } else {
+                       DBG("Failed to create application event notifier group (application is dead): app socket fd = %d",
+                                       app->sock);
+               }
+
+               goto error;
+       }
+
+       lttng_ret = notification_thread_command_add_tracer_event_source(
+                       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");
+               ret = - 1;
+               goto error;
+       }
+
+       /* Assign handle only when the complete setup is valid. */
+       app->event_notifier_group.object = event_notifier_group;
+       return ret;
+
+error:
+       ustctl_release_object(app->sock, app->event_notifier_group.object);
+       free(app->event_notifier_group.object);
+       return ret;
+}
+
 /*
  * Unregister app by removing it from the global traceable app list and freeing
  * the data struct.
This page took 0.028682 seconds and 4 git commands to generate.