示例#1
0
/*
 * List JUL events for a specific session using the handle.
 *
 * Return CMD_SUCCESS on success else a negative value.
 */
static int list_session_jul_events(void)
{
	int ret, count, i;
	struct lttng_event *events = NULL;

	count = lttng_list_events(handle, "", &events);
	if (count < 0) {
		ret = count;
		ERR("%s", lttng_strerror(ret));
		goto error;
	}

	MSG("Events (Logger name):\n---------------------");
	if (count == 0) {
		MSG("%sNone\n", indent6);
		goto end;
	}

	for (i = 0; i < count; i++) {
		MSG("%s- %s%s", indent4, events[i].name,
				enabled_string(events[i].enabled));
	}

	MSG("");

end:
	free(events);
	ret = CMD_SUCCESS;

error:
	return ret;
}
示例#2
0
/*
 * List events of channel of session and domain.
 */
static int list_events(const char *channel_name)
{
	int ret, count, i;
	struct lttng_event *events = NULL;

	count = lttng_list_events(handle, channel_name, &events);
	if (count < 0) {
		ret = count;
		ERR("%s", lttng_strerror(ret));
		goto error;
	}

	MSG("\n%sEvents:", indent4);
	if (count == 0) {
		MSG("%sNone\n", indent6);
		goto end;
	}

	for (i = 0; i < count; i++) {
		print_events(&events[i]);
	}

	MSG("");

end:
	free(events);
	ret = CMD_SUCCESS;

error:
	return ret;
}
示例#3
0
/*
 * destroy_session
 *
 * Unregister the provided session to the session daemon. On success, removes
 * the default configuration.
 */
static int destroy_session(struct lttng_session *session)
{
	int ret;

	ret = lttng_destroy_session(session->name);
	if (ret < 0) {
		switch (-ret) {
		case LTTNG_ERR_SESS_NOT_FOUND:
			WARN("Session name %s not found", session->name);
			break;
		default:
			ERR("%s", lttng_strerror(ret));
			break;
		}
		goto error;
	}

	MSG("Session %s destroyed", session->name);
	config_destroy_default();

	if (lttng_opt_mi) {
		ret = mi_lttng_session(writer, session, 0);
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	}

	ret = CMD_SUCCESS;
error:
	return ret;
}
示例#4
0
/*
 * List available domain(s) for a session.
 */
static int list_domains(const char *session_name)
{
	int i, count, ret = CMD_SUCCESS;
	struct lttng_domain *domains = NULL;


	count = lttng_list_domains(session_name, &domains);
	if (count < 0) {
		ret = CMD_ERROR;
		ERR("%s", lttng_strerror(count));
		goto end;
	}

	if (lttng_opt_mi) {
		/* Mi output */
		ret = mi_list_domains(domains, count);
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	} else {
		/* Pretty print */
		MSG("Domains:\n-------------");
		if (count == 0) {
			MSG("  None");
			goto end;
		}

		for (i = 0; i < count; i++) {
			switch (domains[i].type) {
			case LTTNG_DOMAIN_KERNEL:
				MSG("  - Kernel");
				break;
			case LTTNG_DOMAIN_UST:
				MSG("  - UST global");
				break;
			case LTTNG_DOMAIN_JUL:
				MSG("  - JUL (Java Util Logging)");
				break;
			case LTTNG_DOMAIN_LOG4J:
				MSG("  - LOG4j (Logging for Java)");
				break;
			case LTTNG_DOMAIN_PYTHON:
				MSG("  - Python (logging)");
				break;
			default:
				break;
			}
		}
	}

error:
	free(domains);

end:
	return ret;
}
示例#5
0
/*
 *  set_session
 */
static int set_session(void)
{
	int ret = CMD_SUCCESS;
	int count, i;
	unsigned int session_found = 0;
	struct lttng_session *sessions;

	if (opt_session_name && strlen(opt_session_name) > NAME_MAX) {
		ERR("Session name too long. Length must be lower or equal to %d",
			NAME_MAX);
		ret = CMD_ERROR;
		goto end;
	}

	count = lttng_list_sessions(&sessions);
	if (count < 0) {
		ret = CMD_ERROR;
		ERR("%s", lttng_strerror(count));
		goto end;
	}

	for (i = 0; i < count; i++) {
		if (strncmp(sessions[i].name, opt_session_name, NAME_MAX) == 0) {
			session_found = 1;
			break;
		}
	}

	if (!session_found) {
		ERR("Session '%s' not found", opt_session_name);
		ret = CMD_ERROR;
		goto error;
	}

	ret = config_init(opt_session_name);
	if (ret < 0) {
		ERR("Unable to set session name");
		ret = CMD_ERROR;
		goto error;
	}

	MSG("Session set to %s", opt_session_name);
	if (lttng_opt_mi) {
		ret = mi_print(opt_session_name);
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	}

	ret = CMD_SUCCESS;

error:
	free(sessions);
end:
	return ret;
}
示例#6
0
/*
 * List available tracing session. List only basic information.
 *
 * If session_name is NULL, all sessions are listed.
 */
static int list_sessions(const char *session_name)
{
	int ret, count, i;
	unsigned int session_found = 0;
	struct lttng_session *sessions;

	count = lttng_list_sessions(&sessions);
	DBG("Session count %d", count);
	if (count < 0) {
		ret = count;
		ERR("%s", lttng_strerror(ret));
		goto error;
	} else if (count == 0) {
		MSG("Currently no available tracing session");
		goto end;
	}

	if (session_name == NULL) {
		MSG("Available tracing sessions:");
	}

	for (i = 0; i < count; i++) {
		if (session_name != NULL) {
			if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) {
				session_found = 1;
				MSG("Tracing session %s: [%s%s]", session_name,
						active_string(sessions[i].enabled),
						snapshot_string(sessions[i].snapshot_mode));
				MSG("%sTrace path: %s\n", indent4, sessions[i].path);
				break;
			}
		} else {
			MSG("  %d) %s (%s) [%s%s]", i + 1, sessions[i].name, sessions[i].path,
					active_string(sessions[i].enabled),
					snapshot_string(sessions[i].snapshot_mode));
		}
	}

	free(sessions);

	if (!session_found && session_name != NULL) {
		ERR("Session '%s' not found", session_name);
		ret = CMD_ERROR;
		goto error;
	}

	if (session_name == NULL) {
		MSG("\nUse lttng list <session_name> for more details");
	}

end:
	return CMD_SUCCESS;

error:
	return ret;
}
示例#7
0
/*
 * Ask session daemon for all user space tracepoints available.
 */
static int list_ust_events(void)
{
	int i, size;
	struct lttng_domain domain;
	struct lttng_handle *handle;
	struct lttng_event *event_list;
	pid_t cur_pid = 0;
	char *cmdline = NULL;

	memset(&domain, 0, sizeof(domain));

	DBG("Getting UST tracing events");

	domain.type = LTTNG_DOMAIN_UST;

	handle = lttng_create_handle(NULL, &domain);
	if (handle == NULL) {
		goto error;
	}

	size = lttng_list_tracepoints(handle, &event_list);
	if (size < 0) {
		ERR("Unable to list UST events: %s", lttng_strerror(size));
		lttng_destroy_handle(handle);
		return size;
	}

	MSG("UST events:\n-------------");

	if (size == 0) {
		MSG("None");
	}

	for (i = 0; i < size; i++) {
		if (cur_pid != event_list[i].pid) {
			cur_pid = event_list[i].pid;
			cmdline = get_cmdline_by_pid(cur_pid);
			MSG("\nPID: %d - Name: %s", cur_pid, cmdline);
			free(cmdline);
		}
		print_events(&event_list[i]);
	}

	MSG("");

	free(event_list);
	lttng_destroy_handle(handle);

	return CMD_SUCCESS;

error:
	lttng_destroy_handle(handle);
	return -1;
}
示例#8
0
/*
 * Ask for all trace events in the kernel
 */
