/* * Enabling event using the lttng API. * Note: in case of error only the last error code will be return. */ static int enable_events(char *session_name) { int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS; int error_holder = CMD_SUCCESS, warn = 0, error = 0, success = 1; char *event_name, *channel_name = NULL; struct lttng_event *ev; struct lttng_domain dom; char **exclusion_list = NULL; memset(&dom, 0, sizeof(dom)); ev = lttng_event_create(); if (!ev) { ret = CMD_ERROR; goto error; } if (opt_kernel) { if (opt_loglevel) { WARN("Kernel loglevels are not supported."); } } /* Create lttng domain */ if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; dom.buf_type = LTTNG_BUFFER_GLOBAL; } else if (opt_userspace) { dom.type = LTTNG_DOMAIN_UST; /* Default. */ dom.buf_type = LTTNG_BUFFER_PER_UID; } else if (opt_jul) { dom.type = LTTNG_DOMAIN_JUL; /* Default. */ dom.buf_type = LTTNG_BUFFER_PER_UID; } else if (opt_log4j) { dom.type = LTTNG_DOMAIN_LOG4J; /* Default. */ dom.buf_type = LTTNG_BUFFER_PER_UID; } else if (opt_python) { dom.type = LTTNG_DOMAIN_PYTHON; /* Default. */ dom.buf_type = LTTNG_BUFFER_PER_UID; } else { /* Checked by the caller. */ assert(0); } if (opt_exclude) { switch (dom.type) { case LTTNG_DOMAIN_KERNEL: case LTTNG_DOMAIN_JUL: case LTTNG_DOMAIN_LOG4J: case LTTNG_DOMAIN_PYTHON: ERR("Event name exclusions are not yet implemented for %s events", get_domain_str(dom.type)); ret = CMD_ERROR; goto error; case LTTNG_DOMAIN_UST: /* Exclusions supported */ break; default: assert(0); } } /* * Adding a filter to a probe, function or userspace-probe would be * denied by the kernel tracer as it's not supported at the moment. We * do an early check here to warn the user. */ if (opt_filter && opt_kernel) { switch (opt_event_type) { case LTTNG_EVENT_ALL: case LTTNG_EVENT_TRACEPOINT: case LTTNG_EVENT_SYSCALL: break; case LTTNG_EVENT_PROBE: case LTTNG_EVENT_USERSPACE_PROBE: case LTTNG_EVENT_FUNCTION: ERR("Filter expressions are not supported for %s events", get_event_type_str(opt_event_type)); ret = CMD_ERROR; goto error; default: ret = CMD_UNDEFINED; goto error; } } channel_name = opt_channel_name; handle = lttng_create_handle(session_name, &dom); if (handle == NULL) { ret = -1; goto error; } /* Prepare Mi */ if (lttng_opt_mi) { /* Open a events element */ ret = mi_lttng_writer_open_element(writer, config_element_events); if (ret) { ret = CMD_ERROR; goto error; } } if (opt_enable_all) { /* Default setup for enable all */ if (opt_kernel) { ev->type = opt_event_type; strcpy(ev->name, "*"); /* kernel loglevels not implemented */ ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; } else { ev->type = LTTNG_EVENT_TRACEPOINT; strcpy(ev->name, "*"); ev->loglevel_type = opt_loglevel_type; if (opt_loglevel) { assert(opt_userspace || opt_jul || opt_log4j || opt_python); if (opt_userspace) { ev->loglevel = loglevel_str_to_value(opt_loglevel); } else if (opt_jul) { ev->loglevel = loglevel_jul_str_to_value(opt_loglevel); } else if (opt_log4j) { ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel); } else if (opt_python) { ev->loglevel = loglevel_python_str_to_value(opt_loglevel); } if (ev->loglevel == -1) { ERR("Unknown loglevel %s", opt_loglevel); ret = -LTTNG_ERR_INVALID; goto error; } } else { assert(opt_userspace || opt_jul || opt_log4j || opt_python); if (opt_userspace) { ev->loglevel = -1; } else if (opt_jul) { ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL; } else if (opt_log4j) { ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL; } else if (opt_python) { ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG; } } } if (opt_exclude) { ret = create_exclusion_list_and_validate("*", opt_exclude, &exclusion_list); if (ret) { ret = CMD_ERROR; goto error; } ev->exclusion = 1; warn_on_truncated_exclusion_names(exclusion_list, &warn); } if (!opt_filter) { ret = lttng_enable_event_with_exclusions(handle, ev, channel_name, NULL, exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0, exclusion_list); if (ret < 0) { switch (-ret) { case LTTNG_ERR_KERN_EVENT_EXIST: WARN("Kernel events already enabled (channel %s, session %s)", print_channel_name(channel_name), session_name); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: { const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; ERR("Events: %s (channel %s, session %s)", msg, print_channel_name(channel_name), session_name); error = 1; break; } default: ERR("Events: %s (channel %s, session %s)", lttng_strerror(ret), ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), session_name); error = 1; break; } goto end; } switch (opt_event_type) { case LTTNG_EVENT_TRACEPOINT: if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) { char *exclusion_string = print_exclusions(exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s", get_domain_str(dom.type), exclusion_string, print_channel_name(channel_name), opt_loglevel); free(exclusion_string); } else { char *exclusion_string = print_exclusions(exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } MSG("All %s tracepoints%s are enabled in channel %s", get_domain_str(dom.type), exclusion_string, print_channel_name(channel_name)); free(exclusion_string); } break; case LTTNG_EVENT_SYSCALL: if (opt_kernel) { MSG("All %s system calls are enabled in channel %s", get_domain_str(dom.type), print_channel_name(channel_name)); } break; case LTTNG_EVENT_ALL: if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) { char *exclusion_string = print_exclusions(exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } MSG("All %s events%s are enabled in channel %s for loglevel %s", get_domain_str(dom.type), exclusion_string, print_channel_name(channel_name), opt_loglevel); free(exclusion_string); } else { char *exclusion_string = print_exclusions(exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } MSG("All %s events%s are enabled in channel %s", get_domain_str(dom.type), exclusion_string, print_channel_name(channel_name)); free(exclusion_string); } break; default: /* * We should not be here since lttng_enable_event should have * failed on the event type. */ goto error; } } if (opt_filter) { command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name, opt_filter, exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0, exclusion_list); if (command_ret < 0) { switch (-command_ret) { case LTTNG_ERR_FILTER_EXIST: WARN("Filter on all events is already enabled" " (channel %s, session %s)", print_channel_name(channel_name), session_name); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: { const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; ERR("All events: %s (channel %s, session %s, filter \'%s\')", msg, print_channel_name(channel_name), session_name, opt_filter); error = 1; break; } default: ERR("All events: %s (channel %s, session %s, filter \'%s\')", lttng_strerror(command_ret), command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), session_name, opt_filter); error = 1; break; } error_holder = command_ret; } else { ev->filter = 1; MSG("Filter '%s' successfully set", opt_filter); } } if (lttng_opt_mi) { /* The wildcard * is used for kernel and ust domain to * represent ALL. We copy * in event name to force the wildcard use * for kernel domain * * Note: this is strictly for semantic and printing while in * machine interface mode. */ strcpy(ev->name, "*"); /* If we reach here the events are enabled */ if (!error && !warn) { ev->enabled = 1; } else { ev->enabled = 0; success = 0; } ret = mi_lttng_event(writer, ev, 1, handle->domain.type); if (ret) { ret = CMD_ERROR; goto error; } /* print exclusion */ ret = mi_print_exclusion(exclusion_list); if (ret) { ret = CMD_ERROR; goto error; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto error; } /* Close event element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto error; } } goto end; } /* Strip event list */ event_name = strtok(opt_event_list, ","); while (event_name != NULL) { /* Copy name and type of the event */ strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN); ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; ev->type = opt_event_type; /* Kernel tracer action */ if (opt_kernel) { DBG("Enabling kernel event %s for channel %s", event_name, print_channel_name(channel_name)); switch (opt_event_type) { case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */ /* If event name differs from *, select tracepoint. */ if (strcmp(ev->name, "*")) { ev->type = LTTNG_EVENT_TRACEPOINT; } break; case LTTNG_EVENT_TRACEPOINT: break; case LTTNG_EVENT_PROBE: ret = parse_probe_opts(ev, opt_probe); if (ret) { ERR("Unable to parse probe options"); ret = CMD_ERROR; goto error; } break; case LTTNG_EVENT_USERSPACE_PROBE: ret = parse_userspace_probe_opts(ev, opt_userspace_probe); if (ret) { switch (ret) { case CMD_UNSUPPORTED: /* * Error message describing * what is not supported was * printed in the function. */ break; case CMD_ERROR: default: ERR("Unable to parse userspace probe options"); break; } goto error; } break; case LTTNG_EVENT_FUNCTION: ret = parse_probe_opts(ev, opt_function); if (ret) { ERR("Unable to parse function probe options"); ret = CMD_ERROR; goto error; } break; case LTTNG_EVENT_SYSCALL: ev->type = LTTNG_EVENT_SYSCALL; break; default: ret = CMD_UNDEFINED; goto error; } /* kernel loglevels not implemented */ ev->loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; } else if (opt_userspace) { /* User-space tracer action */ DBG("Enabling UST event %s for channel %s, loglevel %s", event_name, print_channel_name(channel_name), opt_loglevel ? : "<all>"); switch (opt_event_type) { case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */ /* Fall-through */ case LTTNG_EVENT_TRACEPOINT: /* Copy name and type of the event */ ev->type = LTTNG_EVENT_TRACEPOINT; strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN); ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; break; case LTTNG_EVENT_PROBE: case LTTNG_EVENT_FUNCTION: case LTTNG_EVENT_SYSCALL: case LTTNG_EVENT_USERSPACE_PROBE: default: ERR("Event type not available for user-space tracing"); ret = CMD_UNSUPPORTED; goto error; } if (opt_exclude) { ev->exclusion = 1; if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) { ERR("Exclusion option can only be used with tracepoint events"); ret = CMD_ERROR; goto error; } /* Free previously allocated items */ strutils_free_null_terminated_array_of_strings( exclusion_list); exclusion_list = NULL; ret = create_exclusion_list_and_validate( event_name, opt_exclude, &exclusion_list); if (ret) { ret = CMD_ERROR; goto error; } warn_on_truncated_exclusion_names( exclusion_list, &warn); } ev->loglevel_type = opt_loglevel_type; if (opt_loglevel) { ev->loglevel = loglevel_str_to_value(opt_loglevel); if (ev->loglevel == -1) { ERR("Unknown loglevel %s", opt_loglevel); ret = -LTTNG_ERR_INVALID; goto error; } } else { ev->loglevel = -1; } } else if (opt_jul || opt_log4j || opt_python) { if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) { ERR("Event type not supported for domain."); ret = CMD_UNSUPPORTED; goto error; } ev->loglevel_type = opt_loglevel_type; if (opt_loglevel) { if (opt_jul) { ev->loglevel = loglevel_jul_str_to_value(opt_loglevel); } else if (opt_log4j) { ev->loglevel = loglevel_log4j_str_to_value(opt_loglevel); } else if (opt_python) { ev->loglevel = loglevel_python_str_to_value(opt_loglevel); } if (ev->loglevel == -1) { ERR("Unknown loglevel %s", opt_loglevel); ret = -LTTNG_ERR_INVALID; goto error; } } else { if (opt_jul) { ev->loglevel = LTTNG_LOGLEVEL_JUL_ALL; } else if (opt_log4j) { ev->loglevel = LTTNG_LOGLEVEL_LOG4J_ALL; } else if (opt_python) { ev->loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG; } } ev->type = LTTNG_EVENT_TRACEPOINT; strncpy(ev->name, event_name, LTTNG_SYMBOL_NAME_LEN); ev->name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; } else { assert(0); } if (!opt_filter) { char *exclusion_string; command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name, NULL, exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0, exclusion_list); exclusion_string = print_exclusions(exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } if (command_ret < 0) { /* Turn ret to positive value to handle the positive error code */ switch (-command_ret) { case LTTNG_ERR_KERN_EVENT_EXIST: WARN("Kernel event %s%s already enabled (channel %s, session %s)", event_name, exclusion_string, print_channel_name(channel_name), session_name); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: { const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; ERR("Event %s%s: %s (channel %s, session %s)", event_name, exclusion_string, msg, print_channel_name(channel_name), session_name); error = 1; break; } case LTTNG_ERR_SDT_PROBE_SEMAPHORE: ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)", event_name, print_channel_name(channel_name), session_name); error = 1; break; default: ERR("Event %s%s: %s (channel %s, session %s)", event_name, exclusion_string, lttng_strerror(command_ret), command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), session_name); error = 1; break; } error_holder = command_ret; } else { switch (dom.type) { case LTTNG_DOMAIN_KERNEL: case LTTNG_DOMAIN_UST: MSG("%s event %s%s created in channel %s", get_domain_str(dom.type), event_name, exclusion_string, print_channel_name(channel_name)); break; case LTTNG_DOMAIN_JUL: case LTTNG_DOMAIN_LOG4J: case LTTNG_DOMAIN_PYTHON: /* * Don't print the default channel * name for agent domains. */ MSG("%s event %s%s enabled", get_domain_str(dom.type), event_name, exclusion_string); break; default: assert(0); } } free(exclusion_string); } if (opt_filter) { char *exclusion_string; /* Filter present */ ev->filter = 1; command_ret = lttng_enable_event_with_exclusions(handle, ev, channel_name, opt_filter, exclusion_list ? strutils_array_of_strings_len(exclusion_list) : 0, exclusion_list); exclusion_string = print_exclusions(exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } if (command_ret < 0) { switch (-command_ret) { case LTTNG_ERR_FILTER_EXIST: WARN("Filter on event %s%s is already enabled" " (channel %s, session %s)", event_name, exclusion_string, print_channel_name(channel_name), session_name); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: { const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name, exclusion_string, msg, print_channel_name(channel_name), session_name, opt_filter); error = 1; break; } default: ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev->name, exclusion_string, lttng_strerror(command_ret), command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), session_name, opt_filter); error = 1; break; } error_holder = command_ret; } else { MSG("Event %s%s: Filter '%s' successfully set", event_name, exclusion_string, opt_filter); } free(exclusion_string); } if (lttng_opt_mi) { if (command_ret) { success = 0; ev->enabled = 0; } else { ev->enabled = 1; } ret = mi_lttng_event(writer, ev, 1, handle->domain.type); if (ret) { ret = CMD_ERROR; goto error; } /* print exclusion */ ret = mi_print_exclusion(exclusion_list); if (ret) { ret = CMD_ERROR; goto error; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Close event element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } } /* Next event */ event_name = strtok(NULL, ","); /* Reset warn, error and success */ success = 1; }
/* * Enabling event using the lttng API. * Note: in case of error only the last error code will be return. */ static int enable_events(char *session_name) { int ret = CMD_SUCCESS, command_ret = CMD_SUCCESS; int error_holder = CMD_SUCCESS, warn = 0, error = 0, success = 1; char *event_name, *channel_name = NULL; struct lttng_event ev; struct lttng_domain dom; int exclusion_count = 0; char **exclusion_list = NULL; memset(&ev, 0, sizeof(ev)); memset(&dom, 0, sizeof(dom)); if (opt_kernel) { if (opt_filter) { ERR("Filter not implement for kernel tracing yet"); ret = CMD_ERROR; goto error; } if (opt_loglevel) { WARN("Kernel loglevels are not supported."); } } /* Create lttng domain */ if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; dom.buf_type = LTTNG_BUFFER_GLOBAL; } else if (opt_userspace) { dom.type = LTTNG_DOMAIN_UST; /* Default. */ dom.buf_type = LTTNG_BUFFER_PER_UID; } else if (opt_jul) { dom.type = LTTNG_DOMAIN_JUL; /* Default. */ dom.buf_type = LTTNG_BUFFER_PER_UID; } else if (opt_log4j) { dom.type = LTTNG_DOMAIN_LOG4J; /* Default. */ dom.buf_type = LTTNG_BUFFER_PER_UID; } else if (opt_python) { dom.type = LTTNG_DOMAIN_PYTHON; /* Default. */ dom.buf_type = LTTNG_BUFFER_PER_UID; } else { print_missing_domain(); ret = CMD_ERROR; goto error; } if (opt_kernel && opt_exclude) { ERR("Event name exclusions are not yet implemented for kernel events"); ret = CMD_ERROR; goto error; } channel_name = opt_channel_name; handle = lttng_create_handle(session_name, &dom); if (handle == NULL) { ret = -1; goto error; } /* Prepare Mi */ if (lttng_opt_mi) { /* Open a events element */ ret = mi_lttng_writer_open_element(writer, config_element_events); if (ret) { ret = CMD_ERROR; goto error; } } if (opt_enable_all) { /* Default setup for enable all */ if (opt_kernel) { ev.type = opt_event_type; ev.name[0] = '\0'; /* kernel loglevels not implemented */ ev.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; } else { ev.type = LTTNG_EVENT_TRACEPOINT; strcpy(ev.name, "*"); ev.loglevel_type = opt_loglevel_type; if (opt_loglevel) { assert(opt_userspace || opt_jul || opt_log4j || opt_python); if (opt_userspace) { ev.loglevel = loglevel_str_to_value(opt_loglevel); } else if (opt_jul) { ev.loglevel = loglevel_jul_str_to_value(opt_loglevel); } else if (opt_log4j) { ev.loglevel = loglevel_log4j_str_to_value(opt_loglevel); } else if (opt_python) { ev.loglevel = loglevel_python_str_to_value(opt_loglevel); } if (ev.loglevel == -1) { ERR("Unknown loglevel %s", opt_loglevel); ret = -LTTNG_ERR_INVALID; goto error; } } else { assert(opt_userspace || opt_jul || opt_log4j || opt_python); if (opt_userspace) { ev.loglevel = -1; } else if (opt_jul || opt_log4j) { ev.loglevel = LTTNG_LOGLEVEL_JUL_ALL; } else if (opt_python) { ev.loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG; } } } if (opt_exclude) { ret = check_exclusion_subsets("*", opt_exclude, &exclusion_count, &exclusion_list); if (ret == CMD_ERROR) { goto error; } ev.exclusion = 1; } if (!opt_filter) { ret = lttng_enable_event_with_exclusions(handle, &ev, channel_name, NULL, exclusion_count, exclusion_list); if (ret < 0) { switch (-ret) { case LTTNG_ERR_KERN_EVENT_EXIST: WARN("Kernel events already enabled (channel %s, session %s)", print_channel_name(channel_name), session_name); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: { const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; ERR("Events: %s (channel %s, session %s)", msg, print_channel_name(channel_name), session_name); error = 1; break; } default: ERR("Events: %s (channel %s, session %s)", lttng_strerror(ret), ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), session_name); error = 1; break; } goto end; } switch (opt_event_type) { case LTTNG_EVENT_TRACEPOINT: if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) { char *exclusion_string = print_exclusions(exclusion_count, exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s", get_domain_str(dom.type), exclusion_string, print_channel_name(channel_name), opt_loglevel); free(exclusion_string); } else { char *exclusion_string = print_exclusions(exclusion_count, exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } MSG("All %s tracepoints%s are enabled in channel %s", get_domain_str(dom.type), exclusion_string, print_channel_name(channel_name)); free(exclusion_string); } break; case LTTNG_EVENT_SYSCALL: if (opt_kernel) { MSG("All %s system calls are enabled in channel %s", get_domain_str(dom.type), print_channel_name(channel_name)); } break; case LTTNG_EVENT_ALL: if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) { char *exclusion_string = print_exclusions(exclusion_count, exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } MSG("All %s events%s are enabled in channel %s for loglevel %s", get_domain_str(dom.type), exclusion_string, print_channel_name(channel_name), opt_loglevel); free(exclusion_string); } else { char *exclusion_string = print_exclusions(exclusion_count, exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } MSG("All %s events%s are enabled in channel %s", get_domain_str(dom.type), exclusion_string, print_channel_name(channel_name)); free(exclusion_string); } break; default: /* * We should not be here since lttng_enable_event should have * failed on the event type. */ goto error; } } if (opt_filter) { command_ret = lttng_enable_event_with_exclusions(handle, &ev, channel_name, opt_filter, exclusion_count, exclusion_list); if (command_ret < 0) { switch (-command_ret) { case LTTNG_ERR_FILTER_EXIST: WARN("Filter on all events is already enabled" " (channel %s, session %s)", print_channel_name(channel_name), session_name); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: { const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; ERR("All events: %s (channel %s, session %s, filter \'%s\')", msg, print_channel_name(channel_name), session_name, opt_filter); error = 1; break; } default: ERR("All events: %s (channel %s, session %s, filter \'%s\')", lttng_strerror(command_ret), command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), session_name, opt_filter); error = 1; break; } error_holder = command_ret; } else { ev.filter = 1; MSG("Filter '%s' successfully set", opt_filter); } } if (lttng_opt_mi) { /* The wildcard * is used for kernel and ust domain to * represent ALL. We copy * in event name to force the wildcard use * for kernel domain * * Note: this is strictly for semantic and printing while in * machine interface mode. */ strcpy(ev.name, "*"); /* If we reach here the events are enabled */ if (!error && !warn) { ev.enabled = 1; } else { ev.enabled = 0; success = 0; } ret = mi_lttng_event(writer, &ev, 1, handle->domain.type); if (ret) { ret = CMD_ERROR; goto error; } /* print exclusion */ ret = mi_print_exclusion(exclusion_count, exclusion_list); if (ret) { ret = CMD_ERROR; goto error; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto error; } /* Close event element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto error; } } goto end; } /* Strip event list */ event_name = strtok(opt_event_list, ","); while (event_name != NULL) { /* Copy name and type of the event */ strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN); ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; ev.type = opt_event_type; /* Kernel tracer action */ if (opt_kernel) { DBG("Enabling kernel event %s for channel %s", event_name, print_channel_name(channel_name)); switch (opt_event_type) { case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */ ev.type = LTTNG_EVENT_TRACEPOINT; /* Fall-through */ case LTTNG_EVENT_TRACEPOINT: break; case LTTNG_EVENT_PROBE: ret = parse_probe_opts(&ev, opt_probe); if (ret) { ERR("Unable to parse probe options"); ret = 0; goto error; } break; case LTTNG_EVENT_FUNCTION: ret = parse_probe_opts(&ev, opt_function); if (ret) { ERR("Unable to parse function probe options"); ret = 0; goto error; } break; case LTTNG_EVENT_FUNCTION_ENTRY: strncpy(ev.attr.ftrace.symbol_name, opt_function_entry_symbol, LTTNG_SYMBOL_NAME_LEN); ev.attr.ftrace.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; break; case LTTNG_EVENT_SYSCALL: ev.type = LTTNG_EVENT_SYSCALL; break; default: ret = CMD_UNDEFINED; goto error; } /* kernel loglevels not implemented */ ev.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; } else if (opt_userspace) { /* User-space tracer action */ #if 0 if (opt_cmd_name != NULL || opt_pid) { MSG("Only supporting tracing all UST processes (-u) for now."); ret = CMD_UNDEFINED; goto error; } #endif DBG("Enabling UST event %s for channel %s, loglevel %s", event_name, print_channel_name(channel_name), opt_loglevel ? : "<all>"); switch (opt_event_type) { case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */ /* Fall-through */ case LTTNG_EVENT_TRACEPOINT: /* Copy name and type of the event */ ev.type = LTTNG_EVENT_TRACEPOINT; strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN); ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; break; case LTTNG_EVENT_PROBE: case LTTNG_EVENT_FUNCTION: case LTTNG_EVENT_FUNCTION_ENTRY: case LTTNG_EVENT_SYSCALL: default: ERR("Event type not available for user-space tracing"); ret = CMD_UNSUPPORTED; goto error; } if (opt_exclude) { ev.exclusion = 1; if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) { ERR("Exclusion option can only be used with tracepoint events"); ret = CMD_ERROR; goto error; } /* Free previously allocated items */ if (exclusion_list != NULL) { while (exclusion_count--) { free(exclusion_list[exclusion_count]); } free(exclusion_list); exclusion_list = NULL; } /* Check for proper subsets */ ret = check_exclusion_subsets(event_name, opt_exclude, &exclusion_count, &exclusion_list); if (ret == CMD_ERROR) { goto error; } } ev.loglevel_type = opt_loglevel_type; if (opt_loglevel) { ev.loglevel = loglevel_str_to_value(opt_loglevel); if (ev.loglevel == -1) { ERR("Unknown loglevel %s", opt_loglevel); ret = -LTTNG_ERR_INVALID; goto error; } } else { ev.loglevel = -1; } } else if (opt_jul || opt_log4j || opt_python) { if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) { ERR("Event type not supported for domain."); ret = CMD_UNSUPPORTED; goto error; } ev.loglevel_type = opt_loglevel_type; if (opt_loglevel) { if (opt_jul) { ev.loglevel = loglevel_jul_str_to_value(opt_loglevel); } else if (opt_log4j) { ev.loglevel = loglevel_log4j_str_to_value(opt_loglevel); } else if (opt_python) { ev.loglevel = loglevel_python_str_to_value(opt_loglevel); } if (ev.loglevel == -1) { ERR("Unknown loglevel %s", opt_loglevel); ret = -LTTNG_ERR_INVALID; goto error; } } else { if (opt_jul) { ev.loglevel = LTTNG_LOGLEVEL_JUL_ALL; } else if (opt_log4j) { ev.loglevel = LTTNG_LOGLEVEL_LOG4J_ALL; } else if (opt_python) { ev.loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG; } } ev.type = LTTNG_EVENT_TRACEPOINT; strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN); ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; } else { print_missing_domain(); ret = CMD_ERROR; goto error; } if (!opt_filter) { char *exclusion_string; command_ret = lttng_enable_event_with_exclusions(handle, &ev, channel_name, NULL, exclusion_count, exclusion_list); exclusion_string = print_exclusions(exclusion_count, exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } if (command_ret < 0) { /* Turn ret to positive value to handle the positive error code */ switch (-command_ret) { case LTTNG_ERR_KERN_EVENT_EXIST: WARN("Kernel event %s%s already enabled (channel %s, session %s)", event_name, exclusion_string, print_channel_name(channel_name), session_name); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: { const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; ERR("Event %s%s: %s (channel %s, session %s)", event_name, exclusion_string, msg, print_channel_name(channel_name), session_name); error = 1; break; } default: ERR("Event %s%s: %s (channel %s, session %s)", event_name, exclusion_string, lttng_strerror(command_ret), command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), session_name); error = 1; break; } error_holder = command_ret; } else { /* So we don't print the default channel name for agent domain. */ if (dom.type == LTTNG_DOMAIN_JUL || dom.type == LTTNG_DOMAIN_LOG4J) { MSG("%s event %s%s enabled.", get_domain_str(dom.type), event_name, exclusion_string); } else { MSG("%s event %s%s created in channel %s", get_domain_str(dom.type), event_name, exclusion_string, print_channel_name(channel_name)); } } free(exclusion_string); } if (opt_filter) { char *exclusion_string; /* Filter present */ ev.filter = 1; command_ret = lttng_enable_event_with_exclusions(handle, &ev, channel_name, opt_filter, exclusion_count, exclusion_list); exclusion_string = print_exclusions(exclusion_count, exclusion_list); if (!exclusion_string) { PERROR("Cannot allocate exclusion_string"); error = 1; goto end; } if (command_ret < 0) { switch (-command_ret) { case LTTNG_ERR_FILTER_EXIST: WARN("Filter on event %s%s is already enabled" " (channel %s, session %s)", event_name, exclusion_string, print_channel_name(channel_name), session_name); warn = 1; break; case LTTNG_ERR_TRACE_ALREADY_STARTED: { const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev.name, exclusion_string, msg, print_channel_name(channel_name), session_name, opt_filter); error = 1; break; } default: ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev.name, exclusion_string, lttng_strerror(command_ret), command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME ? print_raw_channel_name(channel_name) : print_channel_name(channel_name), session_name, opt_filter); error = 1; break; } error_holder = command_ret; } else { MSG("Event %s%s: Filter '%s' successfully set", event_name, exclusion_string, opt_filter); } free(exclusion_string); } if (lttng_opt_mi) { if (command_ret) { success = 0; ev.enabled = 0; } else { ev.enabled = 1; } ret = mi_lttng_event(writer, &ev, 1, handle->domain.type); if (ret) { ret = CMD_ERROR; goto error; } /* print exclusion */ ret = mi_print_exclusion(exclusion_count, exclusion_list); if (ret) { ret = CMD_ERROR; goto error; } /* Success ? */ ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_command_success, success); if (ret) { ret = CMD_ERROR; goto end; } /* Close event element */ ret = mi_lttng_writer_close_element(writer); if (ret) { ret = CMD_ERROR; goto end; } } /* Next event */ event_name = strtok(NULL, ","); /* Reset warn, error and success */ success = 1; }