X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fsave.c;h=865775c8d838108c9691a6010183a8932a1a1abf;hp=3e2627818deffffceb5f5deeb03c31111be25482;hb=1f4962443;hpb=83712c39736bc4edbd64ca7e83192c9877a80a8e diff --git a/src/bin/lttng-sessiond/save.c b/src/bin/lttng-sessiond/save.c index 3e2627818..865775c8d 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; @@ -291,6 +294,63 @@ const char *get_kernel_context_type_string( case LTTNG_KERNEL_CONTEXT_CALLSTACK_KERNEL: context_type_string = config_event_context_callstack_kernel; break; + case LTTNG_KERNEL_CONTEXT_CGROUP_NS: + context_type_string = config_event_context_cgroup_ns; + break; + case LTTNG_KERNEL_CONTEXT_IPC_NS: + context_type_string = config_event_context_ipc_ns; + break; + case LTTNG_KERNEL_CONTEXT_MNT_NS: + context_type_string = config_event_context_mnt_ns; + break; + case LTTNG_KERNEL_CONTEXT_NET_NS: + context_type_string = config_event_context_net_ns; + break; + case LTTNG_KERNEL_CONTEXT_PID_NS: + context_type_string = config_event_context_pid_ns; + break; + case LTTNG_KERNEL_CONTEXT_USER_NS: + context_type_string = config_event_context_user_ns; + break; + case LTTNG_KERNEL_CONTEXT_UTS_NS: + context_type_string = config_event_context_uts_ns; + break; + case LTTNG_KERNEL_CONTEXT_UID: + context_type_string = config_event_context_uid; + break; + case LTTNG_KERNEL_CONTEXT_EUID: + context_type_string = config_event_context_euid; + break; + case LTTNG_KERNEL_CONTEXT_SUID: + context_type_string = config_event_context_suid; + break; + case LTTNG_KERNEL_CONTEXT_GID: + context_type_string = config_event_context_gid; + break; + case LTTNG_KERNEL_CONTEXT_EGID: + context_type_string = config_event_context_egid; + break; + case LTTNG_KERNEL_CONTEXT_SGID: + context_type_string = config_event_context_sgid; + break; + case LTTNG_KERNEL_CONTEXT_VUID: + context_type_string = config_event_context_vuid; + break; + case LTTNG_KERNEL_CONTEXT_VEUID: + context_type_string = config_event_context_veuid; + break; + case LTTNG_KERNEL_CONTEXT_VSUID: + context_type_string = config_event_context_vsuid; + break; + case LTTNG_KERNEL_CONTEXT_VGID: + context_type_string = config_event_context_vgid; + break; + case LTTNG_KERNEL_CONTEXT_VEGID: + context_type_string = config_event_context_vegid; + break; + case LTTNG_KERNEL_CONTEXT_VSGID: + context_type_string = config_event_context_vsgid; + break; default: context_type_string = NULL; } @@ -323,6 +383,45 @@ const char *get_ust_context_type_string( case LTTNG_UST_CONTEXT_APP_CONTEXT: context_type_string = config_event_context_app; break; + case LTTNG_UST_CONTEXT_CGROUP_NS: + context_type_string = config_event_context_cgroup_ns; + break; + case LTTNG_UST_CONTEXT_IPC_NS: + context_type_string = config_event_context_ipc_ns; + break; + case LTTNG_UST_CONTEXT_MNT_NS: + context_type_string = config_event_context_mnt_ns; + break; + case LTTNG_UST_CONTEXT_NET_NS: + context_type_string = config_event_context_net_ns; + break; + case LTTNG_UST_CONTEXT_PID_NS: + context_type_string = config_event_context_pid_ns; + break; + case LTTNG_UST_CONTEXT_USER_NS: + context_type_string = config_event_context_user_ns; + break; + case LTTNG_UST_CONTEXT_UTS_NS: + context_type_string = config_event_context_uts_ns; + break; + case LTTNG_UST_CONTEXT_VUID: + context_type_string = config_event_context_vuid; + break; + case LTTNG_UST_CONTEXT_VEUID: + context_type_string = config_event_context_veuid; + break; + case LTTNG_UST_CONTEXT_VSUID: + context_type_string = config_event_context_vsuid; + break; + case LTTNG_UST_CONTEXT_VGID: + context_type_string = config_event_context_vgid; + break; + case LTTNG_UST_CONTEXT_VEGID: + context_type_string = config_event_context_vegid; + break; + case LTTNG_UST_CONTEXT_VSGID: + context_type_string = config_event_context_vsgid; + break; case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER: /* * Error, should not be stored in the XML, perf contexts @@ -433,10 +532,13 @@ int save_kernel_kprobe_event(struct config_writer *writer, case LTTNG_KERNEL_KRETPROBE: addr = event->event->u.kretprobe.addr; offset = event->event->u.kretprobe.offset; - symbol_name = event->event->u.kretprobe.symbol_name; + 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); @@ -445,41 +547,316 @@ int save_kernel_kprobe_event(struct config_writer *writer, goto end; } - if (symbol_name) { + 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; } - if (addr) { - ret = config_writer_write_element_unsigned_int( writer, - config_element_address, addr); + + 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; } - if (offset) { - ret = config_writer_write_element_unsigned_int(writer, - config_element_offset, offset); + /* 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) { @@ -534,6 +911,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, @@ -558,6 +936,12 @@ int save_kernel_event(struct config_writer *writer, goto end; } break; + case LTTNG_KERNEL_UPROBE: + ret = save_kernel_userspace_probe_event(writer, event); + if (ret) { + goto end; + } + break; default: ERR("Unsupported kernel instrumentation type."); ret = LTTNG_ERR_INVALID; @@ -1957,6 +2341,9 @@ int save_session_rotation_schedules(struct config_writer *writer, ret = config_writer_open_element(writer, config_element_rotation_schedules); + if (ret) { + goto end; + } if (session->rotate_timer_period) { ret = save_session_rotation_schedule(writer, LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC, @@ -1993,13 +2380,13 @@ static int save_session(struct ltt_session *session, struct lttng_save_session_attr *attr, lttng_sock_cred *creds) { - int ret, fd; - unsigned int file_opened = 0; /* Indicate if the file has been opened */ - char config_file_path[PATH_MAX]; + int ret, fd = -1; + char config_file_path[LTTNG_PATH_MAX]; size_t len; struct config_writer *writer = NULL; size_t session_name_len; const char *provided_path; + int file_open_flags = O_CREAT | O_WRONLY | O_TRUNC; assert(session); assert(attr); @@ -2010,7 +2397,7 @@ int save_session(struct ltt_session *session, if (!session_access_ok(session, LTTNG_SOCK_GET_UID_CRED(creds), - LTTNG_SOCK_GET_GID_CRED(creds))) { + LTTNG_SOCK_GET_GID_CRED(creds)) || session->destroyed) { ret = LTTNG_ERR_EPERM; goto end; } @@ -2023,7 +2410,7 @@ int save_session(struct ltt_session *session, ret = LTTNG_ERR_SET_URL; goto end; } - strncpy(config_file_path, provided_path, len); + strncpy(config_file_path, provided_path, sizeof(config_file_path)); } else { ssize_t ret_len; char *home_dir = utils_get_user_home_dir( @@ -2067,27 +2454,34 @@ int save_session(struct ltt_session *session, * was done just above. */ config_file_path[len++] = '/'; - strncpy(config_file_path + len, session->name, session_name_len); + strncpy(config_file_path + len, session->name, sizeof(config_file_path) - len); len += session_name_len; strcpy(config_file_path + len, DEFAULT_SESSION_CONFIG_FILE_EXTENSION); len += sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION); config_file_path[len] = '\0'; - if (!access(config_file_path, F_OK) && !attr->overwrite) { - /* File exists, notify the user since the overwrite flag is off. */ - ret = LTTNG_ERR_SAVE_FILE_EXIST; - goto end; + if (!attr->overwrite) { + file_open_flags |= O_EXCL; } - fd = run_as_open(config_file_path, O_CREAT | O_WRONLY | O_TRUNC, + fd = run_as_open(config_file_path, file_open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, LTTNG_SOCK_GET_UID_CRED(creds), LTTNG_SOCK_GET_GID_CRED(creds)); if (fd < 0) { PERROR("Could not create configuration file"); - ret = LTTNG_ERR_SAVE_IO_FAIL; + switch (errno) { + case EEXIST: + ret = LTTNG_ERR_SAVE_FILE_EXIST; + break; + case EACCES: + ret = LTTNG_ERR_EPERM; + break; + default: + ret = LTTNG_ERR_SAVE_IO_FAIL; + break; + } goto end; } - file_opened = 1; writer = config_writer_create(fd, 1); if (!writer) { @@ -2201,12 +2595,12 @@ end: } if (ret) { /* Delete file in case of error */ - if (file_opened && unlink(config_file_path)) { + if ((fd >= 0) && unlink(config_file_path)) { PERROR("Unlinking XML session configuration."); } } - if (file_opened) { + if (fd >= 0) { ret = close(fd); if (ret) { PERROR("Closing XML session configuration"); @@ -2236,6 +2630,7 @@ int cmd_save_sessions(struct lttng_save_session_attr *attr, session_lock(session); ret = save_session(session, attr, creds); session_unlock(session); + session_put(session); if (ret) { goto end; } @@ -2243,10 +2638,13 @@ int cmd_save_sessions(struct lttng_save_session_attr *attr, struct ltt_session_list *list = session_get_list(); cds_list_for_each_entry(session, &list->head, list) { + if (!session_get(session)) { + continue; + } session_lock(session); ret = save_session(session, attr, creds); session_unlock(session); - + session_put(session); /* Don't abort if we don't have the required permissions. */ if (ret && ret != LTTNG_ERR_EPERM) { goto end;