Various fixes for prototype branch notification-prototype
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 9 Mar 2017 03:45:01 +0000 (22:45 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 9 Mar 2017 03:48:35 +0000 (22:48 -0500)
14 files changed:
include/lttng/condition/buffer-usage-internal.h
include/lttng/condition/buffer-usage.h
include/lttng/condition/condition-internal.h
include/lttng/condition/condition.h
include/lttng/condition/evaluation-internal.h
include/lttng/notification/channel.h
include/lttng/notification/notification-internal.h
include/lttng/trigger/trigger-internal.h
include/lttng/trigger/trigger.h
src/common/buffer-usage.c
src/common/condition.c
src/common/evaluation.c
src/common/notification.c
src/common/trigger.c

index bac144bc6015ede97586b0e9191214c551d1e5bb..8c725240b908f271f478d2a64bba94ab30b51cac 100644 (file)
@@ -25,7 +25,6 @@
 
 struct lttng_condition_buffer_usage {
        struct lttng_condition parent;
-       bool frozen;
        struct {
                bool set;
                uint64_t value;
@@ -33,7 +32,7 @@ struct lttng_condition_buffer_usage {
        struct {
                bool set;
                double value;
-       } threshold_percent;
+       } threshold_ratio;
        char *session_name;
        char *channel_name;
        struct {
@@ -44,10 +43,13 @@ struct lttng_condition_buffer_usage {
 
 struct lttng_condition_buffer_usage_comm {
        uint8_t threshold_set_in_bytes;
-       union {
-               double percent;
-               uint64_t bytes;
-       } threshold;
+       /*
+        * Expressed in bytes if "threshold_set_in_bytes" is not 0.
+        * Otherwise, it is expressed a ratio in the interval [0.0, 1.0]
+        * that is mapped to the range on a 64-bit unsigned integer.
+        * The ratio is obtained by (threshold / UINT64_MAX).
+        */
+       uint64_t threshold;
        /* Both lengths include the trailing \0. */
        uint32_t session_name_len;
        uint32_t channel_name_len;
@@ -63,8 +65,14 @@ struct lttng_evaluation_buffer_usage {
        uint64_t buffer_capacity;
 };
 
+struct lttng_evaluation_buffer_usage_comm {
+       uint64_t buffer_use;
+       uint64_t buffer_capacity;
+} LTTNG_PACKED;
+
 LTTNG_HIDDEN
-struct lttng_evaluation *lttng_evaluation_buffer_usage_create(uint64_t use,
+struct lttng_evaluation *lttng_evaluation_buffer_usage_create(
+               enum lttng_condition_type type, uint64_t use,
                uint64_t capacity);
 
 LTTNG_HIDDEN
@@ -75,4 +83,14 @@ LTTNG_HIDDEN
 ssize_t lttng_condition_buffer_usage_high_create_from_buffer(const char *buf,
                struct lttng_condition **condition);
 
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_buffer_usage_low_create_from_buffer(const char *buf,
+               struct lttng_evaluation **evaluation);
+
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_buffer_usage_high_create_from_buffer(const char *buf,
+               struct lttng_evaluation **evaluation);
+
+
+
 #endif /* LTTNG_CONDITION_BUFFER_USAGE_INTERNAL_H */
index 7c8834eab72d209b6176ace8cb5d0fdc3da5cca8..fc06ee10e2a615ed29ad12f44b754a83c1586844 100644 (file)
@@ -31,17 +31,17 @@ lttng_condition_buffer_usage_low_create(void);
 extern struct lttng_condition *
 lttng_condition_buffer_usage_high_create(void);
 
-/* threshold_percent expressed as [0.0, 1.0]. */
+/* threshold_ratio expressed as [0.0, 1.0]. */
 extern enum lttng_condition_status
-lttng_condition_buffer_usage_get_threshold_percentage(
+lttng_condition_buffer_usage_get_threshold_ration(
                struct lttng_condition *condition,
-               double *threshold_percent);
+               double *threshold_ratio);
 
-/* threshold_percent expressed as [0.0, 1.0]. */
+/* threshold_ratio expressed as [0.0, 1.0]. */
 extern enum lttng_condition_status
-lttng_condition_buffer_usage_set_threshold_percentage(
+lttng_condition_buffer_usage_set_threshold_ratio(
                struct lttng_condition *condition,
-               double threshold_percent);
+               double threshold_ratio);
 
 extern enum lttng_condition_status
 lttng_condition_buffer_usage_get_threshold(
@@ -86,9 +86,9 @@ lttng_condition_buffer_usage_set_domain_type(
 
 /* LTTng Condition Evaluation */
 extern enum lttng_evaluation_status
-lttng_evaluation_buffer_usage_get_usage_percentage(
+lttng_evaluation_buffer_usage_get_usage_ratio(
                struct lttng_evaluation *evaluation,
-               double *usage_percent);
+               double *usage_ratio);
 
 extern enum lttng_evaluation_status
 lttng_evaluation_buffer_usage_get_usage(
index 652b4369cceeb8847fc66ccb19fc88b2c409a7f5..5cf12fb7a5eb47c5a353acc8435113beaa84f000 100644 (file)
@@ -27,11 +27,14 @@ typedef void (*condition_destroy_cb)(struct lttng_condition *condition);
 typedef bool (*condition_validate_cb)(struct lttng_condition *condition);
 typedef ssize_t (*condition_serialize_cb)(struct lttng_condition *condition,
                char *buf);
+typedef bool (*condition_equal_cb)(struct lttng_condition *a,
+               struct lttng_condition *b);
 
 struct lttng_condition {
        enum lttng_condition_type type;
        condition_validate_cb validate;
        condition_serialize_cb serialize;
+       condition_equal_cb equal;
        condition_destroy_cb destroy;
        struct cds_list_head list_node;
 };
@@ -39,6 +42,7 @@ struct lttng_condition {
 struct lttng_condition_comm {
        /* enum lttng_condition_type */
        int8_t condition_type;
+       char payload[];
 };
 
 LTTNG_HIDDEN
@@ -53,6 +57,10 @@ ssize_t lttng_condition_create_from_buffer(const char *buf,
                struct lttng_condition **condition);
 
 LTTNG_HIDDEN
-ssize_t lttng_condition_serialize(struct lttng_condition *action, char *buf);
+ssize_t lttng_condition_serialize(struct lttng_condition *condition, char *buf);
+
+LTTNG_HIDDEN
+bool lttng_condition_is_equal(struct lttng_condition *a,
+               struct lttng_condition *b);
 
 #endif /* LTTNG_CONDITION_INTERNAL_H */
index 9830dbfb1b583f4748a85d120209305b3ce6b4e9..177b4ab83f5d0b012d2575531fdf4d9c8d7e418a 100644 (file)
@@ -28,8 +28,8 @@ struct lttng_condition;
 
 enum lttng_condition_type {
        LTTNG_CONDITION_TYPE_UNKNOWN = -1,
-       LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW = 0,
-       LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH = 1,
+       LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW = 102,
+       LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH = 101,
 };
 
 enum lttng_condition_status {
index e73411d5c844e162602b6174d0378ae902afdeb6..f52707ca77dfe50a3e15bc12a69ae0e9d024e96b 100644 (file)
 #include <stdbool.h>
 
 typedef void (*evaluation_destroy_cb)(struct lttng_evaluation *evaluation);
+typedef ssize_t (*evaluation_serialize_cb)(struct lttng_evaluation *evaluation,
+               char *buf);
 
 struct lttng_evaluation_comm {
        /* enum lttng_condition_type type */
        int8_t type;
+       char payload[];
 } LTTNG_PACKED;
 
 struct lttng_evaluation {
        enum lttng_condition_type type;
+       evaluation_serialize_cb serialize;
        evaluation_destroy_cb destroy;
 };
 
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_create_from_buffer(const char *buf,
+               struct lttng_evaluation **evaluation);
+
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_serialize(struct lttng_evaluation *evaluation,
+               char *buf);
+
 #endif /* LTTNG_EVALUATION_INTERNAL_H */
index b1c2d6af50e790e25dfd0af52f4a9253d84599ca..5e6ba9651ef196ccb38228b5b9788dec6e90302f 100644 (file)
@@ -29,12 +29,12 @@ struct lttng_notification_channel;
 
 /* LTTng Notification channel */
 enum lttng_notification_channel_status {
-       LTTNG_NOTIFICATION_CHANNEL_STATUS_TIMEOUT = 2,
        LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED = 1,
        LTTNG_NOTIFICATION_CHANNEL_STATUS_OK = 0,
        LTTNG_NOTIFICATION_CHANNEL_STATUS_ERROR = -1,
        LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED = -2,
-       LTTNG_NOTIFICATION_CHANNEL_STATUS_NOT_FOUND = -3,
+       /* Condition unknown. */
+       LTTNG_NOTIFICATION_CHANNEL_STATUS_UNKNOWN = -3,
        LTTNG_NOTIFICATION_CHANNEL_STATUS_UNSUPPORTED = -4,
        LTTNG_NOTIFICATION_CHANNEL_STATUS_INVALID = -5,
 };
@@ -45,8 +45,7 @@ extern struct lttng_notification_channel *lttng_notification_channel_create(
 extern enum lttng_notification_channel_status
 lttng_notification_channel_get_next_notification(
                struct lttng_notification_channel *channel,
-               struct lttng_notification **notification,
-               unsigned int timeout_ms);
+               struct lttng_notification **notification);
 
 extern enum lttng_notification_channel_status
 lttng_notification_channel_subscribe(
index d37db1ee5cd57c49815e8cffa630b75f3e1bbaff..fc213ac048d9f8e6168e0950d9a0e77a8a00762f 100644 (file)
 
 #include <lttng/notification/notification.h>
 #include <common/macros.h>
+#include <stdint.h>
 
 struct lttng_notification {
        struct lttng_condition *condition;
        struct lttng_evaluation *evaluation;
 };
 
+struct lttng_notification_comm {
+       /* length excludes its own length. */
+       uint32_t length;
+       /* A condition and evaluation object follow. */
+       char payload[];
+} LTTNG_PACKED;
+
 LTTNG_HIDDEN
 struct lttng_notification *lttng_notification_create(
                struct lttng_condition *condition,
                struct lttng_evaluation *evaluation);
 
+LTTNG_HIDDEN
+ssize_t lttng_notification_serialize(struct lttng_notification *notification,
+               char *buf);
+
+LTTNG_HIDDEN
+ssize_t lttng_notification_create_from_buffer(const char *buf,
+               struct lttng_notification **notification);
+
 #endif /* LTTNG_NOTIFICATION_INTERNAL_H */
index 4d90fe84fcdfb6322b34342cf768d70bdf32a332..5f37057b814b9509d8d74c2f45f17dd18b4e605d 100644 (file)
@@ -32,8 +32,10 @@ struct lttng_trigger {
 };
 
 struct lttng_trigger_comm {
-       /* len excludes its own length. */
-       uint32_t len;
+       /* length excludes its own length. */
+       uint32_t length;
+       /* A condition and action object follow. */
+       char payload[];
 } LTTNG_PACKED;
 
 LTTNG_HIDDEN
index ea9c16edf41d66552fa23f0003c59df13b9b2b77..29d42c987fc774833ceded96cf957e9e8ac3dac2 100644 (file)
@@ -21,7 +21,6 @@
 struct lttng_action;
 struct lttng_condition;
 struct lttng_trigger;
-struct lttng_endpoint;
 
 #ifdef __cplusplus
 extern "C" {
@@ -36,6 +35,12 @@ enum lttng_register_trigger_status {
 extern struct lttng_trigger *lttng_trigger_create(
                struct lttng_condition *condition, struct lttng_action *action);
 
+extern struct lttng_condition *lttng_trigger_get_condition(
+               struct lttng_trigger *trigger);
+
+extern struct lttng_action *lttng_trigger_get_action(
+               struct lttng_trigger *trigger);
+
 extern void lttng_trigger_destroy(struct lttng_trigger *trigger);
 
 extern int lttng_register_trigger(struct lttng_trigger *trigger);
index 66449c3139113db69676f5702ef150a9a0c35b0f..c541d34ed46204d7b87b4570823003f19c377de7 100644 (file)
 #include <common/macros.h>
 #include <common/error.h>
 #include <assert.h>
+#include <math.h>
+#include <float.h>
+
+static
+double fixed_to_double(uint64_t val)
+{
+       return (double) val / (double) UINT64_MAX;
+}
+
+static
+uint64_t double_to_fixed(double val)
+{
+       return (val * (double) UINT64_MAX);
+}
 
 static
 bool is_usage_condition(struct lttng_condition *condition)
@@ -72,7 +86,7 @@ bool lttng_condition_buffer_usage_validate(struct lttng_condition *condition)
                ERR("Invalid buffer condition: a target channel name must be set.");
                goto end;
        }
-       if (!usage->threshold_percent.set && !usage->threshold_bytes.set) {
+       if (!usage->threshold_ratio.set && !usage->threshold_bytes.set) {
                ERR("Invalid buffer condition: a threshold must be set.");
                goto end;
        }
@@ -111,11 +125,10 @@ ssize_t lttng_condition_buffer_usage_serialize(struct lttng_condition *condition
                };
 
                if (usage->threshold_bytes.set) {
-                       usage_comm.threshold.bytes =
-                                       usage->threshold_bytes.value;
+                       usage_comm.threshold = usage->threshold_bytes.value;
                } else {
-                       usage_comm.threshold.percent =
-                                       usage->threshold_percent.value;
+                       usage_comm.threshold = double_to_fixed(
+                                       usage->threshold_ratio.value);
                }
 
                memcpy(buf, &usage_comm, sizeof(usage_comm));
@@ -129,6 +142,76 @@ end:
        return size;
 }
 
+static
+bool lttng_condition_buffer_usage_is_equal(struct lttng_condition *_a,
+               struct lttng_condition *_b)
+{
+       bool is_equal = false;
+       struct lttng_condition_buffer_usage *a, *b;
+
+       a = container_of(_a, struct lttng_condition_buffer_usage, parent);
+       b = container_of(_b, struct lttng_condition_buffer_usage, parent);
+
+       if ((a->threshold_ratio.set && !b->threshold_ratio.set) ||
+                       (a->threshold_bytes.set && !b->threshold_bytes.set)) {
+               goto end;
+       }
+
+       if (a->threshold_ratio.set && b->threshold_ratio.set) {
+               double a_value, b_value, diff;
+
+               a_value = a->threshold_ratio.value;
+               b_value = b->threshold_ratio.value;
+               diff = fabs(a_value - b_value);
+
+               if (diff > DBL_EPSILON) {
+                       goto end;
+               }
+       } else if (a->threshold_bytes.set && b->threshold_bytes.set) {
+               uint64_t a_value, b_value;
+
+               a_value = a->threshold_bytes.value;
+               b_value = b->threshold_bytes.value;
+               if (a_value != b_value) {
+                       goto end;
+               }
+       }
+
+       if ((a->session_name && !b->session_name) ||
+                       (!a->session_name && b->session_name)) {
+               goto end;
+       }
+
+       if (a->channel_name && b->channel_name) {
+               if (strcmp(a->channel_name, b->channel_name)) {
+                       goto end;
+               }
+       }       if ((a->channel_name && !b->channel_name) ||
+                       (!a->channel_name && b->channel_name)) {
+               goto end;
+       }
+
+       if (a->channel_name && b->channel_name) {
+               if (strcmp(a->channel_name, b->channel_name)) {
+                       goto end;
+               }
+       }
+
+       if ((a->domain.set && !b->domain.set) ||
+                       (!a->domain.set && b->domain.set)) {
+               goto end;
+       }
+
+       if (a->domain.set && b->domain.set) {
+               if (a->domain.type != b->domain.type) {
+                       goto end;
+               }
+       }
+       is_equal = true;
+end:
+       return is_equal;
+}
+
 static
 struct lttng_condition *lttng_condition_buffer_usage_create(
                enum lttng_condition_type type)
@@ -143,6 +226,7 @@ struct lttng_condition *lttng_condition_buffer_usage_create(
        lttng_condition_init(&condition->parent, type);
        condition->parent.validate = lttng_condition_buffer_usage_validate;
        condition->parent.serialize = lttng_condition_buffer_usage_serialize;
+       condition->parent.equal = lttng_condition_buffer_usage_is_equal;
        condition->parent.destroy = lttng_condition_buffer_usage_destroy;
 end:
        return &condition->parent;
@@ -161,7 +245,8 @@ struct lttng_condition *lttng_condition_buffer_usage_high_create(void)
 }
 
 static
-ssize_t init_from_buffer(struct lttng_condition *condition, const char *buf)
+ssize_t init_condition_from_buffer(struct lttng_condition *condition,
+               const char *buf)
 {
        ssize_t ret, condition_size;
        enum lttng_condition_status status;
@@ -172,10 +257,11 @@ ssize_t init_from_buffer(struct lttng_condition *condition, const char *buf)
 
        if (condition_comm->threshold_set_in_bytes) {
                status = lttng_condition_buffer_usage_set_threshold(condition,
-                               condition_comm->threshold.bytes);
+                               condition_comm->threshold);
        } else {
-               status = lttng_condition_buffer_usage_set_threshold_percentage(
-                               condition, condition_comm->threshold.percent);
+               status = lttng_condition_buffer_usage_set_threshold_ratio(
+                               condition,
+                               fixed_to_double(condition_comm->threshold));
        }
        if (status != LTTNG_CONDITION_STATUS_OK) {
                ERR("Failed to initialize buffer usage condition threshold");
@@ -246,8 +332,7 @@ ssize_t lttng_condition_buffer_usage_low_create_from_buffer(const char *buf,
                goto error;
        }
 
-       DBG("Initializing low buffer usage condition from buffer");
-       ret = init_from_buffer(condition, buf);
+       ret = init_condition_from_buffer(condition, buf);
        if (ret < 0) {
                goto error;
        }
@@ -272,8 +357,7 @@ ssize_t lttng_condition_buffer_usage_high_create_from_buffer(const char *buf,
                goto error;
        }
 
-       DBG("Initializing high buffer usage condition from buffer");
-       ret = init_from_buffer(condition, buf);
+       ret = init_condition_from_buffer(condition, buf);
        if (ret < 0) {
                goto error;
        }
@@ -285,49 +369,115 @@ error:
        return ret;
 }
 
+static
+struct lttng_evaluation *create_evaluation_from_buffer(
+               enum lttng_condition_type type, const char *buf)
+{
+       struct lttng_evaluation_buffer_usage_comm *comm =
+                       (struct lttng_evaluation_buffer_usage_comm *) buf;
+       struct lttng_evaluation *evaluation;
+
+       evaluation = lttng_evaluation_buffer_usage_create(type,
+                       comm->buffer_use, comm->buffer_capacity);
+       return evaluation;
+}
+
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_buffer_usage_low_create_from_buffer(const char *buf,
+               struct lttng_evaluation **_evaluation)
+{
+       ssize_t ret;
+       struct lttng_evaluation *evaluation;
+
+       if (!_evaluation) {
+               ret = -1;
+               goto error;
+       }
+
+       evaluation = create_evaluation_from_buffer(
+                       LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW, buf);
+       if (!evaluation) {
+               goto error;
+       }
+
+       *_evaluation = evaluation;
+       ret = sizeof(struct lttng_evaluation_buffer_usage_comm);
+       return ret;
+error:
+       lttng_evaluation_destroy(evaluation);
+       return ret;
+}
+
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_buffer_usage_high_create_from_buffer(const char *buf,
+               struct lttng_evaluation **_evaluation)
+{
+       ssize_t ret;
+       struct lttng_evaluation *evaluation;
+
+       if (!_evaluation) {
+               ret = -1;
+               goto error;
+       }
+
+       evaluation = create_evaluation_from_buffer(
+                       LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH, buf);
+       if (!evaluation) {
+               goto error;
+       }
+
+       *_evaluation = evaluation;
+       ret = sizeof(struct lttng_evaluation_buffer_usage_comm);
+       return ret;
+error:
+       lttng_evaluation_destroy(evaluation);
+       return ret;
+}
+
 enum lttng_condition_status
-lttng_condition_buffer_usage_get_threshold_percentage(
-               struct lttng_condition *condition, double *threshold_percent)
+lttng_condition_buffer_usage_get_threshold_ratio(
+               struct lttng_condition *condition, double *threshold_ratio)
 {
        struct lttng_condition_buffer_usage *usage;
        enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
 
        if (!condition || !is_usage_condition(condition) ||
-                       !threshold_percent) {
+                       !threshold_ratio) {
                status = LTTNG_CONDITION_STATUS_INVALID;
                goto end;
        }
 
        usage = container_of(condition, struct lttng_condition_buffer_usage,
                        parent);
-       if (!usage->threshold_percent.set) {
+       if (!usage->threshold_ratio.set) {
                status = LTTNG_CONDITION_STATUS_UNSET;
                goto end;
        }
-       *threshold_percent = usage->threshold_percent.value;
+       *threshold_ratio = usage->threshold_ratio.value;
 end:
        return status;
 }
 
-/* threshold_percent expressed as [0.0, 1.0]. */
+/* threshold_ratio expressed as [0.0, 1.0]. */
 enum lttng_condition_status
-lttng_condition_buffer_usage_set_threshold_percentage(
-               struct lttng_condition *condition, double threshold_percent)
+lttng_condition_buffer_usage_set_threshold_ratio(
+               struct lttng_condition *condition, double threshold_ratio)
 {
        struct lttng_condition_buffer_usage *usage;
        enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
 
        if (!condition || !is_usage_condition(condition) ||
-               threshold_percent < 0.0 || threshold_percent > 1.0) {
+                       threshold_ratio < 0.0 ||
+                       threshold_ratio > 1.0) {
                status = LTTNG_CONDITION_STATUS_INVALID;
                goto end;
        }
 
        usage = container_of(condition, struct lttng_condition_buffer_usage,
                        parent);
-       usage->threshold_percent.set = true;
+       usage->threshold_ratio.set = true;
        usage->threshold_bytes.set = false;
-       usage->threshold_percent.value = threshold_percent;
+       usage->threshold_ratio.value = threshold_ratio;
 end:
        return status;
 }
@@ -369,7 +519,7 @@ lttng_condition_buffer_usage_set_threshold(
 
        usage = container_of(condition, struct lttng_condition_buffer_usage,
                        parent);
-       usage->threshold_percent.set = false;
+       usage->threshold_ratio.set = false;
        usage->threshold_bytes.set = true;
        usage->threshold_bytes.value = threshold_bytes;
 end:
@@ -403,6 +553,7 @@ extern enum lttng_condition_status
 lttng_condition_buffer_usage_set_session_name(
                struct lttng_condition *condition, const char *session_name)
 {
+       char *session_name_copy;
        struct lttng_condition_buffer_usage *usage;
        enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
 
@@ -414,11 +565,16 @@ lttng_condition_buffer_usage_set_session_name(
 
        usage = container_of(condition, struct lttng_condition_buffer_usage,
                        parent);
-       usage->session_name = strdup(session_name);
-       if (!usage->session_name) {
+       session_name_copy = strdup(session_name);
+       if (!session_name_copy) {
                status = LTTNG_CONDITION_STATUS_ERROR;
                goto end;
        }
+
+       if (usage->session_name) {
+               free(usage->session_name);
+       }
+       usage->session_name = session_name_copy;
 end:
        return status;
 }
@@ -450,6 +606,7 @@ extern enum lttng_condition_status
 lttng_condition_buffer_usage_set_channel_name(
                struct lttng_condition *condition, const char *channel_name)
 {
+       char *channel_name_copy;
        struct lttng_condition_buffer_usage *usage;
        enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
 
@@ -461,11 +618,16 @@ lttng_condition_buffer_usage_set_channel_name(
 
        usage = container_of(condition, struct lttng_condition_buffer_usage,
                        parent);
-       usage->channel_name = strdup(channel_name);
-       if (!usage->channel_name) {
+       channel_name_copy = strdup(channel_name);
+       if (!channel_name_copy) {
                status = LTTNG_CONDITION_STATUS_ERROR;
                goto end;
        }
+
+       if (usage->channel_name) {
+               free(usage->channel_name);
+       }
+       usage->channel_name = channel_name_copy;
 end:
        return status;
 }
@@ -514,6 +676,28 @@ end:
        return status;
 }
 
+static
+ssize_t lttng_evaluation_buffer_usage_serialize(
+               struct lttng_evaluation *evaluation, char *buf)
+{
+       ssize_t ret;
+       struct lttng_evaluation_buffer_usage *usage;
+
+       usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
+                       parent);
+       if (buf) {
+               struct lttng_evaluation_buffer_usage_comm comm = {
+                       .buffer_use = usage->buffer_use,
+                       .buffer_capacity = usage->buffer_capacity,
+               };
+
+               memcpy(buf, &comm, sizeof(comm));
+       }
+
+       ret = sizeof(struct lttng_evaluation_buffer_usage_comm);
+       return ret;
+}
+
 static
 void lttng_evaluation_buffer_usage_destroy(
                struct lttng_evaluation *evaluation)
@@ -526,8 +710,8 @@ void lttng_evaluation_buffer_usage_destroy(
 }
 
 LTTNG_HIDDEN
-struct lttng_evaluation *lttng_evaluation_buffer_usage_create(uint64_t use,
-               uint64_t capacity)
+struct lttng_evaluation *lttng_evaluation_buffer_usage_create(
+               enum lttng_condition_type type, uint64_t use, uint64_t capacity)
 {
        struct lttng_evaluation_buffer_usage *usage;
 
@@ -536,8 +720,10 @@ struct lttng_evaluation *lttng_evaluation_buffer_usage_create(uint64_t use,
                goto end;
        }
 
+       usage->parent.type = type;
        usage->buffer_use = use;
        usage->buffer_capacity = capacity;
+       usage->parent.serialize = lttng_evaluation_buffer_usage_serialize;
        usage->parent.destroy = lttng_evaluation_buffer_usage_destroy;
 end:
        return &usage->parent;
@@ -548,20 +734,20 @@ end:
  * evaluate to "true".
  */
 enum lttng_evaluation_status
-lttng_evaluation_buffer_usage_get_usage_percentage(
-               struct lttng_evaluation *evaluation, double *usage_percent)
+lttng_evaluation_buffer_usage_get_usage_ratio(
+               struct lttng_evaluation *evaluation, double *usage_ratio)
 {
        struct lttng_evaluation_buffer_usage *usage;
        enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
 
-       if (!evaluation || !is_usage_evaluation(evaluation) || !usage_percent) {
+       if (!evaluation || !is_usage_evaluation(evaluation) || !usage_ratio) {
                status = LTTNG_EVALUATION_STATUS_INVALID;
                goto end;
        }
 
        usage = container_of(evaluation, struct lttng_evaluation_buffer_usage,
                        parent);
-       *usage_percent = (double) usage->buffer_use /
+       *usage_ratio = (double) usage->buffer_use /
                        (double) usage->buffer_capacity;
 end:
        return status;
index 4a24202fed6f851e309344471e3664d599045f42..6ee931ec6a4cdcade37e79aac68dd7790ed04f23 100644 (file)
@@ -87,6 +87,25 @@ end:
        return ret;
 }
 
+LTTNG_HIDDEN
+bool lttng_condition_is_equal(struct lttng_condition *a,
+               struct lttng_condition *b)
+{
+       bool is_equal = false;
+
+       if (!a || !b) {
+               goto end;
+       }
+
+       if (a->type != b->type) {
+               goto end;
+       }
+
+       is_equal = a->equal ? a->equal(a, b) : true;
+end:
+       return is_equal;
+}
+
 LTTNG_HIDDEN
 ssize_t lttng_condition_create_from_buffer(const char *buf,
                struct lttng_condition **condition)
@@ -104,7 +123,7 @@ ssize_t lttng_condition_create_from_buffer(const char *buf,
        condition_size += sizeof(*condition_comm);
        buf += condition_size;
 
-       switch (condition_comm->condition_type) {
+       switch ((enum lttng_condition_type) condition_comm->condition_type) {
        case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
                ret = lttng_condition_buffer_usage_low_create_from_buffer(buf,
                                condition);
index 41e59c1d530587d5527faefd6376671980a5a9c4..49cba5dd18fa999761ed8567d6637e0093021f98 100644 (file)
  */
 
 #include <lttng/condition/evaluation-internal.h>
+#include <lttng/condition/buffer-usage-internal.h>
 #include <common/macros.h>
+#include <common/error.h>
 #include <stdbool.h>
 #include <assert.h>
 
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_serialize(struct lttng_evaluation *evaluation,
+               char *buf)
+{
+       ssize_t ret, offset = 0;
+       struct lttng_evaluation_comm evaluation_comm;
+
+       evaluation_comm.type = (int8_t) evaluation->type;
+       if (buf) {
+               memcpy(buf, &evaluation_comm, sizeof(evaluation_comm));
+       }
+       offset += sizeof(evaluation_comm);
+
+       if (evaluation->serialize) {
+               ret = evaluation->serialize(evaluation,
+                               buf ? (buf + offset) : NULL);
+               if (ret < 0) {
+                       goto end;
+               }
+               offset += ret;
+       }
+
+       ret = offset;
+end:
+       return ret;
+}
+
+LTTNG_HIDDEN
+ssize_t lttng_evaluation_create_from_buffer(const char *buf,
+               struct lttng_evaluation **evaluation)
+{
+       ssize_t ret, evaluation_size = 0;
+       struct lttng_evaluation_comm *evaluation_comm =
+                       (struct lttng_evaluation_comm *) buf;
+
+       if (!buf || !evaluation) {
+               ret = -1;
+               goto end;
+       }
+
+       evaluation_size += sizeof(*evaluation_comm);
+       buf += evaluation_size;
+
+       switch ((enum lttng_condition_type) evaluation_comm->type) {
+       case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
+               ret = lttng_evaluation_buffer_usage_low_create_from_buffer(buf,
+                               evaluation);
+               if (ret < 0) {
+                       goto end;
+               }
+               evaluation_size += ret;
+               break;
+       case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
+               ret = lttng_evaluation_buffer_usage_high_create_from_buffer(buf,
+                               evaluation);
+               if (ret < 0) {
+                       goto end;
+               }
+               evaluation_size += ret;
+               break;
+       default:
+               ERR("Attempted to create evaluation of unknown type (%i)",
+                               (int) evaluation_comm->type);
+               ret = -1;
+               goto end;
+       }
+       ret = evaluation_size;
+end:
+       return ret;
+}
+
 enum lttng_condition_type lttng_evaluation_get_type(
                struct lttng_evaluation *evaluation)
 {
index 4d9640613d5547ce930d5d84744689fd15751d4d..a41de7e6ff7606ccd692e2ec22b7fa2c6a23650c 100644 (file)
@@ -16,6 +16,8 @@
  */
 
 #include <lttng/notification/notification-internal.h>
+#include <lttng/condition/condition-internal.h>
+#include <lttng/condition/evaluation-internal.h>
 #include <lttng/condition/condition.h>
 #include <lttng/condition/evaluation.h>
 #include <assert.h>
@@ -42,6 +44,101 @@ end:
        return notification;
 }
 
+LTTNG_HIDDEN
+ssize_t lttng_notification_serialize(struct lttng_notification *notification,
+               char *buf)
+{
+       ssize_t ret, condition_size, evaluation_size, offset = 0;
+       struct lttng_notification_comm notification_comm;
+
+       if (!notification) {
+               ret = -1;
+               goto end;
+       }
+
+       offset += sizeof(notification_comm);
+       condition_size = lttng_condition_serialize(notification->condition,
+                       buf ? (buf + offset) : NULL);
+       if (condition_size < 0) {
+               ret = condition_size;
+               goto end;
+       }
+       offset += condition_size;
+
+       evaluation_size = lttng_evaluation_serialize(notification->evaluation,
+                       buf ? (buf + offset) : NULL);
+       if (evaluation_size < 0) {
+               ret = evaluation_size;
+               goto end;
+       }
+       offset += evaluation_size;
+
+       if (buf) {
+               notification_comm.length =
+                               (uint32_t) (condition_size + evaluation_size);
+               memcpy(buf, &notification_comm, sizeof(notification_comm));
+       }
+       ret = offset;
+end:
+       return ret;
+
+}
+
+LTTNG_HIDDEN
+ssize_t lttng_notification_create_from_buffer(const char *buf,
+               struct lttng_notification **notification)
+{
+       ssize_t ret, offset = 0, condition_size, evaluation_size;
+       struct lttng_notification_comm *notification_comm;
+       struct lttng_condition *condition;
+       struct lttng_evaluation *evaluation;
+
+       if (!buf || !notification) {
+               ret = -1;
+               goto end;
+       }
+
+       notification_comm = (struct lttng_notification_comm *) buf;
+       offset += sizeof(*notification_comm);
+
+       /* struct lttng_condition */
+       condition_size = lttng_condition_create_from_buffer(buf + offset,
+                       &condition);
+       if (condition_size < 0) {
+               ret = condition_size;
+               goto end;
+       }
+       offset += condition_size;
+
+       /* struct lttng_evaluation */
+       evaluation_size = lttng_evaluation_create_from_buffer(buf + offset,
+                       &evaluation);
+       if (evaluation_size < 0) {
+               ret = evaluation_size;
+               goto end;
+       }
+       offset += evaluation_size;
+
+       /* Unexpected size of inner-elements; the buffer is corrupted. */
+       if ((ssize_t) notification_comm->length !=
+                       condition_size + evaluation_size) {
+               ret = -1;
+               goto error;
+       }
+
+       *notification = lttng_notification_create(condition, evaluation);
+       if (!*notification) {
+               goto error;
+       }
+       ret = offset;
+end:
+       return ret;
+error:
+       lttng_condition_destroy(condition);
+       lttng_evaluation_destroy(evaluation);
+       return ret;
+}
+
 void lttng_notification_destroy(struct lttng_notification *notification)
 {
        if (!notification) {
index ede1ac567dad043627d6ea71b070eab8c12969ec..21b527f3b404a9412191eba40efe2ce775e3cc58 100644 (file)
@@ -59,6 +59,18 @@ end:
        return trigger;
 }
 
+struct lttng_condition *lttng_trigger_get_condition(
+               struct lttng_trigger *trigger)
+{
+       return trigger ? trigger->condition : NULL;
+}
+
+extern struct lttng_action *lttng_trigger_get_action(
+               struct lttng_trigger *trigger)
+{
+       return trigger ? trigger->action : NULL;
+}
+
 void lttng_trigger_destroy(struct lttng_trigger *trigger)
 {
        if (!trigger) {
@@ -74,34 +86,48 @@ LTTNG_HIDDEN
 ssize_t lttng_trigger_create_from_buffer(const char *buf,
                struct lttng_trigger **trigger)
 {
-       ssize_t ret, trigger_size;
+       ssize_t ret, offset = 0, condition_size, action_size;
        struct lttng_condition *condition = NULL;
        struct lttng_action *action = NULL;
+       struct lttng_trigger_comm *trigger_comm;
 
        if (!buf || !trigger) {
                ret = -1;
                goto end;
        }
 
-       DBG("Deserializing trigger from buffer");
-       ret = lttng_condition_create_from_buffer(buf, &condition);
-       if (ret < 0) {
+       /* lttng_trigger_comm header */
+       trigger_comm = (struct lttng_trigger_comm *) buf;
+       offset += sizeof(*trigger_comm);
+
+       /* struct lttng_condition */
+       condition_size = lttng_condition_create_from_buffer(buf + offset,
+                       &condition);
+       if (condition_size < 0) {
+               ret = condition_size;
                goto end;
        }
+       offset += condition_size;
 
-       trigger_size = ret;
-       buf += ret;
-       ret = lttng_action_create_from_buffer(buf, &action);
-       if (ret < 0) {
+       /* struct lttng_action */
+       action_size = lttng_action_create_from_buffer(buf + offset, &action);
+       if (action_size < 0) {
+               ret = action_size;
                goto end;
        }
+       offset += action_size;
+
+       /* Unexpected size of inner-elements; the buffer is corrupted. */
+       if ((ssize_t) trigger_comm->length != condition_size + action_size) {
+               ret = -1;
+               goto error;
+       }
 
-       trigger_size += ret;
        *trigger = lttng_trigger_create(condition, action);
        if (!*trigger) {
                goto error;
        }
-       ret = trigger_size;
+       ret = offset;
 end:
        return ret;
 error:
@@ -111,49 +137,43 @@ error:
 }
 
 /*
- * Returns the size of a trigger's condition and action.
+ * Returns the size of a trigger (header + condition + action).
  * Both elements are stored contiguously, see their "*_comm" structure
  * for the detailed format.
  */
 LTTNG_HIDDEN
 ssize_t lttng_trigger_serialize(struct lttng_trigger *trigger, char *buf)
 {
-       ssize_t action_size, condition_size, ret;
+       struct lttng_trigger_comm trigger_comm;
+       ssize_t action_size, condition_size, offset = 0, ret;
 
        if (!trigger) {
                ret = -1;
                goto end;
        }
 
-       condition_size = lttng_condition_serialize(trigger->condition, NULL);
+       offset += sizeof(trigger_comm);
+       condition_size = lttng_condition_serialize(trigger->condition,
+                       buf ? (buf + offset) : NULL);
        if (condition_size < 0) {
                ret = -1;
                goto end;
        }
+       offset += condition_size;
 
-       action_size = lttng_action_serialize(trigger->action, NULL);
+       action_size = lttng_action_serialize(trigger->action,
+                       buf ? (buf + offset) : NULL);
        if (action_size < 0) {
                ret = -1;
                goto end;
        }
+       offset += action_size;
 
-       ret = action_size + condition_size;
-       if (!buf) {
-               goto end;
-       }
-
-       condition_size = lttng_condition_serialize(trigger->condition, buf);
-       if (condition_size < 0) {
-               ret = -1;
-               goto end;
-       }
-
-       buf += condition_size;
-       action_size = lttng_action_serialize(trigger->action, buf);
-       if (action_size < 0) {
-               ret = -1;
-               goto end;
+       if (buf) {
+               trigger_comm.length = (uint32_t) (condition_size + action_size);
+               memcpy(buf, &trigger_comm, sizeof(trigger_comm));
        }
+       ret = offset;
 end:
        return ret;
 }
This page took 0.042414 seconds and 5 git commands to generate.