X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fsave.c;h=e57f0e03a6b451b920592a6cb2a08d5f61d1fd29;hp=b7d0cc80a40d4d9fb47d4b17aaaa9e683c7e2776;hb=87597c2c3bbaa1502ad2025cbf16704829f3b464;hpb=0dbc2034c9571ec342d382bf87231775563f8624 diff --git a/src/bin/lttng-sessiond/save.c b/src/bin/lttng-sessiond/save.c index b7d0cc80a..e57f0e03a 100644 --- a/src/bin/lttng-sessiond/save.c +++ b/src/bin/lttng-sessiond/save.c @@ -215,13 +215,16 @@ const char *get_kernel_instrumentation_string( instrumentation_string = config_event_type_tracepoint; break; case LTTNG_KERNEL_KPROBE: - instrumentation_string = config_event_type_kprobe; + instrumentation_string = config_event_type_probe; + break; + case LTTNG_KERNEL_UPROBE: + instrumentation_string = config_event_type_userspace_probe; break; case LTTNG_KERNEL_FUNCTION: - instrumentation_string = config_event_type_function; + instrumentation_string = config_event_type_function_entry; break; case LTTNG_KERNEL_KRETPROBE: - instrumentation_string = config_event_type_kretprobe; + instrumentation_string = config_event_type_function; break; case LTTNG_KERNEL_NOOP: instrumentation_string = config_event_type_noop; @@ -285,6 +288,12 @@ const char *get_kernel_context_type_string( case LTTNG_KERNEL_CONTEXT_MIGRATABLE: context_type_string = config_event_context_migratable; break; + case LTTNG_KERNEL_CONTEXT_CALLSTACK_USER: + context_type_string = config_event_context_callstack_user; + break; + case LTTNG_KERNEL_CONTEXT_CALLSTACK_KERNEL: + context_type_string = config_event_context_callstack_kernel; + break; default: context_type_string = NULL; } @@ -376,9 +385,384 @@ const char *get_loglevel_type_string( return loglevel_type_string; } +static +int save_kernel_function_event(struct config_writer *writer, + struct ltt_kernel_event *event) +{ + int ret; + + ret = config_writer_open_element(writer, config_element_function_attributes); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + ret = config_writer_write_element_string(writer, config_element_name, + event->event->u.ftrace.symbol_name); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + /* /function attributes */ + ret = config_writer_close_element(writer); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } +end: + return ret; +} + +static +int save_kernel_kprobe_event(struct config_writer *writer, + struct ltt_kernel_event *event) +{ + int ret; + const char *symbol_name; + uint64_t addr; + uint64_t offset; + + switch (event->event->instrumentation) { + case LTTNG_KERNEL_KPROBE: + /* + * Comments in lttng-kernel.h mention that + * either addr or symbol_name are set, not both. + */ + addr = event->event->u.kprobe.addr; + offset = event->event->u.kprobe.offset; + symbol_name = addr ? NULL : event->event->u.kprobe.symbol_name; + break; + case LTTNG_KERNEL_KRETPROBE: + addr = event->event->u.kretprobe.addr; + offset = event->event->u.kretprobe.offset; + symbol_name = addr ? NULL : event->event->u.kretprobe.symbol_name; + break; + default: + assert(1); + ERR("Unsupported kernel instrumentation type."); + ret = LTTNG_ERR_INVALID; + goto end; + } + + ret = config_writer_open_element(writer, config_element_probe_attributes); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + if (addr) { + ret = config_writer_write_element_unsigned_int( writer, + config_element_address, addr); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + } else if (symbol_name) { + ret = config_writer_write_element_string(writer, + config_element_symbol_name, symbol_name); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + /* If the offset is non-zero, write it.*/ + if (offset) { + ret = config_writer_write_element_unsigned_int(writer, + config_element_offset, offset); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + } + } else { + /* + * This really should not happen as we are either setting the + * address or the symbol above. + */ + ERR("Invalid probe/function description."); + ret = LTTNG_ERR_INVALID; + goto end; + } + + + ret = config_writer_close_element(writer); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } +end: + return ret; +} + +/* + * Save the userspace probe tracepoint event associated with the event to the + * config writer. + */ +static +int save_kernel_userspace_probe_tracepoint_event(struct config_writer *writer, + struct ltt_kernel_event *event) +{ + int ret = 0; + const char *probe_name, *provider_name, *binary_path; + const struct lttng_userspace_probe_location *userspace_probe_location; + const struct lttng_userspace_probe_location_lookup_method *lookup_method; + enum lttng_userspace_probe_location_lookup_method_type lookup_type; + + /* Get userspace probe location from the event. */ + userspace_probe_location = event->userspace_probe_location; + if (!userspace_probe_location) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + /* Get lookup method and lookup method type. */ + lookup_method = lttng_userspace_probe_location_get_lookup_method(userspace_probe_location); + if (!lookup_method) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method); + + /* Get the binary path, probe name and provider name. */ + binary_path = + lttng_userspace_probe_location_tracepoint_get_binary_path( + userspace_probe_location); + if (!binary_path) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + probe_name = + lttng_userspace_probe_location_tracepoint_get_probe_name( + userspace_probe_location); + if (!probe_name) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + provider_name = + lttng_userspace_probe_location_tracepoint_get_provider_name( + userspace_probe_location); + if (!provider_name) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + /* Open a userspace probe tracepoint attribute. */ + ret = config_writer_open_element(writer, config_element_userspace_probe_tracepoint_attributes); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + switch (lookup_type) { + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT: + ret = config_writer_write_element_string(writer, + config_element_userspace_probe_lookup, + config_element_userspace_probe_lookup_tracepoint_sdt); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + break; + default: + ERR("Unsupported kernel userspace probe tracepoint lookup method."); + ret = LTTNG_ERR_INVALID; + goto end; + } + + /* Write the binary path, provider name and the probe name. */ + ret = config_writer_write_element_string(writer, + config_element_userspace_probe_location_binary_path, + binary_path); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + ret = config_writer_write_element_string(writer, + config_element_userspace_probe_tracepoint_location_provider_name, + provider_name); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + ret = config_writer_write_element_string(writer, + config_element_userspace_probe_tracepoint_location_probe_name, + probe_name); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + /* Close the userspace probe tracepoint attribute. */ + ret = config_writer_close_element(writer); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + +end: + return ret; +} + +/* + * Save the userspace probe function event associated with the event to the + * config writer. + */ +static +int save_kernel_userspace_probe_function_event(struct config_writer *writer, + struct ltt_kernel_event *event) +{ + int ret = 0; + const char *function_name, *binary_path; + const struct lttng_userspace_probe_location *userspace_probe_location; + const struct lttng_userspace_probe_location_lookup_method *lookup_method; + enum lttng_userspace_probe_location_lookup_method_type lookup_type; + + /* Get userspace probe location from the event. */ + userspace_probe_location = event->userspace_probe_location; + if (!userspace_probe_location) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + /* Get lookup method and lookup method type. */ + lookup_method = lttng_userspace_probe_location_get_lookup_method( + userspace_probe_location); + if (!lookup_method) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + /* Get the binary path and the function name. */ + binary_path = + lttng_userspace_probe_location_function_get_binary_path( + userspace_probe_location); + if (!binary_path) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + function_name = + lttng_userspace_probe_location_function_get_function_name( + userspace_probe_location); + if (!function_name) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + /* Open a userspace probe function attribute. */ + ret = config_writer_open_element(writer, + config_element_userspace_probe_function_attributes); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method); + switch (lookup_type) { + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF: + ret = config_writer_write_element_string(writer, + config_element_userspace_probe_lookup, + config_element_userspace_probe_lookup_function_elf); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + break; + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT: + ret = config_writer_write_element_string(writer, + config_element_userspace_probe_lookup, + config_element_userspace_probe_lookup_function_default); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + break; + default: + ERR("Unsupported kernel userspace probe function lookup method."); + ret = LTTNG_ERR_INVALID; + goto end; + } + + /* Write the binary path and the function name. */ + ret = config_writer_write_element_string(writer, + config_element_userspace_probe_location_binary_path, + binary_path); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + ret = config_writer_write_element_string(writer, + config_element_userspace_probe_function_location_function_name, + function_name); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + /* Close the userspace probe function attribute. */ + ret = config_writer_close_element(writer); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + +end: + return ret; +} + +static +int save_kernel_userspace_probe_event(struct config_writer *writer, + struct ltt_kernel_event *event) +{ + int ret; + struct lttng_userspace_probe_location *userspace_probe_location; + + /* Get userspace probe location from the event. */ + userspace_probe_location = event->userspace_probe_location; + if (!userspace_probe_location) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + + switch(lttng_userspace_probe_location_get_type(userspace_probe_location)) { + case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION: + { + ret = save_kernel_userspace_probe_function_event(writer, event); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + break; + } + case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT: + { + ret = save_kernel_userspace_probe_tracepoint_event(writer, event); + if (ret) { + ret = LTTNG_ERR_SAVE_IO_FAIL; + goto end; + } + break; + } + case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN: + default: + ERR("Unsupported kernel userspace probe location type."); + ret = LTTNG_ERR_INVALID; + goto end; + } + +end: + return ret; +} + static int save_kernel_event(struct config_writer *writer, - struct ltt_kernel_event *event) + struct ltt_kernel_event *event) { int ret; const char *instrumentation_type; @@ -431,6 +815,7 @@ int save_kernel_event(struct config_writer *writer, if (event->event->instrumentation == LTTNG_KERNEL_FUNCTION || event->event->instrumentation == LTTNG_KERNEL_KPROBE || + event->event->instrumentation == LTTNG_KERNEL_UPROBE || event->event->instrumentation == LTTNG_KERNEL_KRETPROBE) { ret = config_writer_open_element(writer, @@ -443,94 +828,24 @@ int save_kernel_event(struct config_writer *writer, switch (event->event->instrumentation) { case LTTNG_KERNEL_SYSCALL: case LTTNG_KERNEL_FUNCTION: - ret = config_writer_open_element(writer, - config_element_function_attributes); - if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; - goto end; - } - - ret = config_writer_write_element_string(writer, - config_element_name, - event->event->u.ftrace.symbol_name); + ret = save_kernel_function_event(writer, event); if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; - goto end; - } - - /* /function attributes */ - ret = config_writer_close_element(writer); - if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } break; case LTTNG_KERNEL_KPROBE: case LTTNG_KERNEL_KRETPROBE: - { - const char *symbol_name; - uint64_t addr; - uint64_t offset; - - if (event->event->instrumentation == - LTTNG_KERNEL_KPROBE) { - /* - * Comments in lttng-kernel.h mention that - * either addr or symbol_name are set, not both. - */ - addr = event->event->u.kprobe.addr; - offset = event->event->u.kprobe.offset; - symbol_name = addr ? NULL : - event->event->u.kprobe.symbol_name; - } else { - symbol_name = - event->event->u.kretprobe.symbol_name; - addr = event->event->u.kretprobe.addr; - offset = event->event->u.kretprobe.offset; - } - - ret = config_writer_open_element(writer, - config_element_probe_attributes); + ret = save_kernel_kprobe_event(writer, event); if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } - - if (symbol_name) { - ret = config_writer_write_element_string(writer, - config_element_symbol_name, - symbol_name); - if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; - goto end; - } - } - - if (addr) { - ret = config_writer_write_element_unsigned_int( - writer, config_element_address, addr); - if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; - goto end; - } - } - - if (offset) { - ret = config_writer_write_element_unsigned_int( - writer, config_element_offset, offset); - if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; - goto end; - } - } - - ret = config_writer_close_element(writer); + break; + case LTTNG_KERNEL_UPROBE: + ret = save_kernel_userspace_probe_event(writer, event); if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; goto end; } break; - } default: ERR("Unsupported kernel instrumentation type."); ret = LTTNG_ERR_INVALID; @@ -780,7 +1095,6 @@ end: static int save_agent_events(struct config_writer *writer, - struct ltt_ust_channel *chan, struct agent *agent) { int ret; @@ -1254,7 +1568,7 @@ int save_ust_channel(struct config_writer *writer, * the "agent" events associated with this channel and serialize * them. */ - ret = save_agent_events(writer, ust_chan, agent); + ret = save_agent_events(writer, agent); if (ret) { goto end; } @@ -1881,6 +2195,83 @@ end: return ret; } +static +int save_session_rotation_schedule(struct config_writer *writer, + enum lttng_rotation_schedule_type type, uint64_t value) +{ + int ret = 0; + const char *element_name; + const char *value_name; + + switch (type) { + case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC: + element_name = config_element_rotation_schedule_periodic; + value_name = config_element_rotation_schedule_periodic_time_us; + break; + case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD: + element_name = config_element_rotation_schedule_size_threshold; + value_name = config_element_rotation_schedule_size_threshold_bytes; + break; + default: + ret = -1; + goto end; + } + + ret = config_writer_open_element(writer, element_name); + if (ret) { + goto end; + } + + ret = config_writer_write_element_unsigned_int(writer, + value_name, value); + if (ret) { + goto end; + } + + /* Close schedule descriptor element. */ + ret = config_writer_close_element(writer); + if (ret) { + goto end; + } +end: + return ret; +} + +static +int save_session_rotation_schedules(struct config_writer *writer, + struct ltt_session *session) +{ + int ret; + + ret = config_writer_open_element(writer, + config_element_rotation_schedules); + if (session->rotate_timer_period) { + ret = save_session_rotation_schedule(writer, + LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC, + session->rotate_timer_period); + if (ret) { + goto close_schedules; + } + } + if (session->rotate_size) { + ret = save_session_rotation_schedule(writer, + LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD, + session->rotate_size); + if (ret) { + goto close_schedules; + } + } + +close_schedules: + /* Close rotation schedules element. */ + ret = config_writer_close_element(writer); + if (ret) { + goto end; + } +end: + return ret; +} + /* * Save the given session. * @@ -2056,20 +2447,9 @@ int save_session(struct ltt_session *session, goto end; } } - if (session->rotate_timer_period) { - ret = config_writer_write_element_unsigned_int(writer, - config_element_rotation_timer_interval, - session->rotate_timer_period); - if (ret) { - ret = LTTNG_ERR_SAVE_IO_FAIL; - goto end; - } - } - - if (session->rotate_size) { - ret = config_writer_write_element_unsigned_int(writer, - config_element_rotation_size, - session->rotate_size); + if (session->rotate_timer_period || session->rotate_size) { + ret = save_session_rotation_schedules(writer, + session); if (ret) { ret = LTTNG_ERR_SAVE_IO_FAIL; goto end;