static int list_kernel_events(void)
{
	int i, size, ret = CMD_SUCCESS;
	struct lttng_domain domain;
	struct lttng_handle *handle;
	struct lttng_event *event_list;

	memset(&domain, 0, sizeof(domain));

	DBG("Getting kernel tracing events");

	domain.type = LTTNG_DOMAIN_KERNEL;

	handle = lttng_create_handle(NULL, &domain);
	if (handle == NULL) {
		ret = CMD_ERROR;
		goto error;
	}

	size = lttng_list_tracepoints(handle, &event_list);
	if (size < 0) {
		ERR("Unable to list kernel events: %s", lttng_strerror(size));
		lttng_destroy_handle(handle);
		return CMD_ERROR;
	}

	if (lttng_opt_mi) {
		/* Mi print */
		ret = mi_list_kernel_events(event_list, size, &domain);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	} else {
		MSG("Kernel events:\n-------------");

		for (i = 0; i < size; i++) {
			print_events(&event_list[i]);
		}

		MSG("");
	}

end:
	free(event_list);

	lttng_destroy_handle(handle);
	return ret;

error:
	lttng_destroy_handle(handle);
	return ret;
}
示例#9
0
/*
 * Retrieve the created session and mi output it based on provided argument
 * This is currently a summary of what was pretty printed and is subject to
 * enhancements.
 */
static int mi_created_session(const char *session_name)
{
	int ret, i, count, found;
	struct lttng_session *sessions;

	/* session_name should not be null */
	assert(session_name);
	assert(writer);

	count = lttng_list_sessions(&sessions);
	if (count < 0) {
		ret = count;
		ERR("%s", lttng_strerror(ret));
		goto error;
	}

	if (count == 0) {
		ERR("Error session creation failed: session %s not found", session_name);
		ret = -LTTNG_ERR_SESS_NOT_FOUND;
		goto end;
	}

	found = 0;
	for (i = 0; i < count; i++) {
		if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) {
			found = 1;
			ret = mi_lttng_session(writer, &sessions[i], 0);
			if (ret) {
				goto error;
			}
			break;
		}
	}

	if (!found) {
		ret = -LTTNG_ERR_SESS_NOT_FOUND;
	} else {
		ret = CMD_SUCCESS;
	}

error:
	free(sessions);
end:
	return ret;
}
示例#10
0
/*
 * List agent events for a specific session using the handle.
 *
 * Return CMD_SUCCESS on success else a negative value.
 */
static int list_session_agent_events(void)
{
	int ret = CMD_SUCCESS, count, i;
	struct lttng_event *events = NULL;

	count = lttng_list_events(handle, "", &events);
	if (count < 0) {
		ret = CMD_ERROR;
		ERR("%s", lttng_strerror(count));
		goto error;
	}

	if (lttng_opt_mi) {
		/* Mi print */
		ret = mi_list_session_agent_events(events, count);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	} else {
		/* Pretty print */
		MSG("Events (Logger name):\n---------------------");
		if (count == 0) {
			MSG("%sNone\n", indent6);
			goto end;
		}

		for (i = 0; i < count; i++) {
			MSG("%s- %s%s (loglevel%s %s)", indent4, events[i].name,
					enabled_string(events[i].enabled),
					logleveltype_string(events[i].loglevel_type),
					mi_lttng_loglevel_string(events[i].loglevel,
						handle->domain.type));
		}

		MSG("");
	}

end:
	free(events);
error:
	return ret;
}
示例#11
0
/*
 * destroy_all_sessions
 *
 * Call destroy_sessions for each registered sessions
 */
static int destroy_all_sessions(struct lttng_session *sessions, int count)
{
	int i, ret = CMD_SUCCESS;

	if (count == 0) {
		MSG("No session found, nothing to do.");
	} else if (count < 0) {
		ERR("%s", lttng_strerror(ret));
		goto error;
	}

	for (i = 0; i < count; i++) {
		ret = destroy_session(&sessions[i]);
		if (ret < 0) {
			goto error;
		}
	}
error:
	return ret;
}
示例#12
0
/*
 * List available domain(s) for a session.
 */
static int list_domains(const char *session_name)
{
	int i, count, ret = CMD_SUCCESS;
	struct lttng_domain *domains = NULL;

	MSG("Domains:\n-------------");

	count = lttng_list_domains(session_name, &domains);
	if (count < 0) {
		ret = count;
		ERR("%s", lttng_strerror(ret));
		goto error;
	} else if (count == 0) {
		MSG("  None");
		goto end;
	}

	for (i = 0; i < count; i++) {
		switch (domains[i].type) {
		case LTTNG_DOMAIN_KERNEL:
			MSG("  - Kernel");
			break;
		case LTTNG_DOMAIN_UST:
			MSG("  - UST global");
			break;
		case LTTNG_DOMAIN_JUL:
			MSG("  - JUL (Java Util Logging)");
			break;
		default:
			break;
		}
	}

end:
	free(domains);

error:
	return ret;
}
示例#13
0
/*
 * Ask for kernel system calls.
 */
static int list_syscalls(void)
{
	int i, size, ret = CMD_SUCCESS;
	struct lttng_event *event_list;

	DBG("Getting kernel system call events");

	size = lttng_list_syscalls(&event_list);
	if (size < 0) {
		ERR("Unable to list system calls: %s", lttng_strerror(size));
		ret = CMD_ERROR;
		goto error;
	}

	if (lttng_opt_mi) {
		/* Mi print */
		ret = mi_list_syscalls(event_list, size);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	} else {
		MSG("System calls:\n-------------");

		for (i = 0; i < size; i++) {
			print_events(&event_list[i]);
		}

		MSG("");
	}

end:
	free(event_list);
	return ret;

error:
	return ret;
}
示例#14
0
/*
 * List events of channel of session and domain.
 */
static int list_events(const char *channel_name)
{
	int ret = CMD_SUCCESS, count, i;
	struct lttng_event *events = NULL;

	count = lttng_list_events(handle, channel_name, &events);
	if (count < 0) {
		ret = CMD_ERROR;
		ERR("%s", lttng_strerror(count));
		goto error;
	}

	if (lttng_opt_mi) {
		/* Mi print */
		ret = mi_list_events(events, count);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	} else {
		/* Pretty print */
		MSG("\n%sEvents:", indent4);
		if (count == 0) {
			MSG("%sNone\n", indent6);
			goto end;
		}

		for (i = 0; i < count; i++) {
			print_events(&events[i]);
		}

		MSG("");
	}
end:
	free(events);
error:
	return ret;
}
示例#15
0
/*
 *  disable_events
 *
 *  Disabling event using the lttng API.
 */
