X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-app.c;h=01fa7fc93d7fbb738555f065d95ad0d10e39f636;hp=38d1d78713e6446dca9b55b001ccfbee376c88b3;hb=f2eafd2d6170ab8974bb8ceb1eec6d89ab969623;hpb=5d4193fd103743e68020148db71469b907020140 diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c index 38d1d7871..01fa7fc93 100644 --- a/src/bin/lttng-sessiond/ust-app.c +++ b/src/bin/lttng-sessiond/ust-app.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include "lttng-sessiond.h" #include "notification-thread-commands.h" #include "rotate.h" +#include "event.h" struct lttng_ht *ust_app_ht; struct lttng_ht *ust_app_ht_by_sock; @@ -360,7 +362,7 @@ static void delete_ust_app_event_notifier_rule(int sock, 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); } @@ -952,6 +954,7 @@ void delete_ust_app(struct ust_app *app) struct ust_app_session *ua_sess, *tmp_ua_sess; struct lttng_ht_iter iter; struct ust_app_event_notifier_rule *event_notifier_rule; + bool event_notifier_write_fd_is_open; /* * The session list lock must be held during this function to guarantee @@ -1009,7 +1012,16 @@ void delete_ust_app(struct ust_app *app) free(app->event_notifier_group.object); } + event_notifier_write_fd_is_open = lttng_pipe_is_write_open( + app->event_notifier_group.event_pipe); lttng_pipe_destroy(app->event_notifier_group.event_pipe); + /* + * Release the file descriptors reserved for the event notifier pipe. + * The app could be destroyed before the write end of the pipe could be + * passed to the application (and closed). In that case, both file + * descriptors must be released. + */ + lttng_fd_put(LTTNG_FD_APPS, event_notifier_write_fd_is_open ? 2 : 1); /* * Wait until we have deleted the application from the sock hash table @@ -1219,11 +1231,13 @@ error: * 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) { @@ -1232,15 +1246,21 @@ static struct ust_app_event_notifier_rule *alloc_ust_app_event_notifier_rule( } 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); - ua_event_notifier_rule->event_rule = event_rule; + /* Acquire the event notifier's reference to the trigger. */ + lttng_trigger_get(trigger); + + 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); @@ -1250,8 +1270,8 @@ static struct ust_app_event_notifier_rule *alloc_ust_app_event_notifier_rule( 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, @@ -1259,8 +1279,8 @@ static struct ust_app_event_notifier_rule *alloc_ust_app_event_notifier_rule( 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; @@ -1307,50 +1327,51 @@ error: } /* - * Allocate a filter and copy the given original filter. + * Create a liblttng-ust filter bytecode from given bytecode. * * Return allocated filter or NULL on error. */ -static struct lttng_filter_bytecode *copy_filter_bytecode( - struct lttng_filter_bytecode *orig_f) +static struct lttng_ust_filter_bytecode * +create_ust_filter_bytecode_from_bytecode(const struct lttng_bytecode *orig_f) { - struct lttng_filter_bytecode *filter = NULL; + 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 filter bytecode"); + PERROR("Failed to allocate lttng_ust_filter_bytecode: bytecode len = %" PRIu32 " bytes", orig_f->len); goto error; } + assert(sizeof(struct lttng_bytecode) == + sizeof(struct lttng_ust_filter_bytecode)); memcpy(filter, orig_f, sizeof(*filter) + orig_f->len); - error: return filter; } /* - * Create a liblttng-ust filter bytecode from given bytecode. + * Create a liblttng-ust capture bytecode from given bytecode. * * Return allocated filter or NULL on error. */ -static struct lttng_ust_filter_bytecode *create_ust_bytecode_from_bytecode( - const struct lttng_filter_bytecode *orig_f) +static struct lttng_ust_capture_bytecode * +create_ust_capture_bytecode_from_bytecode(const struct lttng_bytecode *orig_f) { - struct lttng_ust_filter_bytecode *filter = NULL; + struct lttng_ust_capture_bytecode *capture = NULL; - /* Copy filter bytecode */ - filter = zmalloc(sizeof(*filter) + orig_f->len); - if (!filter) { - PERROR("zmalloc alloc ust filter bytecode"); + /* 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_filter_bytecode) == - sizeof(struct lttng_ust_filter_bytecode)); - memcpy(filter, orig_f, sizeof(*filter) + orig_f->len); + assert(sizeof(struct lttng_bytecode) == + sizeof(struct lttng_ust_capture_bytecode)); + memcpy(capture, orig_f, sizeof(*capture) + orig_f->len); error: - return filter; + return capture; } /* @@ -1405,7 +1426,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, - const char *name, const struct lttng_filter_bytecode *filter, + const char *name, const struct lttng_bytecode *filter, int loglevel_value, const struct lttng_event_exclusion *exclusion) { @@ -1514,7 +1535,7 @@ error: * Set the filter on the tracer. */ static int set_ust_object_filter(struct ust_app *app, - const struct lttng_filter_bytecode *bytecode, + const struct lttng_bytecode *bytecode, struct lttng_ust_object_data *ust_object) { int ret; @@ -1522,7 +1543,7 @@ static int set_ust_object_filter(struct ust_app *app, 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; @@ -1533,8 +1554,8 @@ static int set_ust_object_filter(struct ust_app *app, 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 @@ -1547,7 +1568,54 @@ static int set_ust_object_filter(struct ust_app *app, 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(); @@ -1934,43 +2002,57 @@ static int init_ust_event_notifier_from_event_rule( memset(event_notifier, 0, sizeof(*event_notifier)); - status = lttng_event_rule_tracepoint_get_pattern(rule, &pattern); - if (status != LTTNG_EVENT_RULE_STATUS_OK) { - /* At this point, this is a fatal error. */ - abort(); - } + if (lttng_event_rule_targets_agent_domain(rule)) { + /* + * Special event for agents + * The actual meat of the event is in the filter that will be + * attached later on. + * Set the default values for the agent event. + */ + pattern = event_get_default_agent_ust_name( + lttng_event_rule_get_domain_type(rule)); + loglevel = 0; + ust_loglevel_type = LTTNG_UST_LOGLEVEL_ALL; + } else { + status = lttng_event_rule_tracepoint_get_pattern( + rule, &pattern); + if (status != LTTNG_EVENT_RULE_STATUS_OK) { + /* At this point, this is a fatal error. */ + abort(); + } - status = lttng_event_rule_tracepoint_get_log_level_type( - rule, &loglevel_type); - if (status != LTTNG_EVENT_RULE_STATUS_OK) { - /* At this point, this is a fatal error. */ - abort(); - } + status = lttng_event_rule_tracepoint_get_log_level_type( + rule, &loglevel_type); + if (status != LTTNG_EVENT_RULE_STATUS_OK) { + /* At this point, this is a fatal error. */ + abort(); + } - switch (loglevel_type) { - case LTTNG_EVENT_LOGLEVEL_ALL: - ust_loglevel_type = LTTNG_UST_LOGLEVEL_ALL; - break; - case LTTNG_EVENT_LOGLEVEL_RANGE: - ust_loglevel_type = LTTNG_UST_LOGLEVEL_RANGE; - break; - case LTTNG_EVENT_LOGLEVEL_SINGLE: - ust_loglevel_type = LTTNG_UST_LOGLEVEL_SINGLE; - break; - default: - /* Unknown log level specification type. */ - abort(); - } + switch (loglevel_type) { + case LTTNG_EVENT_LOGLEVEL_ALL: + ust_loglevel_type = LTTNG_UST_LOGLEVEL_ALL; + break; + case LTTNG_EVENT_LOGLEVEL_RANGE: + ust_loglevel_type = LTTNG_UST_LOGLEVEL_RANGE; + break; + case LTTNG_EVENT_LOGLEVEL_SINGLE: + ust_loglevel_type = LTTNG_UST_LOGLEVEL_SINGLE; + break; + default: + /* Unknown log level specification type. */ + abort(); + } - if (loglevel_type != LTTNG_EVENT_LOGLEVEL_ALL) { - status = lttng_event_rule_tracepoint_get_log_level( - rule, &loglevel); - assert(status == LTTNG_EVENT_RULE_STATUS_OK); + if (loglevel_type != LTTNG_EVENT_LOGLEVEL_ALL) { + status = lttng_event_rule_tracepoint_get_log_level( + rule, &loglevel); + assert(status == LTTNG_EVENT_RULE_STATUS_OK); + } } event_notifier->event.instrumentation = LTTNG_UST_TRACEPOINT; ret = lttng_strncpy(event_notifier->event.name, pattern, - LTTNG_UST_SYM_NAME_LEN - 1); + LTTNG_UST_SYM_NAME_LEN - 1); if (ret) { ERR("Failed to copy event rule pattern to notifier: pattern = '%s' ", pattern); @@ -1991,19 +2073,25 @@ static int create_ust_event_notifier(struct ust_app *app, 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; 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. */ @@ -2109,7 +2197,7 @@ static void shadow_copy_event(struct ust_app_event *ua_event, /* Copy filter bytecode */ if (uevent->filter) { - ua_event->filter = copy_filter_bytecode(uevent->filter); + ua_event->filter = lttng_bytecode_copy(uevent->filter); /* Filter might be NULL here in case of ENONEM. */ } @@ -3519,13 +3607,13 @@ error: * 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; @@ -3543,7 +3631,7 @@ int create_ust_app_event_notifier_rule(struct lttng_event_rule *rule, 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); } @@ -3554,7 +3642,7 @@ int create_ust_app_event_notifier_rule(struct lttng_event_rule *rule, &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; @@ -3708,6 +3796,7 @@ error: */ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock) { + int ret; struct ust_app *lta = NULL; struct lttng_pipe *event_notifier_event_source_pipe = NULL; @@ -3726,6 +3815,18 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock) goto error; } + /* + * Reserve the two file descriptors of the event source pipe. The write + * end will be closed once it is passed to the application, at which + * point a single 'put' will be performed. + */ + ret = lttng_fd_get(LTTNG_FD_APPS, 2); + if (ret) { + ERR("Failed to reserve two file descriptors for the event source pipe while creating a new application instance: app = '%s' (ppid: %d)", + msg->name, (int) msg->ppid); + 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)", @@ -3783,6 +3884,7 @@ struct ust_app *ust_app_create(struct ust_register_msg *msg, int sock) error_free_pipe: lttng_pipe_destroy(event_notifier_event_source_pipe); + lttng_fd_put(LTTNG_FD_APPS, 2); error: return NULL; } @@ -3892,6 +3994,12 @@ int ust_app_setup_event_notifier_group(struct ust_app *app) goto error; } + /* + * Release the file descriptor that was reserved for the write-end of + * the pipe. + */ + lttng_fd_put(LTTNG_FD_APPS, 1); + lttng_ret = notification_thread_command_add_tracer_event_source( notification_thread_handle, lttng_pipe_get_readfd(app->event_notifier_group.event_pipe), @@ -5533,7 +5641,7 @@ void ust_app_synchronize_event_notifier_rules(struct ust_app *app) 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; }