X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Ftrace-kernel.c;fp=src%2Fbin%2Flttng-sessiond%2Ftrace-kernel.c;h=7ad8f2320fd14965b0de0644797beb2ad128d8ec;hp=52f819b3001390fba5fb71c253a6321497649a01;hb=1831ae68b70dece8e9b847081526495adbbf05e5;hpb=25357057de5ae4dd2a572e8f9b893c1b90cbd60a diff --git a/src/bin/lttng-sessiond/trace-kernel.c b/src/bin/lttng-sessiond/trace-kernel.c index 52f819b30..7ad8f2320 100644 --- a/src/bin/lttng-sessiond/trace-kernel.c +++ b/src/bin/lttng-sessiond/trace-kernel.c @@ -15,7 +15,17 @@ #include #include #include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -130,6 +140,29 @@ struct ltt_kernel_event *trace_kernel_get_event_by_name( } } +struct ltt_kernel_token_event_rule *trace_kernel_find_trigger_by_token( + struct ltt_kernel_token_event_rule_list *list, + uint64_t token) +{ + struct ltt_kernel_token_event_rule *token_event_rule; + int found = 0; + + assert(list); + + cds_list_for_each_entry(token_event_rule, &list->head, list) { + if (token_event_rule->token == token) { + found = 1; + } + break; + } + if (found) { + DBG("Found token event rule %" PRIu64, token); + return token_event_rule; + } else { + return NULL; + } +} + /* * Allocate and initialize a kernel session data structure. * @@ -478,6 +511,162 @@ error: return ret; } +/* + * Allocate and initialize a kernel token event rule. + * + * Return pointer to structure or NULL. + */ +enum lttng_error_code trace_kernel_create_token_event_rule( + struct lttng_event_rule *event_rule, + uint64_t token, + struct ltt_kernel_token_event_rule **kernel_token_event_rule) +{ + enum lttng_error_code ret = LTTNG_OK; + struct ltt_kernel_token_event_rule *local_kernel_token_event_rule; + + assert(kernel_token_event_rule); + + local_kernel_token_event_rule = zmalloc(sizeof(struct ltt_kernel_token_event_rule)); + if (local_kernel_token_event_rule == NULL) { + PERROR("Failed to allocate ltt_kernel_token_event_rule structure"); + ret = LTTNG_ERR_NOMEM; + goto error; + } + + local_kernel_token_event_rule->fd = -1; + local_kernel_token_event_rule->enabled = 1; + local_kernel_token_event_rule->token = token; + + /* Get the reference of the event rule */ + if (!lttng_event_rule_get(event_rule)) { + assert(0); + } + + local_kernel_token_event_rule->event_rule = event_rule; + /* The event rule still own the filter and bytecode */ + local_kernel_token_event_rule->filter = lttng_event_rule_get_filter_bytecode(event_rule); + + DBG3("[trace] Kernel token event rule %" PRIu64 " allocated", local_kernel_token_event_rule->token); +error: + *kernel_token_event_rule = local_kernel_token_event_rule; + return ret; + +} + +/* + * Initialize a kernel trigger from an event rule. + */ +enum lttng_error_code trace_kernel_init_trigger_from_event_rule(const struct lttng_event_rule *rule, + struct lttng_kernel_trigger *kernel_trigger) +{ + enum lttng_error_code ret; + enum lttng_event_rule_status status; + const char *name = NULL; + + /* TODO: do this for now but have disucssion on if this could be the + * responsability of the event_rule itself ala + * "lttng_even_rule_generate_kernel_trigger" + */ + switch (lttng_event_rule_get_type(rule)) { + case LTTNG_EVENT_RULE_TYPE_KPROBE: + kernel_trigger->instrumentation = LTTNG_KERNEL_KPROBE; + kernel_trigger->u.kprobe.addr = lttng_event_rule_kprobe_get_address(rule); + kernel_trigger->u.kprobe.offset = lttng_event_rule_kprobe_get_offset(rule); + strncpy(kernel_trigger->u.kprobe.symbol_name, + lttng_event_rule_kprobe_get_symbol_name(rule), LTTNG_KERNEL_SYM_NAME_LEN); + kernel_trigger->u.kprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; + (void) lttng_event_rule_kprobe_get_name(rule, &name); + ret = LTTNG_OK; + break; + case LTTNG_EVENT_RULE_TYPE_UPROBE: + { + const struct lttng_userspace_probe_location* location = NULL; + const struct lttng_userspace_probe_location_lookup_method *lookup = NULL; + + status = lttng_event_rule_uprobe_get_location(rule, &location); + if (status != LTTNG_EVENT_RULE_STATUS_OK) { + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + kernel_trigger->instrumentation = LTTNG_KERNEL_UPROBE; + + /* + * Only the elf lookup method is supported at the moment. + */ + lookup = lttng_userspace_probe_location_get_lookup_method( + location); + if (!lookup) { + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + /* + * From the kernel tracer's perspective, all userspace probe + * event types are all the same: a file and an offset. + */ + switch (lttng_userspace_probe_location_lookup_method_get_type(lookup)) { + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF: + /* Get the file descriptor on the target binary. */ + kernel_trigger->u.uprobe.fd = + lttng_userspace_probe_location_function_get_binary_fd(location); + + break; + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT: + /* Get the file descriptor on the target binary. */ + kernel_trigger->u.uprobe.fd = + lttng_userspace_probe_location_tracepoint_get_binary_fd(location); + break; + default: + DBG("Unsupported lookup method type"); + ret = LTTNG_ERR_PROBE_LOCATION_INVAL; + goto error; + } + + (void) lttng_event_rule_uprobe_get_name(rule, &name); + + ret = LTTNG_OK; + break; + } + case LTTNG_EVENT_RULE_TYPE_KRETPROBE: + assert("Not supported" && 0); + kernel_trigger->instrumentation = LTTNG_KERNEL_KRETPROBE; + kernel_trigger->u.kretprobe.addr = lttng_event_rule_kretprobe_get_address(rule); + kernel_trigger->u.kretprobe.offset = lttng_event_rule_kretprobe_get_offset(rule); + strncpy(kernel_trigger->u.kretprobe.symbol_name, + lttng_event_rule_kretprobe_get_symbol_name(rule), LTTNG_KERNEL_SYM_NAME_LEN); + kernel_trigger->u.kretprobe.symbol_name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; + (void) lttng_event_rule_kretprobe_get_name(rule, &name); + ret = LTTNG_OK; + break; + case LTTNG_EVENT_RULE_TYPE_TRACEPOINT: + /* TODO: assert his is a kernel domain event-rule */ + kernel_trigger->instrumentation = LTTNG_KERNEL_TRACEPOINT; + (void) lttng_event_rule_tracepoint_get_pattern(rule, &name); + ret = LTTNG_OK; + break; + case LTTNG_EVENT_RULE_TYPE_SYSCALL: + kernel_trigger->instrumentation = LTTNG_KERNEL_SYSCALL; + (void) lttng_event_rule_syscall_get_pattern(rule, &name); + ret = LTTNG_OK; + break; + default: + ERR("Unknown kernel event rule instrumentation type (%d)", lttng_event_rule_get_type(rule)); + ret = LTTNG_ERR_INVALID; + goto error; + } + + /* + * WTF is LTTNG_EVENT_ALL??? and LTTNG_EVENT_FUNTION_ENTRY????? + */ + + /* Copy event name */ + strncpy(kernel_trigger->name, name, LTTNG_KERNEL_SYM_NAME_LEN); + kernel_trigger->name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; + +error: + return ret; +} /* * Allocate and initialize a kernel metadata. * @@ -607,6 +796,33 @@ void trace_kernel_destroy_event(struct ltt_kernel_event *event) free(event); } +/* + * Cleanup kernel event structure. + */ +void trace_kernel_destroy_token_event_rule(struct ltt_kernel_token_event_rule *event) +{ + /* TODO: review in depth to ensure adequate disposing */ + assert(event); + + /* Remove from event list */ + cds_list_del(&event->list); + + if (event->fd >= 0) { + int ret; + + DBG("[trace] Closing ,token event rule fd %d", event->fd); + /* Close kernel fd */ + ret = close(event->fd); + if (ret) { + PERROR("close"); + } + } else { + DBG("[trace] Tearing down token event rule (no associated fd)"); + } + + lttng_event_rule_put(event->event_rule); + free(event); +} /* * Cleanup kernel context structure. */