static int disable_events(char *session_name)
{
	int ret = CMD_SUCCESS, warn = 0, command_ret = CMD_SUCCESS;
	int enabled = 1, success = 1;
	char *event_name, *channel_name = NULL;
	struct lttng_domain dom;
	struct lttng_event event;

	memset(&dom, 0, sizeof(dom));

	/* Create lttng domain */
	if (opt_kernel) {
		dom.type = LTTNG_DOMAIN_KERNEL;
	} else if (opt_userspace) {
		dom.type = LTTNG_DOMAIN_UST;
	} else if (opt_jul) {
		dom.type = LTTNG_DOMAIN_JUL;
	} else if (opt_log4j) {
		dom.type = LTTNG_DOMAIN_LOG4J;
	} else if (opt_python) {
		dom.type = LTTNG_DOMAIN_PYTHON;
	} else {
		/* Checked by the caller. */
		assert(0);
	}

	channel_name = opt_channel_name;

	handle = lttng_create_handle(session_name, &dom);
	if (handle == NULL) {
		ret = -1;
		goto error;
	}

	/* Mi print the channel and open the events element */
	if (lttng_opt_mi) {
		ret = mi_lttng_writer_open_element(writer, config_element_channel);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		ret = mi_lttng_writer_write_element_string(writer,
				config_element_name, print_channel_name(channel_name));
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Open events element */
		ret = mi_lttng_writer_open_element(writer, config_element_events);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}

	memset(&event, 0, sizeof(event));
	/* Set default loglevel to any/unknown */
	event.loglevel = -1;

	/* opt_event_type contain the event type to disable at this point */
	event.type = opt_event_type;

	if (opt_disable_all) {
		command_ret = lttng_disable_event_ext(handle, &event, channel_name, NULL);
		if (command_ret < 0) {
			ERR("%s", lttng_strerror(command_ret));
			enabled = 1;
			success = 0;

		} else {
			enabled = 0;
			success = 1;
			MSG("All %s events of type %s are disabled in channel %s",
					get_domain_str(dom.type),
					print_event_type(opt_event_type),
					print_channel_name(channel_name));
		}

		if (lttng_opt_mi) {
			ret = mi_print_event("*", enabled, success);
			if (ret) {
				ret = CMD_ERROR;
				goto error;
			}
		}
	} else {
		/* Strip event list */
		event_name = strtok(opt_event_list, ",");
		while (event_name != NULL) {
			DBG("Disabling event %s", event_name);

			strncpy(event.name, event_name, sizeof(event.name));
			event.name[sizeof(event.name) - 1] = '\0';
			command_ret = lttng_disable_event_ext(handle, &event, channel_name, NULL);
			if (command_ret < 0) {
				ERR("%s of type %s : %s (channel %s, session %s)",
						event_name,
						print_event_type(opt_event_type),
						lttng_strerror(command_ret),
						command_ret == -LTTNG_ERR_NEED_CHANNEL_NAME
							? print_raw_channel_name(channel_name)
							: print_channel_name(channel_name),
						session_name);
				warn = 1;
				success = 0;
				/*
				 * If an error occurred we assume that the event is still
				 * enabled.
				 */
				enabled = 1;
			} else {
				MSG("%s %s of type %s disabled in channel %s for session %s",
						get_domain_str(dom.type),
						event_name,
						print_event_type(opt_event_type),
						print_channel_name(channel_name),
						session_name);
				success = 1;
				enabled = 0;
			}

			if (lttng_opt_mi) {
				ret = mi_print_event(event_name, enabled, success);
				if (ret) {
					ret = CMD_ERROR;
					goto error;
				}
			}

			/* Next event */
			event_name = strtok(NULL, ",");
		}
	}

end:
	if (lttng_opt_mi) {
		/* Close events element and channel element */
		ret = mi_lttng_close_multi_element(writer, 2);
		if (ret) {
			ret = CMD_ERROR;
		}
	}
error:
	/* if there is already an error preserve it */
	if (warn && !ret) {
		ret = CMD_WARNING;
	}

	/* Overwrite ret if an error occurred */
	ret = command_ret ? command_ret : ret;

	lttng_destroy_handle(handle);
	return ret;
}
示例#16
0
/*
 * 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;
	}
示例#17
0
/*
 * 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;
	}
示例#18
0
static
enum cmd_error_code track_untrack_pid(enum cmd_type cmd_type, const char *cmd_str,
		const char *session_name, const char *pid_string,
		int all, struct mi_writer *writer)
{
	int ret, success = 1 , i;
	enum cmd_error_code retval = CMD_SUCCESS;
	int *pid_list = NULL;
	int nr_pids;
	struct lttng_domain dom;
	struct lttng_handle *handle = NULL;
	int (*cmd_func)(struct lttng_handle *handle, int pid);

	switch (cmd_type) {
	case CMD_TRACK:
		cmd_func = lttng_track_pid;
		break;
	case CMD_UNTRACK:
		cmd_func = lttng_untrack_pid;
		break;
	default:
		ERR("Unknown command");
		retval = CMD_ERROR;
		goto end;
	}

	memset(&dom, 0, sizeof(dom));
	if (opt_kernel) {
		dom.type = LTTNG_DOMAIN_KERNEL;
	} else if (opt_userspace) {
		dom.type = LTTNG_DOMAIN_UST;
	} else {
		/* Checked by the caller. */
		assert(0);
	}

	ret = parse_pid_string(pid_string, all, &pid_list, &nr_pids);
	if (ret != CMD_SUCCESS) {
		ERR("Error parsing PID string");
		retval = CMD_ERROR;
		goto end;
	}

	handle = lttng_create_handle(session_name, &dom);
	if (handle == NULL) {
		retval = CMD_ERROR;
		goto end;
	}

	if (writer) {
		/* Open process element */
		ret = mi_lttng_targets_open(writer);
		if (ret) {
			retval = CMD_ERROR;
			goto end;
		}
	}

	for (i = 0; i < nr_pids; i++) {
		DBG("%s PID %d", cmd_str, pid_list[i]);
		ret = cmd_func(handle, pid_list[i]);
		if (ret) {
			switch (-ret) {
			case LTTNG_ERR_PID_TRACKED:
				WARN("PID %i already tracked in session %s",
						pid_list[i], session_name);
				success = 1;
				retval = CMD_SUCCESS;
				break;
			case LTTNG_ERR_PID_NOT_TRACKED:
				WARN("PID %i not tracked in session %s",
						pid_list[i], session_name);
				success = 1;
				retval = CMD_SUCCESS;
				break;
			default:
				ERR("%s", lttng_strerror(ret));
				success = 0;
				retval = CMD_ERROR;
				break;
			}
		} else {
			MSG("PID %i %sed in session %s",
					pid_list[i], cmd_str, session_name);
			success = 1;
		}

		/* Mi */
		if (writer) {
			ret = mi_lttng_pid_target(writer, pid_list[i], 1);
			if (ret) {
				retval = CMD_ERROR;
				goto end;
			}

			ret = mi_lttng_writer_write_element_bool(writer,
					mi_lttng_element_success, success);
			if (ret) {
				retval = CMD_ERROR;
				goto end;
			}

			ret = mi_lttng_writer_close_element(writer);
			if (ret) {
				retval = CMD_ERROR;
				goto end;
			}
		}
	}

	if (writer) {
		/* Close targets element */
		ret = mi_lttng_writer_close_element(writer);
		if (ret) {
			retval = CMD_ERROR;
			goto end;
		}
	}

end:
	if (handle) {
		lttng_destroy_handle(handle);
	}
	free(pid_list);
	return retval;
}
示例#19
0
/*
 * Start tracing for all trace of the session.
 */
static int stop_tracing(void)
{
	int ret;
	char *session_name;

	if (opt_session_name == NULL) {
		session_name = get_session_name();
		if (session_name == NULL) {
			ret = CMD_ERROR;
			goto error;
		}
	} else {
		session_name = opt_session_name;
	}

	ret = lttng_stop_tracing_no_wait(session_name);
	if (ret < 0) {
		switch (-ret) {
		case LTTNG_ERR_TRACE_ALREADY_STOPPED:
			WARN("Tracing already stopped for session %s", session_name);
			break;
		default:
			ERR("%s", lttng_strerror(ret));
			break;
		}
		goto free_name;
	}

	if (!opt_no_wait) {
		_MSG("Waiting for data availability");
		fflush(stdout);
		do {
			ret = lttng_data_pending(session_name);
			if (ret < 0) {
				/* Return the data available call error. */
				goto free_name;
			}

			/*
			 * Data sleep time before retrying (in usec). Don't sleep if the call
			 * returned value indicates availability.
			 */
			if (ret) {
				usleep(DEFAULT_DATA_AVAILABILITY_WAIT_TIME);
				_MSG(".");
				fflush(stdout);
			}
		} while (ret != 0);
		MSG("");
	}

	ret = CMD_SUCCESS;

	print_session_stats(session_name);
	MSG("Tracing stopped for session %s", session_name);
	if (lttng_opt_mi) {
		ret = mi_print_session(session_name, 0);
		if (ret) {
			goto free_name;
		}
	}

free_name:
	if (opt_session_name == NULL) {
		free(session_name);
	}

error:
	return ret;
}
示例#20
0
/*
 * The 'destroy <options>' first level command
 */
