Esempio n. 1
0
/*
 * Create a brand new session using name and url for destination.
 *
 * Returns LTTNG_OK on success or a negative error code.
 */
int lttng_create_session(const char *name, const char *url)
{
	int ret;
	ssize_t size;
	struct lttcomm_session_msg lsm;
	struct lttng_uri *uris = NULL;

	if (name == NULL) {
		return -LTTNG_ERR_INVALID;
	}

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

	lsm.cmd_type = LTTNG_CREATE_SESSION;
	copy_string(lsm.session.name, name, sizeof(lsm.session.name));

	/* There should never be a data URL */
	size = parse_str_urls_to_uri(url, NULL, &uris);
	if (size < 0) {
		return -LTTNG_ERR_INVALID;
	}

	lsm.u.uri.size = size;

	ret = ask_sessiond_varlen(&lsm, uris, sizeof(struct lttng_uri) * size,
			NULL);

	free(uris);
	return ret;
}
Esempio n. 2
0
/*
 * Set URL for a consumer for a session and domain.
 *
 * Return 0 on success, else a negative value.
 */
int lttng_set_consumer_url(struct lttng_handle *handle,
		const char *control_url, const char *data_url)
{
	int ret;
	ssize_t size;
	struct lttcomm_session_msg lsm;
	struct lttng_uri *uris = NULL;

	if (handle == NULL || (control_url == NULL && data_url == NULL)) {
		return -LTTNG_ERR_INVALID;
	}

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

	lsm.cmd_type = LTTNG_SET_CONSUMER_URI;

	copy_string(lsm.session.name, handle->session_name,
			sizeof(lsm.session.name));
	copy_lttng_domain(&lsm.domain, &handle->domain);

	size = parse_str_urls_to_uri(control_url, data_url, &uris);
	if (size < 0) {
		return -LTTNG_ERR_INVALID;
	}

	lsm.u.uri.size = size;

	ret = ask_sessiond_varlen(&lsm, uris, sizeof(struct lttng_uri) * size,
			NULL);

	free(uris);
	return ret;
}
Esempio n. 3
0
/*
 * This is an extension of create session that is ONLY and SHOULD only be used
 * by the lttng command line program. It exists to avoid using URI parsing in
 * the lttng client.
 *
 * We need the date and time for the trace path subdirectory for the case where
 * the user does NOT define one using either -o or -U. Using the normal
 * lttng_create_session API call, we have no clue on the session daemon side if
 * the URL was generated automatically by the client or define by the user.
 *
 * So this function "wrapper" is hidden from the public API, takes the datetime
 * string and appends it if necessary to the URI subdirectory before sending it
 * to the session daemon.
 *
 * With this extra function, the lttng_create_session call behavior is not
 * changed and the timestamp is appended to the URI on the session daemon side
 * if necessary.
 */
int _lttng_create_session_ext(const char *name, const char *url,
		const char *datetime)
{
	int ret;
	ssize_t size;
	struct lttcomm_session_msg lsm;
	struct lttng_uri *uris = NULL;

	if (name == NULL || datetime == NULL || url == NULL) {
		return -LTTNG_ERR_INVALID;
	}

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

	lsm.cmd_type = LTTNG_CREATE_SESSION;
	copy_string(lsm.session.name, name, sizeof(lsm.session.name));

	/* There should never be a data URL */
	size = parse_str_urls_to_uri(url, NULL, &uris);
	if (size < 0) {
		ret = -LTTNG_ERR_INVALID;
		goto error;
	}

	lsm.u.uri.size = size;

	if (size > 0 && uris[0].dtype != LTTNG_DST_PATH && strlen(uris[0].subdir) == 0) {
		/* Don't append datetime if the name was automatically created. */
		if (strncmp(name, DEFAULT_SESSION_NAME "-",
					strlen(DEFAULT_SESSION_NAME) + 1)) {
			ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s-%s",
					name, datetime);
		} else {
			ret = snprintf(uris[0].subdir, sizeof(uris[0].subdir), "%s", name);
		}
		if (ret < 0) {
			PERROR("snprintf uri subdir");
			ret = -LTTNG_ERR_FATAL;
			goto error;
		}
	}

	ret = ask_sessiond_varlen(&lsm, uris, sizeof(struct lttng_uri) * size,
			NULL);

error:
	free(uris);
	return ret;
}
Esempio n. 4
0
/*
 * Create or enable an event with a filter expression.
 *
 * Return negative error value on error.
 * Return size of returned session payload data if OK.
 */
