コード例 #1
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;
}
コード例 #2
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;
}
コード例 #3
0
ファイル: enable_channels.c プロジェクト: lttng/lttng-tools
/*
 * Adding channel using the lttng API.
 */
static int enable_channel(char *session_name)
{
	struct lttng_channel *channel = NULL;
	int ret = CMD_SUCCESS, warn = 0, error = 0, success = 0;
	char *channel_name;
	struct lttng_domain dom;

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

	/* Validate options. */
	if (opt_kernel) {
		if (opt_blocking_timeout.set) {
			ERR("Retry timeout option not supported for kernel domain (-k)");
			ret = CMD_ERROR;
			goto error;
		}
	}

	/* 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 {
		/* Checked by the caller. */
		assert(0);
	}

	set_default_attr(&dom);

	if (chan_opts.attr.tracefile_size == 0 && chan_opts.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_opts.attr.tracefile_size > 0) &&
			(chan_opts.attr.tracefile_size < chan_opts.attr.subbuf_size)) {
		WARN("Tracefile size rounded up from (%" PRIu64 ") to subbuffer size (%" PRIu64 ")",
				chan_opts.attr.tracefile_size, chan_opts.attr.subbuf_size);
		chan_opts.attr.tracefile_size = chan_opts.attr.subbuf_size;
	}

	/* Setting channel output */
	if (opt_output) {
		if (!strncmp(output_mmap, opt_output, strlen(output_mmap))) {
			chan_opts.attr.output = LTTNG_EVENT_MMAP;
		} else if (!strncmp(output_splice, opt_output, strlen(output_splice))) {
			chan_opts.attr.output = LTTNG_EVENT_SPLICE;
		} else {
			ERR("Unknown output type %s. Possible values are: %s, %s\n",
					opt_output, output_mmap, output_splice);
			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) {
		void *extended_ptr;

		/* Validate channel name's length */
		if (strlen(channel_name) >= sizeof(chan_opts.name)) {
			ERR("Channel name is too long (max. %zu characters)",
					sizeof(chan_opts.name) - 1);
			error = 1;
			goto skip_enable;
		}

		/*
		 * A dynamically-allocated channel is used in order to allow
		 * the configuration of extended attributes (post-2.9).
		 */
		channel = lttng_channel_create(&dom);
		if (!channel) {
			ERR("Unable to create channel object");
			error = 1;
			goto error;
		}

		/* Copy channel name */
		strcpy(channel->name, channel_name);
		channel->enabled = 1;
		extended_ptr = channel->attr.extended.ptr;
		memcpy(&channel->attr, &chan_opts.attr, sizeof(chan_opts.attr));
		channel->attr.extended.ptr = extended_ptr;
		if (opt_monitor_timer.set) {
			ret = lttng_channel_set_monitor_timer_interval(channel,
					opt_monitor_timer.interval);
			if (ret) {
				ERR("Failed to set the channel's monitor timer interval");
				error = 1;
				goto error;
			}
		}
		if (opt_blocking_timeout.set) {
			ret = lttng_channel_set_blocking_timeout(channel,
					opt_blocking_timeout.value);
			if (ret) {
				ERR("Failed to set the channel's blocking timeout");
				error = 1;
				goto error;
			}
		}

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

		ret = lttng_enable_channel(handle, channel);
		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;
			case LTTNG_ERR_INVALID_CHANNEL_NAME:
				ERR("Invalid channel name: \"%s\". "
				    "Channel names may not start with '.', and "
				    "may not contain '/'.", channel_name);
				error = 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;
		}

skip_enable:
		if (lttng_opt_mi) {
			/* Mi print the channel element and leave it open */
			ret = mi_lttng_channel(writer, channel, 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, ",");
		lttng_channel_destroy(channel);
		channel = 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 (channel) {
		lttng_channel_destroy(channel);
	}
	/* 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;
}