int cmd_destroy(int argc, const char **argv)
{
	int opt;
	int ret = CMD_SUCCESS , i, command_ret = CMD_SUCCESS, success = 1;
	static poptContext pc;
	char *session_name = NULL;
	const char *leftover = NULL;

	struct lttng_session *sessions;
	int count;
	int found;

	pc = poptGetContext(NULL, argc, argv, long_options, 0);
	poptReadDefaultConfig(pc, 0);

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case OPT_HELP:
			SHOW_HELP();
			break;
		case OPT_LIST_OPTIONS:
			list_cmd_options(stdout, long_options);
			break;
		default:
			ret = CMD_UNDEFINED;
			break;
		}
		goto end;
	}

	/* Mi preparation */
	if (lttng_opt_mi) {
		writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
		if (!writer) {
			ret = -LTTNG_ERR_NOMEM;
			goto end;
		}

		/* Open command element */
		ret = mi_lttng_writer_command_open(writer,
				mi_lttng_element_command_destroy);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Open output element */
		ret = mi_lttng_writer_open_element(writer,
				mi_lttng_element_command_output);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* For validation and semantic purpose we open a sessions element */
		ret = mi_lttng_sessions_open(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}

	/* Recuperate all sessions for further operation */
	count = lttng_list_sessions(&sessions);
	if (count < 0) {
		ERR("%s", lttng_strerror(count));
		command_ret = CMD_ERROR;
		success = 0;
		goto mi_closing;
	}

	/* Ignore session name in case all sessions are to be destroyed */
	if (opt_destroy_all) {
		command_ret = destroy_all_sessions(sessions, count);
		if (command_ret) {
			success = 0;
		}
	} else {
		opt_session_name = (char *) poptGetArg(pc);

		if (!opt_session_name) {
			/* No session name specified, lookup default */
			session_name = get_session_name();
			if (session_name == NULL) {
				command_ret = CMD_ERROR;
				success = 0;
				goto mi_closing;
			}
		} else {
			session_name = opt_session_name;
		}

		/* Find the corresponding lttng_session struct */
		found = 0;
		for (i = 0; i < count; i++) {
			if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) {
				found = 1;
				command_ret = destroy_session(&sessions[i]);
				if (command_ret) {
					success = 0;
				}

			}
		}

		if (!found) {
			ERR("Session name %s not found", session_name);
			command_ret = LTTNG_ERR_SESS_NOT_FOUND;
			success = 0;
			goto mi_closing;
		}
	}

	leftover = poptGetArg(pc);
	if (leftover) {
		ERR("Unknown argument: %s", leftover);
		ret = CMD_ERROR;
		success = 0;
		goto mi_closing;
	}

mi_closing:
	/* Mi closing */
	if (lttng_opt_mi) {
		/* Close sessions and output element element */
		ret = mi_lttng_close_multi_element(writer, 2);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Success ? */
		ret = mi_lttng_writer_write_element_bool(writer,
				mi_lttng_element_command_success, success);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Command element close */
		ret = mi_lttng_writer_command_close(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}
end:
	/* Mi clean-up */
	if (writer && mi_lttng_writer_destroy(writer)) {
		/* Preserve original error code */
		ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
	}

	if (opt_session_name == NULL) {
		free(session_name);
	}

	/* Overwrite ret if an error occurred during destroy_session/all */
	ret = command_ret ? command_ret : ret;

	poptFreeContext(pc);
	return ret;
}
示例#21
0
/*
 * The 'snapshot <cmd> <options>' first level command
 */
