Save filter expression as part of agent events and save them
[lttng-tools.git] / src / bin / lttng-sessiond / ust-app.c
index c30792c3c785e959968dc9c00434c0e12af1ec73..5cc9622f4c444aa41994cf2de22f1fa907731dcf 100644 (file)
@@ -431,6 +431,9 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan,
  * Must be called with the registry lock held.
  *
  * On success, return the len of metadata pushed or else a negative value.
+ * Returning a -EPIPE return value means we could not send the metadata,
+ * but it can be caused by recoverable errors (e.g. the application has
+ * terminated concurrently).
  */
 ssize_t ust_app_push_metadata(struct ust_registry_session *registry,
                struct consumer_socket *socket, int send_zero_data)
@@ -454,9 +457,10 @@ ssize_t ust_app_push_metadata(struct ust_registry_session *registry,
        /*
         * On a push metadata error either the consumer is dead or the
         * metadata channel has been destroyed because its endpoint
-        * might have died (e.g: relayd). If so, the metadata closed
-        * flag is set to 1 so we deny pushing metadata again which is
-        * not valid anymore on the consumer side.
+        * might have died (e.g: relayd), or because the application has
+        * exited. If so, the metadata closed flag is set to 1 so we
+        * deny pushing metadata again which is not valid anymore on the
+        * consumer side.
         */
        if (registry->metadata_closed) {
                return -EPIPE;
@@ -547,6 +551,9 @@ error_push:
  * of socket throughout this function.
  *
  * Return 0 on success else a negative error.
+ * Returning a -EPIPE return value means we could not send the metadata,
+ * but it can be caused by recoverable errors (e.g. the application has
+ * terminated concurrently).
  */
 static int push_metadata(struct ust_registry_session *registry,
                struct consumer_output *consumer)
@@ -973,15 +980,15 @@ error:
  *
  * Return allocated filter or NULL on error.
  */
-static struct lttng_ust_filter_bytecode *alloc_copy_ust_app_filter(
-               struct lttng_ust_filter_bytecode *orig_f)
+static struct lttng_filter_bytecode *copy_filter_bytecode(
+               struct lttng_filter_bytecode *orig_f)
 {
-       struct lttng_ust_filter_bytecode *filter = NULL;
+       struct lttng_filter_bytecode *filter = NULL;
 
        /* Copy filter bytecode */
        filter = zmalloc(sizeof(*filter) + orig_f->len);
        if (!filter) {
-               PERROR("zmalloc alloc ust app filter");
+               PERROR("zmalloc alloc filter bytecode");
                goto error;
        }
 
@@ -991,6 +998,30 @@ error:
        return filter;
 }
 
+/*
+ * Create a liblttng-ust filter bytecode from given bytecode.
+ *
+ * Return allocated filter or NULL on error.
+ */
+static struct lttng_ust_filter_bytecode *create_ust_bytecode_from_bytecode(
+               struct lttng_filter_bytecode *orig_f)
+{
+       struct lttng_ust_filter_bytecode *filter = NULL;
+
+       /* Copy filter bytecode */
+       filter = zmalloc(sizeof(*filter) + orig_f->len);
+       if (!filter) {
+               PERROR("zmalloc alloc ust filter bytecode");
+               goto error;
+       }
+
+       assert(sizeof(struct lttng_filter_bytecode) ==
+                       sizeof(struct lttng_ust_filter_bytecode));
+       memcpy(filter, orig_f, sizeof(*filter) + orig_f->len);
+error:
+       return filter;
+}
+
 /*
  * Find an ust_app using the sock and return it. RCU read side lock must be
  * held before calling this helper function.
@@ -1043,7 +1074,7 @@ error:
  * Return an ust_app_event object or NULL on error.
  */
 static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
-               char *name, struct lttng_ust_filter_bytecode *filter, int loglevel,
+               char *name, struct lttng_filter_bytecode *filter, int loglevel,
                const struct lttng_event_exclusion *exclusion)
 {
        struct lttng_ht_iter iter;
@@ -1059,7 +1090,7 @@ static struct ust_app_event *find_ust_app_event(struct lttng_ht *ht,
        key.filter = filter;
        key.loglevel = loglevel;
        /* lttng_event_exclusion and lttng_ust_event_exclusion structures are similar */
-       key.exclusion = (struct lttng_ust_event_exclusion *)exclusion;
+       key.exclusion = exclusion;
 
        /* Lookup using the event name as hash and a custom match fct. */
        cds_lfht_lookup(ht->ht, ht->hash_fct((void *) name, lttng_ht_seed),
@@ -1124,6 +1155,7 @@ int set_ust_event_filter(struct ust_app_event *ua_event,
                struct ust_app *app)
 {
        int ret;
+       struct lttng_ust_filter_bytecode *ust_bytecode = NULL;
 
        health_code_update();
 
@@ -1132,7 +1164,12 @@ int set_ust_event_filter(struct ust_app_event *ua_event,
                goto error;
        }
 
-       ret = ustctl_set_filter(app->sock, ua_event->filter,
+       ust_bytecode = create_ust_bytecode_from_bytecode(ua_event->filter);
+       if (!ust_bytecode) {
+               ret = -LTTNG_ERR_NOMEM;
+               goto error;
+       }
+       ret = ustctl_set_filter(app->sock, ust_bytecode,
                        ua_event->obj);
        if (ret < 0) {
                if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
@@ -1154,9 +1191,31 @@ int set_ust_event_filter(struct ust_app_event *ua_event,
 
 error:
        health_code_update();
+       free(ust_bytecode);
        return ret;
 }
 
+static
+struct lttng_ust_event_exclusion *create_ust_exclusion_from_exclusion(
+               struct lttng_event_exclusion *exclusion)
+{
+       struct lttng_ust_event_exclusion *ust_exclusion = NULL;
+       size_t exclusion_alloc_size = sizeof(struct lttng_ust_event_exclusion) +
+               LTTNG_UST_SYM_NAME_LEN * exclusion->count;
+
+       ust_exclusion = zmalloc(exclusion_alloc_size);
+       if (!ust_exclusion) {
+               PERROR("malloc");
+               goto end;
+       }
+
+       assert(sizeof(struct lttng_event_exclusion) ==
+                       sizeof(struct lttng_ust_event_exclusion));
+       memcpy(ust_exclusion, exclusion, exclusion_alloc_size);
+end:
+       return ust_exclusion;
+}
+
 /*
  * Set event exclusions on the tracer.
  */
@@ -1165,6 +1224,7 @@ int set_ust_event_exclusion(struct ust_app_event *ua_event,
                struct ust_app *app)
 {
        int ret;
+       struct lttng_ust_event_exclusion *ust_exclusion = NULL;
 
        health_code_update();
 
@@ -1173,8 +1233,13 @@ int set_ust_event_exclusion(struct ust_app_event *ua_event,
                goto error;
        }
 
-       ret = ustctl_set_exclusion(app->sock, ua_event->exclusion,
-                       ua_event->obj);
+       ust_exclusion = create_ust_exclusion_from_exclusion(
+                       ua_event->exclusion);
+       if (!ust_exclusion) {
+               ret = -LTTNG_ERR_NOMEM;
+               goto error;
+       }
+       ret = ustctl_set_exclusion(app->sock, ust_exclusion, ua_event->obj);
        if (ret < 0) {
                if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
                        ERR("UST app event %s exclusions failed for app (pid: %d) "
@@ -1195,6 +1260,7 @@ int set_ust_event_exclusion(struct ust_app_event *ua_event,
 
 error:
        health_code_update();
+       free(ust_exclusion);
        return ret;
 }
 
@@ -1496,13 +1562,13 @@ static void shadow_copy_event(struct ust_app_event *ua_event,
 
        /* Copy filter bytecode */
        if (uevent->filter) {
-               ua_event->filter = alloc_copy_ust_app_filter(uevent->filter);
+               ua_event->filter = copy_filter_bytecode(uevent->filter);
                /* Filter might be NULL here in case of ENONEM. */
        }
 
        /* Copy exclusion data */
        if (uevent->exclusion) {
-               exclusion_alloc_size = sizeof(struct lttng_ust_event_exclusion) +
+               exclusion_alloc_size = sizeof(struct lttng_event_exclusion) +
                                LTTNG_UST_SYM_NAME_LEN * uevent->exclusion->count;
                ua_event->exclusion = zmalloc(exclusion_alloc_size);
                if (ua_event->exclusion == NULL) {
This page took 0.026169 seconds and 4 git commands to generate.