int lttng_enable_event_with_filter(struct lttng_handle *handle,
		struct lttng_event *event, const char *channel_name,
		const char *filter_expression)
{
	struct lttcomm_session_msg lsm;
	struct filter_parser_ctx *ctx;
	FILE *fmem;
	int ret = 0;

	if (!filter_expression) {
		/*
		 * Fall back to normal event enabling if no filter
		 * specified.
		 */
		return lttng_enable_event(handle, event, channel_name);
	}

	/*
	 * Empty filter string will always be rejected by the parser
	 * anyway, so treat this corner-case early to eliminate
	 * lttng_fmemopen error for 0-byte allocation.
	 */
	if (handle == NULL || filter_expression[0] == '\0') {
		return -LTTNG_ERR_INVALID;
	}

	/*
	 * casting const to non-const, as the underlying function will
	 * use it in read-only mode.
	 */
	fmem = lttng_fmemopen((void *) filter_expression,
			strlen(filter_expression), "r");
	if (!fmem) {
		fprintf(stderr, "Error opening memory as stream\n");
		return -LTTNG_ERR_FILTER_NOMEM;
	}
	ctx = filter_parser_ctx_alloc(fmem);
	if (!ctx) {
		fprintf(stderr, "Error allocating parser\n");
		ret = -LTTNG_ERR_FILTER_NOMEM;
		goto alloc_error;
	}
	ret = filter_parser_ctx_append_ast(ctx);
	if (ret) {
		fprintf(stderr, "Parse error\n");
		ret = -LTTNG_ERR_FILTER_INVAL;
		goto parse_error;
	}
	ret = filter_visitor_set_parent(ctx);
	if (ret) {
		fprintf(stderr, "Set parent error\n");
		ret = -LTTNG_ERR_FILTER_INVAL;
		goto parse_error;
	}
	if (print_xml) {
		ret = filter_visitor_print_xml(ctx, stdout, 0);
		if (ret) {
			fflush(stdout);
			fprintf(stderr, "XML print error\n");
			ret = -LTTNG_ERR_FILTER_INVAL;
			goto parse_error;
		}
	}

	dbg_printf("Generating IR... ");
	fflush(stdout);
	ret = filter_visitor_ir_generate(ctx);
	if (ret) {
		fprintf(stderr, "Generate IR error\n");
		ret = -LTTNG_ERR_FILTER_INVAL;
		goto parse_error;
	}
	dbg_printf("done\n");

	dbg_printf("Validating IR... ");
	fflush(stdout);
	ret = filter_visitor_ir_check_binary_op_nesting(ctx);
	if (ret) {
		ret = -LTTNG_ERR_FILTER_INVAL;
		goto parse_error;
	}
	dbg_printf("done\n");

	dbg_printf("Generating bytecode... ");
	fflush(stdout);
	ret = filter_visitor_bytecode_generate(ctx);
	if (ret) {
		fprintf(stderr, "Generate bytecode error\n");
		ret = -LTTNG_ERR_FILTER_INVAL;
		goto parse_error;
	}
	dbg_printf("done\n");
	dbg_printf("Size of bytecode generated: %u bytes.\n",
		bytecode_get_len(&ctx->bytecode->b));

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

	lsm.cmd_type = LTTNG_ENABLE_EVENT_WITH_FILTER;

	/* Copy channel name */
	copy_string(lsm.u.enable.channel_name, channel_name,
			sizeof(lsm.u.enable.channel_name));
	/* Copy event name */
	if (event) {
		memcpy(&lsm.u.enable.event, event, sizeof(lsm.u.enable.event));
	}

	lsm.u.enable.bytecode_len = sizeof(ctx->bytecode->b)
			+ bytecode_get_len(&ctx->bytecode->b);

	copy_lttng_domain(&lsm.domain, &handle->domain);

	copy_string(lsm.session.name, handle->session_name,
			sizeof(lsm.session.name));

	ret = ask_sessiond_varlen(&lsm, &ctx->bytecode->b,
				lsm.u.enable.bytecode_len, NULL);

	filter_bytecode_free(ctx);
	filter_ir_free(ctx);
	filter_parser_ctx_free(ctx);
	if (fclose(fmem) != 0) {
		perror("fclose");
	}
	return ret;

parse_error:
	filter_bytecode_free(ctx);
	filter_ir_free(ctx);
	filter_parser_ctx_free(ctx);
alloc_error:
	if (fclose(fmem) != 0) {
		perror("fclose");
	}
	return ret;
}
Esempio n. 5
0
/*
 * Ask the session daemon a specific command and put the data into buf.
 *
 * Return size of data (only payload, not header) or a negative error code.
 */
static int ask_sessiond(struct lttcomm_session_msg *lsm, void **buf)
{
	return ask_sessiond_varlen(lsm, NULL, 0, buf);
}