int cmd_snapshot(int argc, const char **argv)
{
	int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
	char *session_name = NULL;
	static poptContext pc;

	pc = poptGetContext(NULL, argc, argv, snapshot_opts, 0);
	poptReadDefaultConfig(pc, 0);

	/* Mi check */
	if (lttng_opt_mi) {
		writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
		if (!writer) {
			ret = -LTTNG_ERR_NOMEM;
			goto end;
		}

		/* Open command element */
		ret = mi_lttng_writer_command_open(writer,
				mi_lttng_element_command_snapshot);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Open output element */
		ret = mi_lttng_writer_open_element(writer,
				mi_lttng_element_command_output);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case OPT_HELP:
			usage(stdout);
			goto end;
		case OPT_LIST_OPTIONS:
			list_cmd_options(stdout, snapshot_opts);
			goto end;
		case OPT_LIST_COMMANDS:
			list_commands(actions, stdout);
			goto end;
		case OPT_MAX_SIZE:
		{
			uint64_t val;
			const char *opt = poptGetOptArg(pc);

			if (utils_parse_size_suffix((char *) opt, &val) < 0) {
				ERR("Unable to handle max-size value %s", opt);
				ret = CMD_ERROR;
				goto end;
			}

			opt_max_size = val;

			break;
		}
		default:
			usage(stderr);
			ret = CMD_UNDEFINED;
			goto end;
		}
	}

	if (!opt_session_name) {
		session_name = get_session_name();
		if (session_name == NULL) {
			ret = CMD_ERROR;
			goto end;
		}
		current_session_name = session_name;
	} else {
		current_session_name = opt_session_name;
	}

	command_ret = handle_command(poptGetArgs(pc));
	if (command_ret) {
		switch (-command_ret) {
		case LTTNG_ERR_EPERM:
			ERR("The session needs to be set in no output mode (--no-output)");
			break;
		case LTTNG_ERR_SNAPSHOT_NODATA:
			WARN("%s", lttng_strerror(command_ret));
			break;
		default:
			ERR("%s", lttng_strerror(command_ret));
			break;
		}
		success = 0;
	}

	if (lttng_opt_mi) {
		/* Close output element */
		ret = mi_lttng_writer_close_element(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Success ? */
		ret = mi_lttng_writer_write_element_bool(writer,
				mi_lttng_element_command_success, success);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Command element close */
		ret = mi_lttng_writer_command_close(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}

end:
	/* Mi clean-up */
	if (writer && mi_lttng_writer_destroy(writer)) {
		/* Preserve original error code */
		ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
	}

	if (!opt_session_name) {
		free(session_name);
	}

	/* Overwrite ret if an error occured during handle_command */
	ret = command_ret ? command_ret : ret;
	poptFreeContext(pc);
	return ret;
}
示例#22
0
int main(int argc, char **argv)
{
	int ret = 0;
	enum lttng_condition_status condition_status;
	enum lttng_notification_channel_status nc_status;
	struct lttng_notification_channel *notification_channel = NULL;
	struct lttng_condition *condition = NULL;
	struct lttng_action *action = NULL;
	struct lttng_trigger *trigger = NULL;

	/*
	 * Disable buffering on stdout.
	 * Safety measure to prevent hang on the validation side since
	 * stdout is used for outside synchronization.
	 */
	setbuf(stdout, NULL);

	if (argc < 8) {
		printf("error: Missing arguments for tests\n");
		ret = 1;
		goto end;
	}

	ret = parse_arguments(argv);
	if (ret) {
		printf("error: Could not parse arguments\n");
		goto end;
	}

	/* Setup */
	notification_channel = lttng_notification_channel_create(
			lttng_session_daemon_notification_endpoint);
	if (!notification_channel) {
		printf("error: Could not create notification channel\n");
		ret = 1;
		goto end;
	}

	switch (buffer_usage_type) {
	case LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW:
		condition = lttng_condition_buffer_usage_low_create();
		break;
	case LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH:
		condition = lttng_condition_buffer_usage_high_create();
		break;
	default:
		printf("error: Invalid buffer_usage_type\n");
		ret = 1;
		goto end;
	}

	if (!condition) {
		printf("error: Could not create condition object\n");
		ret = 1;
		goto end;
	}

	if (is_threshold_ratio) {
		condition_status = lttng_condition_buffer_usage_set_threshold_ratio(
				condition, threshold_ratio);
	} else {
		condition_status = lttng_condition_buffer_usage_set_threshold(
				condition, threshold_bytes);
	}

	if (condition_status != LTTNG_CONDITION_STATUS_OK) {
		printf("error: Could not set threshold\n");
		ret = 1;
		goto end;
	}

	condition_status = lttng_condition_buffer_usage_set_session_name(
			condition, session_name);
	if (condition_status != LTTNG_CONDITION_STATUS_OK) {
		printf("error: Could not set session name\n");
		ret = 1;
		goto end;
	}
	condition_status = lttng_condition_buffer_usage_set_channel_name(
			condition, channel_name);
	if (condition_status != LTTNG_CONDITION_STATUS_OK) {
		printf("error: Could not set channel name\n");
		ret = 1;
		goto end;
	}
	condition_status = lttng_condition_buffer_usage_set_domain_type(
			condition, domain_type);
	if (condition_status != LTTNG_CONDITION_STATUS_OK) {
		printf("error: Could not set domain type\n");
		ret = 1;
		goto end;
	}

	action = lttng_action_notify_create();
	if (!action) {
		printf("error: Could not create action notify\n");
		ret = 1;
		goto end;
	}

	trigger = lttng_trigger_create(condition, action);
	if (!trigger) {
		printf("error: Could not create trigger\n");
		ret = 1;
		goto end;
	}

	ret = lttng_register_trigger(trigger);

	/*
	 * An equivalent trigger might already be registered if an other app
	 * registered an equivalent trigger.
	 */
	if (ret < 0 && ret != -LTTNG_ERR_TRIGGER_EXISTS) {
		printf("error: %s\n", lttng_strerror(ret));
		ret = 1;
		goto end;
	}

	nc_status = lttng_notification_channel_subscribe(notification_channel, condition);
	if (nc_status != LTTNG_NOTIFICATION_CHANNEL_STATUS_OK) {
		printf("error: Could not subscribe\n");
		ret = 1;
		goto end;
	}

	/* Tell outside process that the client is ready */
	printf("sync: ready\n");

	for (;;) {
		struct lttng_notification *notification;
		enum lttng_notification_channel_status status;
		const struct lttng_evaluation *notification_evaluation;
		const struct lttng_condition *notification_condition;

		if (nr_notifications == nr_expected_notifications) {
			ret = 0;
			goto end;
		}
		/* Receive the next notification. */
		status = lttng_notification_channel_get_next_notification(
				notification_channel,
				&notification);

		switch (status) {
		case LTTNG_NOTIFICATION_CHANNEL_STATUS_OK:
			break;
		case LTTNG_NOTIFICATION_CHANNEL_STATUS_NOTIFICATIONS_DROPPED:
			ret = 1;
			printf("error: No drop should be observed during this test app\n");
			goto end;
		case LTTNG_NOTIFICATION_CHANNEL_STATUS_CLOSED:
			/*
			 * The notification channel has been closed by the
			 * session daemon. This is typically caused by a session
			 * daemon shutting down (cleanly or because of a crash).
			 */
			printf("error: Notification channel was closed\n");
			ret = 1;
			goto end;
		default:
			/* Unhandled conditions / errors. */
			printf("error: Unknown notification channel status\n");
			ret = 1;
			goto end;
		}

		notification_condition = lttng_notification_get_condition(notification);
		notification_evaluation = lttng_notification_get_evaluation(notification);

		ret = handle_condition(notification_condition, notification_evaluation);
		nr_notifications++;

		lttng_notification_destroy(notification);
		if (ret != 0) {
			goto end;
		}
	}
end:
	if (trigger) {
		lttng_unregister_trigger(trigger);
	}
	if (lttng_notification_channel_unsubscribe(notification_channel, condition)) {
		printf("error: channel unsubscribe error\n");
	}
	lttng_trigger_destroy(trigger);
	lttng_condition_destroy(condition);
	lttng_action_destroy(action);
	lttng_notification_channel_destroy(notification_channel);
	printf("exit: %d\n", ret);
	return ret;
}
示例#23
0
/*
 * List available tracing session. List only basic information.
 *
 * If session_name is NULL, all sessions are listed.
 */
static int list_sessions(const char *session_name)
{
	int ret = CMD_SUCCESS;
	int count, i;
	unsigned int session_found = 0;
	struct lttng_session *sessions;

	count = lttng_list_sessions(&sessions);
	DBG("Session count %d", count);
	if (count < 0) {
		ret = CMD_ERROR;
		ERR("%s", lttng_strerror(count));
		goto end;
	}

	if (lttng_opt_mi) {
		/* Mi */
		if (session_name == NULL) {
			/* List all session */
			ret = mi_list_sessions(sessions, count);
		} else {
			/* Note : this return an open session element */
			ret = mi_list_session(session_name, sessions, count);
		}
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	} else {
		/* Pretty print */
		if (count == 0) {
			MSG("Currently no available tracing session");
			goto end;
		}

		if (session_name == NULL) {
			MSG("Available tracing sessions:");
		}


		for (i = 0; i < count; i++) {
			if (session_name != NULL) {
				if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) {
					session_found = 1;
					MSG("Tracing session %s: [%s%s]", session_name,
							active_string(sessions[i].enabled),
							snapshot_string(sessions[i].snapshot_mode));
					MSG("%sTrace path: %s\n", indent4, sessions[i].path);
					break;
				}
			} else {
				MSG("  %d) %s (%s) [%s%s]", i + 1,
						sessions[i].name, sessions[i].path,
						active_string(sessions[i].enabled),
						snapshot_string(sessions[i].snapshot_mode));
				MSG("%sTrace path: %s", indent4, sessions[i].path);
				if (sessions[i].live_timer_interval != 0) {
					MSG("%sLive timer interval (usec): %u", indent4,
							sessions[i].live_timer_interval);
				}
				MSG("");
			}
		}

		if (!session_found && session_name != NULL) {
			ERR("Session '%s' not found", session_name);
			ret = CMD_ERROR;
			goto error;
		}

		if (session_name == NULL) {
			MSG("\nUse lttng list <session_name> for more details");
		}
	}

error:
	free(sessions);
end:
	return ret;
}
示例#24
0
/*
 * List channel(s) of session and domain.
 *
 * If channel_name is NULL, all channels are listed.
 */
static int list_channels(const char *channel_name)
{
	int count, i, ret = CMD_SUCCESS;
	unsigned int chan_found = 0;
	struct lttng_channel *channels = NULL;

	DBG("Listing channel(s) (%s)", channel_name ? : "<all>");

	count = lttng_list_channels(handle, &channels);
	if (count < 0) {
		switch (-count) {
		case LTTNG_ERR_KERN_CHAN_NOT_FOUND:
			if (lttng_opt_mi) {
				/* When printing mi this is not an error
				 * but an empty channels element */
				count = 0;
			} else {
				ret = CMD_SUCCESS;
				WARN("No kernel channel");
				goto error_channels;
			}
			break;
		default:
			/* We had a real error */
			ret = CMD_ERROR;
			ERR("%s", lttng_strerror(count));
			goto error_channels;
			break;
		}
	}

	if (lttng_opt_mi) {
		/* Mi print */
		ret = mi_list_channels(channels, count, channel_name);
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	} else {
		/* Pretty print */
		if (count) {
			MSG("Channels:\n-------------");
		}

		for (i = 0; i < count; i++) {
			if (channel_name != NULL) {
				if (strncmp(channels[i].name, channel_name, NAME_MAX) == 0) {
					chan_found = 1;
				} else {
					continue;
				}
			}
			print_channel(&channels[i]);

			/* Listing events per channel */
			ret = list_events(channels[i].name);
			if (ret) {
				goto error;
			}

			if (chan_found) {
				break;
			}
		}

		if (!chan_found && channel_name != NULL) {
			ret = CMD_ERROR;
			ERR("Channel %s not found", channel_name);
			goto error;
		}
	}
error:
	free(channels);

error_channels:
	return ret;
}
示例#25
0
/*
 * destroy_session
 *
 * Unregister the provided session to the session daemon. On success, removes
 * the default configuration.
 */
