#include <lttng/condition/condition.h>
#include <lttng/condition/event-rule-internal.h>
#include <lttng/condition/event-rule.h>
+#include <lttng/trigger/trigger-internal.h>
#include <common/sessiond-comm/sessiond-comm.h>
#include "buffer-registry.h"
*
* Return allocated filter or NULL on error.
*/
-static struct lttng_ust_filter_bytecode *create_ust_bytecode_from_bytecode(
- const struct lttng_bytecode *orig_f)
+static struct lttng_ust_filter_bytecode *
+create_ust_filter_bytecode_from_bytecode(const struct lttng_bytecode *orig_f)
{
struct lttng_ust_filter_bytecode *filter = NULL;
- /* Copy filter bytecode */
+ /* Copy filter bytecode. */
filter = zmalloc(sizeof(*filter) + orig_f->len);
if (!filter) {
- PERROR("zmalloc alloc ust filter bytecode");
+ PERROR("Failed to allocate lttng_ust_filter_bytecode: bytecode len = %" PRIu32 " bytes", orig_f->len);
goto error;
}
return filter;
}
+/*
+ * Create a liblttng-ust capture bytecode from given bytecode.
+ *
+ * Return allocated filter or NULL on error.
+ */
+static struct lttng_ust_capture_bytecode *
+create_ust_capture_bytecode_from_bytecode(const struct lttng_bytecode *orig_f)
+{
+ struct lttng_ust_capture_bytecode *capture = NULL;
+
+ /* Copy capture bytecode. */
+ capture = zmalloc(sizeof(*capture) + orig_f->len);
+ if (!capture) {
+ PERROR("Failed to allocate lttng_ust_capture_bytecode: bytecode len = %" PRIu32 " bytes", orig_f->len);
+ goto error;
+ }
+
+ assert(sizeof(struct lttng_bytecode) ==
+ sizeof(struct lttng_ust_capture_bytecode));
+ memcpy(capture, orig_f, sizeof(*capture) + orig_f->len);
+error:
+ return capture;
+}
+
/*
* Find an ust_app using the sock and return it. RCU read side lock must be
* held before calling this helper function.
health_code_update();
- ust_bytecode = create_ust_bytecode_from_bytecode(bytecode);
+ ust_bytecode = create_ust_filter_bytecode_from_bytecode(bytecode);
if (!ust_bytecode) {
ret = -LTTNG_ERR_NOMEM;
goto error;
pthread_mutex_unlock(&app->sock_lock);
if (ret < 0) {
if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
- ERR("UST app set object filter failed for object %p of app (pid: %d) "
- "with ret %d", ust_object, app->pid, ret);
+ ERR("UST app set object filter failed: object = %p of app pid = %d, ret = %d",
+ ust_object, app->pid, ret);
} else {
/*
* This is normal behavior, an application can die during the
goto error;
}
- DBG2("UST filter successfully set for object %p", ust_object);
+ DBG2("UST filter successfully set: object = %p", ust_object);
+
+error:
+ health_code_update();
+ free(ust_bytecode);
+ return ret;
+}
+
+/*
+ * Set a capture bytecode for the passed object.
+ * The sequence number enforces the ordering at runtime and on reception of
+ * the captured payloads.
+ */
+static int set_ust_capture(struct ust_app *app,
+ const struct lttng_bytecode *bytecode,
+ unsigned int capture_seqnum,
+ struct lttng_ust_object_data *ust_object)
+{
+ int ret;
+ struct lttng_ust_capture_bytecode *ust_bytecode = NULL;
+
+ health_code_update();
+
+ ust_bytecode = create_ust_capture_bytecode_from_bytecode(bytecode);
+ if (!ust_bytecode) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto error;
+ }
+
+ /*
+ * Set the sequence number to ensure the capture of fields is ordered.
+ */
+ ust_bytecode->seqnum = capture_seqnum;
+
+ pthread_mutex_lock(&app->sock_lock);
+ ret = ustctl_set_capture(app->sock, ust_bytecode,
+ ust_object);
+ pthread_mutex_unlock(&app->sock_lock);
+ if (ret < 0) {
+ if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
+ ERR("UST app set object capture failed: object = %p of app pid = %d, ret = %d",
+ ust_object, app->pid, ret);
+ } else {
+ /*
+ * This is normal behavior, an application can die during the
+ * creation process. Don't report an error so the execution can
+ * continue normally.
+ */
+ ret = 0;
+ DBG3("Failed to set UST app object capture. Application is dead.");
+ }
+
+ goto error;
+ }
+
+ DBG2("UST capture successfully set: object = %p", ust_object);
error:
health_code_update();
const struct lttng_condition *condition = NULL;
struct lttng_ust_event_notifier event_notifier;
const struct lttng_event_rule *event_rule = NULL;
+ unsigned int capture_bytecode_count = 0, i;
+ enum lttng_condition_status cond_status;
health_code_update();
assert(app->event_notifier_group.object);
}
}
+ /* Set the capture bytecodes. */
+ cond_status = lttng_condition_event_rule_get_capture_descriptor_count(
+ condition, &capture_bytecode_count);
+ assert(cond_status == LTTNG_CONDITION_STATUS_OK);
+
+ for (i = 0; i < capture_bytecode_count; i++) {
+ const struct lttng_bytecode *capture_bytecode =
+ lttng_condition_event_rule_get_capture_bytecode_at_index(
+ condition, i);
+
+ ret = set_ust_capture(app, capture_bytecode, i,
+ ua_event_notifier_rule->obj);
+ if (ret < 0) {
+ goto error;
+ }
+ }
+
/*
* We now need to explicitly enable the event, since it
* is disabled at creation.