#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"
free(ua_event_notifier_rule->obj);
}
- lttng_event_rule_put(ua_event_notifier_rule->event_rule);
+ lttng_trigger_put(ua_event_notifier_rule->trigger);
call_rcu(&ua_event_notifier_rule->rcu_head,
free_ust_app_event_notifier_rule_rcu);
}
* Allocate a new UST app event notifier rule.
*/
static struct ust_app_event_notifier_rule *alloc_ust_app_event_notifier_rule(
- struct lttng_event_rule *event_rule, uint64_t token)
+ struct lttng_trigger *trigger)
{
enum lttng_event_rule_generate_exclusions_status
generate_exclusion_status;
struct ust_app_event_notifier_rule *ua_event_notifier_rule;
+ struct lttng_condition *condition = NULL;
+ const struct lttng_event_rule *event_rule = NULL;
ua_event_notifier_rule = zmalloc(sizeof(struct ust_app_event_notifier_rule));
if (ua_event_notifier_rule == NULL) {
}
ua_event_notifier_rule->enabled = 1;
- ua_event_notifier_rule->token = token;
- lttng_ht_node_init_u64(&ua_event_notifier_rule->node, token);
+ ua_event_notifier_rule->token = lttng_trigger_get_tracer_token(trigger);
+ lttng_ht_node_init_u64(&ua_event_notifier_rule->node,
+ ua_event_notifier_rule->token);
- /* Get reference of the event rule. */
- if (!lttng_event_rule_get(event_rule)) {
- abort();
- }
+ condition = lttng_trigger_get_condition(trigger);
+ assert(condition);
+ assert(lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_EVENT_RULE_HIT);
+
+ assert(LTTNG_CONDITION_STATUS_OK == lttng_condition_event_rule_get_rule(condition, &event_rule));
+ assert(event_rule);
+
+ /* Acquire the event notifier's reference to the trigger. */
+ lttng_trigger_get(trigger);
- ua_event_notifier_rule->event_rule = event_rule;
+ ua_event_notifier_rule->trigger = trigger;
ua_event_notifier_rule->filter = lttng_event_rule_get_filter_bytecode(event_rule);
generate_exclusion_status = lttng_event_rule_generate_exclusions(
event_rule, &ua_event_notifier_rule->exclusion);
break;
default:
/* Error occured. */
- ERR("Failed to generate exclusions from event rule while allocating an event notifier rule");
- goto error_put_event_rule;
+ ERR("Failed to generate exclusions from trigger while allocating an event notifier rule");
+ goto error_put_trigger;
}
DBG3("UST app event notifier rule allocated: token = %" PRIu64,
return ua_event_notifier_rule;
-error_put_event_rule:
- lttng_event_rule_put(event_rule);
+error_put_trigger:
+ lttng_trigger_put(trigger);
error:
free(ua_event_notifier_rule);
return NULL;
*
* 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.
+ */
+static int set_ust_capture(struct ust_app *app,
+ const struct lttng_bytecode *bytecode,
+ 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;
+ }
+
+ 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();
struct ust_app_event_notifier_rule *ua_event_notifier_rule)
{
int ret = 0;
+ enum lttng_condition_status condition_status;
+ 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);
- ret = init_ust_event_notifier_from_event_rule(
- ua_event_notifier_rule->event_rule, &event_notifier);
- if (ret) {
- ERR("Failed to initialize UST event notifier from event rule: app = '%s' (ppid: %d)",
- app->name, app->ppid);
- goto error;
- }
+ condition = lttng_trigger_get_const_condition(
+ ua_event_notifier_rule->trigger);
+ assert(condition);
+ assert(lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_EVENT_RULE_HIT);
+
+ condition_status = lttng_condition_event_rule_get_rule(condition, &event_rule);
+ assert(condition_status == LTTNG_CONDITION_STATUS_OK);
+ assert(event_rule);
+ assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_TRACEPOINT);
+ init_ust_event_notifier_from_event_rule(event_rule, &event_notifier);
event_notifier.event.token = ua_event_notifier_rule->token;
/* Create UST event notifier against the tracer. */
}
}
+ /* 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,
+ ua_event_notifier_rule->obj);
+ if (ret < 0) {
+ goto error;
+ }
+ }
+
/*
* We now need to explicitly enable the event, since it
* is disabled at creation.
* Called with ust app session mutex held.
*/
static
-int create_ust_app_event_notifier_rule(struct lttng_event_rule *rule,
- struct ust_app *app, uint64_t token)
+int create_ust_app_event_notifier_rule(struct lttng_trigger *trigger,
+ struct ust_app *app)
{
int ret = 0;
struct ust_app_event_notifier_rule *ua_event_notifier_rule;
- ua_event_notifier_rule = alloc_ust_app_event_notifier_rule(rule, token);
+ ua_event_notifier_rule = alloc_ust_app_event_notifier_rule(trigger);
if (ua_event_notifier_rule == NULL) {
ret = -ENOMEM;
goto end;
if (ret == -LTTNG_UST_ERR_EXIST) {
ERR("Tracer for application reported that an event notifier being created already exists: "
"token = \"%" PRIu64 "\", pid = %d, ppid = %d, uid = %d, gid = %d",
- token,
+ lttng_trigger_get_tracer_token(trigger),
app->pid, app->ppid, app->uid,
app->gid);
}
&ua_event_notifier_rule->node);
DBG2("UST app create token event rule completed: app = '%s' (ppid: %d), token = %" PRIu64,
- app->name, app->ppid, token);
+ app->name, app->ppid, lttng_trigger_get_tracer_token(trigger));
end:
return ret;
looked_up_event_notifier_rule = find_ust_app_event_notifier_rule(
app->token_to_event_notifier_rule_ht, token);
if (!looked_up_event_notifier_rule) {
- ret = create_ust_app_event_notifier_rule(event_rule, app, token);
+ ret = create_ust_app_event_notifier_rule(trigger, app);
if (ret < 0) {
goto end;
}