static int destroy_session(struct lttng_session *session)
{
	int ret;
	char *session_name = NULL;
	bool session_was_stopped;

	ret = lttng_stop_tracing_no_wait(session->name);
	if (ret < 0 && ret != -LTTNG_ERR_TRACE_ALREADY_STOPPED) {
		ERR("%s", lttng_strerror(ret));
	}
	session_was_stopped = ret == -LTTNG_ERR_TRACE_ALREADY_STOPPED;
	if (!opt_no_wait) {
		bool printed_wait_msg = false;

		do {
			ret = lttng_data_pending(session->name);
			if (ret < 0) {
				/* Return the data available call error. */
				goto error;
			}

			/*
			 * Data sleep time before retrying (in usec). Don't sleep if the call
			 * returned value indicates availability.
			 */
			if (ret) {
				if (!printed_wait_msg) {
					_MSG("Waiting for data availability");
					fflush(stdout);
				}

				printed_wait_msg = true;
				usleep(DEFAULT_DATA_AVAILABILITY_WAIT_TIME);
				_MSG(".");
				fflush(stdout);
			}
		} while (ret != 0);
		if (printed_wait_msg) {
			MSG("");
		}
	}
	if (!session_was_stopped) {
		/*
		 * Don't print the event and packet loss warnings since the user
		 * already saw them when stopping the trace.
		 */
		print_session_stats(session->name);
	}

	ret = lttng_destroy_session_no_wait(session->name);
	if (ret < 0) {
		goto error;
	}

	MSG("Session %s destroyed", session->name);

	session_name = get_session_name_quiet();
	if (session_name && !strncmp(session->name, session_name, NAME_MAX)) {
		config_destroy_default();
	}

	if (lttng_opt_mi) {
		ret = mi_lttng_session(writer, session, 0);
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	}

	ret = CMD_SUCCESS;
error:
	free(session_name);
	return ret;
}
示例#26
0
/*
 * Ask session daemon for all user space tracepoint fields available.
 */
static int list_ust_event_fields(void)
{
	int i, size, ret = CMD_SUCCESS;
	struct lttng_domain domain;
	struct lttng_handle *handle;
	struct lttng_event_field *event_field_list;
	pid_t cur_pid = 0;
	char *cmdline = NULL;

	struct lttng_event cur_event;

	memset(&domain, 0, sizeof(domain));
	memset(&cur_event, 0, sizeof(cur_event));

	DBG("Getting UST tracing event fields");

	domain.type = LTTNG_DOMAIN_UST;

	handle = lttng_create_handle(NULL, &domain);
	if (handle == NULL) {
		ret = CMD_ERROR;
		goto end;
	}

	size = lttng_list_tracepoint_fields(handle, &event_field_list);
	if (size < 0) {
		ERR("Unable to list UST event fields: %s", lttng_strerror(size));
		ret = CMD_ERROR;
		goto end;
	}

	if (lttng_opt_mi) {
		/* Mi print */
		ret = mi_list_ust_event_fields(event_field_list, size, &domain);
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	} else {
		/* Pretty print */
		MSG("UST events:\n-------------");

		if (size == 0) {
			MSG("None");
		}

		for (i = 0; i < size; i++) {
			if (cur_pid != event_field_list[i].event.pid) {
				cur_pid = event_field_list[i].event.pid;
				cmdline = get_cmdline_by_pid(cur_pid);
				if (cmdline == NULL) {
					ret = CMD_ERROR;
					goto error;
				}
				MSG("\nPID: %d - Name: %s", cur_pid, cmdline);
				free(cmdline);
				/* Wipe current event since we are about to print a new PID. */
				memset(&cur_event, 0, sizeof(cur_event));
			}
			if (strcmp(cur_event.name, event_field_list[i].event.name) != 0) {
				print_events(&event_field_list[i].event);
				memcpy(&cur_event, &event_field_list[i].event,
						sizeof(cur_event));
			}
			print_event_field(&event_field_list[i]);
		}

		MSG("");
	}

error:
	free(event_field_list);
end:
	lttng_destroy_handle(handle);
	return ret;
}
示例#27
0
/*
 * Adding channel using the lttng API.
 */
static int enable_channel(char *session_name)
{
	int ret = CMD_SUCCESS, warn = 0, error = 0, success = 0;
	char *channel_name;
	struct lttng_domain dom;

	memset(&dom, 0, sizeof(dom));

	/* Create lttng domain */
	if (opt_kernel) {
		dom.type = LTTNG_DOMAIN_KERNEL;
		dom.buf_type = LTTNG_BUFFER_GLOBAL;
		if (opt_buffer_uid || opt_buffer_pid) {
			ERR("Buffer type not supported for domain -k");
			ret = CMD_ERROR;
			goto error;
		}
	} else if (opt_userspace) {
		dom.type = LTTNG_DOMAIN_UST;
		if (opt_buffer_pid) {
			dom.buf_type = LTTNG_BUFFER_PER_PID;
		} else {
			if (opt_buffer_global) {
				ERR("Buffer type not supported for domain -u");
				ret = CMD_ERROR;
				goto error;
			}
			dom.buf_type = LTTNG_BUFFER_PER_UID;
		}
	} else {
		print_missing_domain();
		ret = CMD_ERROR;
		goto error;
	}

	set_default_attr(&dom);

	if (chan.attr.tracefile_size == 0 && chan.attr.tracefile_count) {
		ERR("Missing option --tracefile-size. "
				"A file count without a size won't do anything.");
		ret = CMD_ERROR;
		goto error;
	}

	if ((chan.attr.tracefile_size > 0) &&
			(chan.attr.tracefile_size < chan.attr.subbuf_size)) {
		WARN("Tracefile size rounded up from (%" PRIu64 ") to subbuffer size (%" PRIu64 ")",
				chan.attr.tracefile_size, chan.attr.subbuf_size);
		chan.attr.tracefile_size = chan.attr.subbuf_size;
	}

	/* Setting channel output */
	if (opt_output) {
		if (!strncmp(output_mmap, opt_output, strlen(output_mmap))) {
			chan.attr.output = LTTNG_EVENT_MMAP;
		} else if (!strncmp(output_splice, opt_output, strlen(output_splice))) {
			chan.attr.output = LTTNG_EVENT_SPLICE;
		} else {
			ERR("Unknown output type %s. Possible values are: %s, %s\n",
					opt_output, output_mmap, output_splice);
			usage(stderr);
			ret = CMD_ERROR;
			goto error;
		}
	}

	handle = lttng_create_handle(session_name, &dom);
	if (handle == NULL) {
		ret = -1;
		goto error;
	}

	/* Mi open channels element */
	if (lttng_opt_mi) {
		assert(writer);
		ret = mi_lttng_channels_open(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	}

	/* Strip channel list (format: chan1,chan2,...) */
	channel_name = strtok(opt_channels, ",");
	while (channel_name != NULL) {
		/* Copy channel name and normalize it */
		strncpy(chan.name, channel_name, NAME_MAX);
		chan.name[NAME_MAX - 1] = '\0';

		DBG("Enabling channel %s", channel_name);

		ret = lttng_enable_channel(handle, &chan);
		if (ret < 0) {
			success = 0;
			switch (-ret) {
			case LTTNG_ERR_KERN_CHAN_EXIST:
			case LTTNG_ERR_UST_CHAN_EXIST:
			case LTTNG_ERR_CHAN_EXIST:
				WARN("Channel %s: %s (session %s)", channel_name,
						lttng_strerror(ret), session_name);
				warn = 1;
				break;
			default:
				ERR("Channel %s: %s (session %s)", channel_name,
						lttng_strerror(ret), session_name);
				error = 1;
				break;
			}
		} else {
			MSG("%s channel %s enabled for session %s",
					get_domain_str(dom.type), channel_name, session_name);
			success = 1;
		}

		if (lttng_opt_mi) {
			/* Mi print the channel element and leave it open */
			ret = mi_lttng_channel(writer, &chan, 1);
			if (ret) {
				ret = CMD_ERROR;
				goto error;
			}

			/* Individual Success ? */
			ret = mi_lttng_writer_write_element_bool(writer,
					mi_lttng_element_command_success, success);
			if (ret) {
				ret = CMD_ERROR;
				goto error;
			}

			/* Close channel element */
			ret = mi_lttng_writer_close_element(writer);
			if (ret) {
				ret = CMD_ERROR;
				goto error;
			}
		}

		/* Next channel */
		channel_name = strtok(NULL, ",");
	}

	if (lttng_opt_mi) {
		/* Close channels element */
		ret = mi_lttng_writer_close_element(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	}

	ret = CMD_SUCCESS;

error:
	/* If more important error happen bypass the warning */
	if (!ret && warn) {
		ret = CMD_WARNING;
	}
	/* If more important error happen bypass the warning */
	if (!ret && error) {
		ret = CMD_ERROR;
	}

	lttng_destroy_handle(handle);

	return ret;
}
示例#28
0
/*
 * The 'list <options>' first level command
 */
int cmd_list(int argc, const char **argv)
{
	int opt, ret = CMD_SUCCESS;
	const char *session_name;
	static poptContext pc;
	struct lttng_domain domain;
	struct lttng_domain *domains = NULL;

	memset(&domain, 0, sizeof(domain));

	if (argc < 1) {
		usage(stderr);
		ret = CMD_ERROR;
		goto end;
	}

	pc = poptGetContext(NULL, argc, argv, long_options, 0);
	poptReadDefaultConfig(pc, 0);

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case OPT_HELP:
			usage(stdout);
			goto end;
		case OPT_USERSPACE:
			opt_userspace = 1;
			break;
		case OPT_LIST_OPTIONS:
			list_cmd_options(stdout, long_options);
			goto end;
		default:
			usage(stderr);
			ret = CMD_UNDEFINED;
			goto end;
		}
	}

	/* Mi check */
	if (lttng_opt_mi) {
		writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
		if (!writer) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Open command element */
		ret = mi_lttng_writer_command_open(writer,
				mi_lttng_element_command_list);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Open output element */
		ret = mi_lttng_writer_open_element(writer,
				mi_lttng_element_command_output);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}

	/* Get session name (trailing argument) */
	session_name = poptGetArg(pc);
	DBG2("Session name: %s", session_name);

	if (opt_kernel) {
		domain.type = LTTNG_DOMAIN_KERNEL;
	} else if (opt_userspace) {
		DBG2("Listing userspace global domain");
		domain.type = LTTNG_DOMAIN_UST;
	} else if (opt_jul) {
		DBG2("Listing JUL domain");
		domain.type = LTTNG_DOMAIN_JUL;
	} else if (opt_log4j) {
		domain.type = LTTNG_DOMAIN_LOG4J;
	} else if (opt_python) {
		domain.type = LTTNG_DOMAIN_PYTHON;
	}

	if (!opt_kernel && opt_syscall) {
		WARN("--syscall will only work with the Kernel domain (-k)");
		ret = CMD_ERROR;
		goto end;
	}

	if (opt_kernel || opt_userspace || opt_jul || opt_log4j || opt_python) {
		handle = lttng_create_handle(session_name, &domain);
		if (handle == NULL) {
			ret = CMD_FATAL;
			goto end;
		}
	}

	if (session_name == NULL) {
		if (!opt_kernel && !opt_userspace && !opt_jul && !opt_log4j
				&& !opt_python) {
			ret = list_sessions(NULL);
			if (ret) {
				goto end;
			}
		}
		if (opt_kernel) {
			if (opt_syscall) {
				ret = list_syscalls();
				if (ret) {
					goto end;
				}
			} else {
				ret = list_kernel_events();
				if (ret) {
					goto end;
				}
			}
		}
		if (opt_userspace) {
			if (opt_fields) {
				ret = list_ust_event_fields();
			} else {
				ret = list_ust_events();
			}
			if (ret) {
				goto end;
			}
		}
		if (opt_jul || opt_log4j || opt_python) {
			ret = list_agent_events();
			if (ret) {
				goto end;
			}
		}
	} else {
		/* List session attributes */
		if (lttng_opt_mi) {
			/* Open element sessions
			 * Present for xml consistency */
			ret = mi_lttng_sessions_open(writer);
			if (ret) {
				goto end;
			}
		}
		/* MI: the ouptut of list_sessions is an unclosed session element */
		ret = list_sessions(session_name);
		if (ret) {
			goto end;
		}

		/* Domain listing */
		if (opt_domain) {
			ret = list_domains(session_name);
			goto end;
		}

		/* Channel listing */
		if (opt_kernel || opt_userspace) {
			if (lttng_opt_mi) {
				/* Add of domains and domain element for xml
				 * consistency and validation
				 */
				ret = mi_lttng_domains_open(writer);
				if (ret) {
					goto end;
				}

				/* Open domain and leave it open for
				 * nested channels printing */
				ret = mi_lttng_domain(writer, &domain, 1);
				if (ret) {
					goto end;
				}

			}

			ret = list_tracker_pids();
			if (ret) {
				goto end;
			}

			ret = list_channels(opt_channel);
			if (ret) {
				goto end;
			}

			if (lttng_opt_mi) {
				/* Close domain and domain element */
				ret = mi_lttng_close_multi_element(writer, 2);
			}
			if (ret) {
				goto end;
			}


		} else {
			int i, nb_domain;

			/* We want all domain(s) */
			nb_domain = lttng_list_domains(session_name, &domains);
			if (nb_domain < 0) {
				ret = CMD_ERROR;
				ERR("%s", lttng_strerror(nb_domain));
				goto end;
			}

			if (lttng_opt_mi) {
				ret = mi_lttng_domains_open(writer);
				if (ret) {
					ret = CMD_ERROR;
					goto end;
				}
			}

			for (i = 0; i < nb_domain; i++) {
				switch (domains[i].type) {
				case LTTNG_DOMAIN_KERNEL:
					MSG("=== Domain: Kernel ===\n");
					break;
				case LTTNG_DOMAIN_UST:
					MSG("=== Domain: UST global ===\n");
					MSG("Buffer type: %s\n",
							domains[i].buf_type ==
							LTTNG_BUFFER_PER_PID ? "per PID" : "per UID");
					break;
				case LTTNG_DOMAIN_JUL:
					MSG("=== Domain: JUL (Java Util Logging) ===\n");
					break;
				case LTTNG_DOMAIN_LOG4J:
					MSG("=== Domain: LOG4j (Logging for Java) ===\n");
					break;
				case LTTNG_DOMAIN_PYTHON:
					MSG("=== Domain: Python (logging) ===\n");
					break;
				default:
					MSG("=== Domain: Unimplemented ===\n");
					break;
				}

				if (lttng_opt_mi) {
					ret = mi_lttng_domain(writer, &domains[i], 1);
					if (ret) {
						ret = CMD_ERROR;
						goto end;
					}
				}

				/* Clean handle before creating a new one */
				if (handle) {
					lttng_destroy_handle(handle);
				}

				handle = lttng_create_handle(session_name, &domains[i]);
				if (handle == NULL) {
					ret = CMD_FATAL;
					goto end;
				}

				if (domains[i].type == LTTNG_DOMAIN_JUL ||
						domains[i].type == LTTNG_DOMAIN_LOG4J ||
						domains[i].type == LTTNG_DOMAIN_PYTHON) {
					ret = list_session_agent_events();
					if (ret) {
						goto end;
					}
					continue;
				}

				switch (domains[i].type) {
				case LTTNG_DOMAIN_KERNEL:
				case LTTNG_DOMAIN_UST:
					ret = list_tracker_pids();
					if (ret) {
						goto end;
					}
					break;
				default:
					break;
				}

				ret = list_channels(opt_channel);
				if (ret) {
					goto end;
				}

				if (lttng_opt_mi) {
					/* Close domain element */
					ret = mi_lttng_writer_close_element(writer);
					if (ret) {
						ret = CMD_ERROR;
						goto end;
					}
				}

			}
			if (lttng_opt_mi) {
				/* Close the domains, session and sessions element */
				ret = mi_lttng_close_multi_element(writer, 3);
				if (ret) {
					ret = CMD_ERROR;
					goto end;
				}
			}
		}
	}

	/* Mi closing */
	if (lttng_opt_mi) {
		/* Close  output element */
		ret = mi_lttng_writer_close_element(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Command element close */
		ret = mi_lttng_writer_command_close(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}
end:
	/* Mi clean-up */
	if (writer && mi_lttng_writer_destroy(writer)) {
		/* Preserve original error code */
		ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
	}

	free(domains);
	if (handle) {
		lttng_destroy_handle(handle);
	}

	poptFreeContext(pc);
	return ret;
}
示例#29
0
/*
 * Adding channel using the lttng API.
 */
static int enable_channel(char *session_name)
{
	int ret = CMD_SUCCESS, warn = 0;
	char *channel_name;
	struct lttng_domain dom;

	memset(&dom, 0, sizeof(dom));

	/* Create lttng domain */
	if (opt_kernel) {
		dom.type = LTTNG_DOMAIN_KERNEL;
		dom.buf_type = LTTNG_BUFFER_GLOBAL;
		if (opt_buffer_uid || opt_buffer_pid) {
			ERR("Buffer type not supported for domain -k");
			ret = CMD_ERROR;
			goto error;
		}
	} else if (opt_userspace) {
		dom.type = LTTNG_DOMAIN_UST;
		if (opt_buffer_uid) {
			dom.buf_type = LTTNG_BUFFER_PER_UID;
		} else {
			if (opt_buffer_global) {
				ERR("Buffer type not supported for domain -u");
				ret = CMD_ERROR;
				goto error;
			}
			dom.buf_type = LTTNG_BUFFER_PER_PID;
		}
	} else {
		ERR("Please specify a tracer (-k/--kernel or -u/--userspace)");
		ret = CMD_ERROR;
		goto error;
	}

	set_default_attr(&dom);

	if (chan.attr.tracefile_size == 0 && chan.attr.tracefile_count) {
		ERR("Missing option --tracefile-size. "
				"A file count without a size won't do anything.");
		ret = CMD_ERROR;
		goto error;
	}

	if ((chan.attr.tracefile_size > 0) &&
			(chan.attr.tracefile_size < chan.attr.subbuf_size)) {
		WARN("Tracefile size rounded up from (%" PRIu64 ") to subbuffer size (%" PRIu64 ")",
				chan.attr.tracefile_size, chan.attr.subbuf_size);
		chan.attr.tracefile_size = chan.attr.subbuf_size;
	}

	/* Setting channel output */
	if (opt_output) {
		if (!strncmp(output_mmap, opt_output, strlen(output_mmap))) {
			chan.attr.output = LTTNG_EVENT_MMAP;
		} else if (!strncmp(output_splice, opt_output, strlen(output_splice))) {
			chan.attr.output = LTTNG_EVENT_SPLICE;
		} else {
			ERR("Unknown output type %s. Possible values are: %s, %s\n",
					opt_output, output_mmap, output_splice);
			usage(stderr);
			ret = CMD_ERROR;
			goto error;
		}
	}

	handle = lttng_create_handle(session_name, &dom);
	if (handle == NULL) {
		ret = -1;
		goto error;
	}

	/* Strip channel list (format: chan1,chan2,...) */
	channel_name = strtok(opt_channels, ",");
	while (channel_name != NULL) {
		/* Copy channel name and normalize it */
		strncpy(chan.name, channel_name, NAME_MAX);
		chan.name[NAME_MAX - 1] = '\0';

		DBG("Enabling channel %s", channel_name);

		ret = lttng_enable_channel(handle, &chan);
		if (ret < 0) {
			switch (-ret) {
			case LTTNG_ERR_KERN_CHAN_EXIST:
			case LTTNG_ERR_UST_CHAN_EXIST:
				WARN("Channel %s: %s (session %s)", channel_name,
						lttng_strerror(ret), session_name);
				goto error;
			default:
				ERR("Channel %s: %s (session %s)", channel_name,
						lttng_strerror(ret), session_name);
				break;
			}
			warn = 1;
		} else {
			MSG("%s channel %s enabled for session %s",
					opt_kernel ? "Kernel" : "UST", channel_name,
					session_name);
		}

		/* Next event */
		channel_name = strtok(NULL, ",");
	}

	ret = CMD_SUCCESS;

error:
	if (warn) {
		ret = CMD_WARNING;
	}

	lttng_destroy_handle(handle);

	return ret;
}
示例#30
0
static int list_agent_events(void)
{
	int i, size, ret = CMD_SUCCESS;
	struct lttng_domain domain;
	struct lttng_handle *handle = NULL;
	struct lttng_event *event_list = NULL;
	pid_t cur_pid = 0;
	char *cmdline = NULL;
	const char *agent_domain_str;

	memset(&domain, 0, sizeof(domain));
	if (opt_jul) {
		domain.type = LTTNG_DOMAIN_JUL;
	} else if (opt_log4j) {
		domain.type = LTTNG_DOMAIN_LOG4J;
	} else if (opt_python) {
		domain.type = LTTNG_DOMAIN_PYTHON;
	} else {
		ERR("Invalid agent domain selected.");
		ret = CMD_ERROR;
		goto error;
	}

	agent_domain_str = get_domain_str(domain.type);

	DBG("Getting %s tracing events", agent_domain_str);

	handle = lttng_create_handle(NULL, &domain);
	if (handle == NULL) {
		ret = CMD_ERROR;
		goto end;
	}

	size = lttng_list_tracepoints(handle, &event_list);
	if (size < 0) {
		ERR("Unable to list %s events: %s", agent_domain_str,
				lttng_strerror(size));
		ret = CMD_ERROR;
		goto end;
	}

	if (lttng_opt_mi) {
		/* Mi print */
		ret = mi_list_agent_ust_events(event_list, size, &domain);
		if (ret) {
			ret = CMD_ERROR;
			goto error;
		}
	} else {
		/* Pretty print */
		MSG("%s events (Logger name):\n-------------------------",
				agent_domain_str);

		if (size == 0) {
			MSG("None");
		}

		for (i = 0; i < size; i++) {
			if (cur_pid != event_list[i].pid) {
				cur_pid = event_list[i].pid;
				cmdline = get_cmdline_by_pid(cur_pid);
				if (cmdline == NULL) {
					ret = CMD_ERROR;
					goto error;
				}
				MSG("\nPID: %d - Name: %s", cur_pid, cmdline);
				free(cmdline);
			}
			MSG("%s- %s", indent6, event_list[i].name);
		}

		MSG("");
	}

error:
	free(event_list);
end:
	lttng_destroy_handle(handle);
	return ret;
}