Пример #1
0
int ctf_fs_metadata_set_trace(struct ctf_fs_trace *ctf_fs_trace,
		struct ctf_fs_metadata_config *config)
{
	int ret = 0;
	struct ctf_fs_file *file = NULL;
	struct ctf_metadata_decoder *metadata_decoder = NULL;
	struct ctf_metadata_decoder_config decoder_config = {
		.clock_class_offset_s = config ? config->clock_class_offset_s : 0,
		.clock_class_offset_ns = config ? config->clock_class_offset_ns : 0,
	};

	file = get_file(ctf_fs_trace->path->str);
	if (!file) {
		BT_LOGE("Cannot create metadata file object");
		ret = -1;
		goto end;
	}

	metadata_decoder = ctf_metadata_decoder_create(
		config ? &decoder_config : NULL,
		ctf_fs_trace->name->str);
	if (!metadata_decoder) {
		BT_LOGE("Cannot create metadata decoder object");
		ret = -1;
		goto end;
	}

	ret = ctf_metadata_decoder_decode(metadata_decoder, file->fp);
	if (ret) {
		BT_LOGE("Cannot decode metadata file");
		goto end;
	}

	ctf_fs_trace->metadata->trace = ctf_metadata_decoder_get_trace(
		metadata_decoder);
	assert(ctf_fs_trace->metadata->trace);

end:
	ctf_fs_file_destroy(file);
	ctf_metadata_decoder_destroy(metadata_decoder);
	return ret;
}

int ctf_fs_metadata_init(struct ctf_fs_metadata *metadata)
{
	/* Nothing to initialize for the moment. */
	return 0;
}

void ctf_fs_metadata_fini(struct ctf_fs_metadata *metadata)
{
	if (metadata->text) {
		free(metadata->text);
	}

	if (metadata->trace) {
		BT_PUT(metadata->trace);
	}
}
Пример #2
0
BT_HIDDEN
void lttng_live_metadata_fini(struct lttng_live_trace *trace)
{
	struct lttng_live_metadata *metadata = trace->metadata;

	if (!metadata) {
		return;
	}
	ctf_metadata_decoder_destroy(metadata->decoder);
	trace->metadata = NULL;
	g_free(metadata);
}
Пример #3
0
BT_HIDDEN
int lttng_live_metadata_create_stream(struct lttng_live_session *session,
		uint64_t ctf_trace_id,
		uint64_t stream_id,
		const char *trace_name)
{
	struct lttng_live_component *lttng_live =
		session->lttng_live_msg_iter->lttng_live_comp;
	struct lttng_live_metadata *metadata = NULL;
	struct lttng_live_trace *trace;
	const char *match;

	metadata = g_new0(struct lttng_live_metadata, 1);
	if (!metadata) {
		return -1;
	}
	metadata->stream_id = stream_id;

	match = strstr(trace_name, session->session_name->str);
	if (!match) {
		goto error;
	}

	metadata->decoder = ctf_metadata_decoder_create(
				lttng_live->self_comp, NULL);
	if (!metadata->decoder) {
		goto error;
	}
	trace = lttng_live_borrow_trace(session, ctf_trace_id);
	if (!trace) {
		goto error;
	}
	metadata->trace = trace;
	trace->metadata = metadata;
	return 0;

error:
	ctf_metadata_decoder_destroy(metadata->decoder);
	g_free(metadata);
	return -1;
}
Пример #4
0
BT_HIDDEN
struct ctf_metadata_decoder *ctf_metadata_decoder_create(
		const struct ctf_metadata_decoder_config *config,
		const char *name)
{
	struct ctf_metadata_decoder *mdec =
		g_new0(struct ctf_metadata_decoder, 1);
	struct ctf_metadata_decoder_config default_config = {
		.clock_class_offset_s = 0,
		.clock_class_offset_ns = 0,
	};

	if (!config) {
		config = &default_config;
	}

	BT_LOGD("Creating CTF metadata decoder: "
		"clock-class-offset-s=%" PRId64 ", "
		"clock-class-offset-ns=%" PRId64 ", name=\"%s\"",
		config->clock_class_offset_s, config->clock_class_offset_ns,
		name);

	if (!mdec) {
		BT_LOGE_STR("Failed to allocate one CTF metadata decoder.");
		goto end;
	}

	mdec->config = *config;
	mdec->visitor = ctf_visitor_generate_ir_create(config, name);
	if (!mdec->visitor) {
		BT_LOGE("Failed to create a CTF IR metadata AST visitor: "
			"mdec-addr=%p", mdec);
		ctf_metadata_decoder_destroy(mdec);
		mdec = NULL;
		goto end;
	}

	BT_LOGD("Creating CTF metadata decoder: "
		"clock-class-offset-s=%" PRId64 ", "
		"clock-class-offset-ns=%" PRId64 ", "
		"name=\"%s\", addr=%p",
		config->clock_class_offset_s, config->clock_class_offset_ns,
		name, mdec);

end:
	return mdec;
}

BT_HIDDEN
void ctf_metadata_decoder_destroy(struct ctf_metadata_decoder *mdec)
{
	if (!mdec) {
		return;
	}

	BT_LOGD("Destroying CTF metadata decoder: addr=%p", mdec);
	ctf_visitor_generate_ir_destroy(mdec->visitor);
	g_free(mdec);
}

BT_HIDDEN
enum ctf_metadata_decoder_status ctf_metadata_decoder_decode(
		struct ctf_metadata_decoder *mdec, FILE *fp)
{
	enum ctf_metadata_decoder_status status =
		CTF_METADATA_DECODER_STATUS_OK;
	int ret;
	struct ctf_scanner *scanner = NULL;
	char *buf = NULL;
	bool close_fp = false;

	assert(mdec);

	if (ctf_metadata_decoder_is_packetized(fp, &mdec->bo)) {
		BT_LOGD("Metadata stream is packetized: mdec-addr=%p", mdec);
		ret = ctf_metadata_decoder_packetized_file_stream_to_buf_with_mdec(
			mdec, fp, &buf, mdec->bo);
		if (ret) {
			BT_LOGE("Cannot decode packetized metadata packets to metadata text: "
				"mdec-addr=%p, ret=%d", mdec, ret);
			status = CTF_METADATA_DECODER_STATUS_ERROR;
			goto end;
		}

		if (strlen(buf) == 0) {
			/* An empty metadata packet is OK. */
			goto end;
		}

		/* Convert the real file pointer to a memory file pointer */
		fp = bt_fmemopen(buf, strlen(buf), "rb");
		close_fp = true;
		if (!fp) {
			BT_LOGE("Cannot memory-open metadata buffer: %s: "
				"mdec-addr=%p", strerror(errno), mdec);
			status = CTF_METADATA_DECODER_STATUS_ERROR;
			goto end;
		}
	} else {
		unsigned int major, minor;
		ssize_t nr_items;
		const long init_pos = ftell(fp);

		BT_LOGD("Metadata stream is plain text: mdec-addr=%p", mdec);

		if (init_pos < 0) {
			BT_LOGE_ERRNO("Failed to get current file position", ".");
			status = CTF_METADATA_DECODER_STATUS_ERROR;
			goto end;
		}

		/* Check text-only metadata header and version */
		nr_items = fscanf(fp, "/* CTF %10u.%10u", &major, &minor);
		if (nr_items < 2) {
			BT_LOGW("Missing \"/* CTF major.minor\" signature in plain text metadata file stream: "
				"mdec-addr=%p", mdec);
		}

		BT_LOGD("Found metadata stream version in signature: version=%u.%u", major, minor);

		if (!is_version_valid(major, minor)) {
			BT_LOGE("Invalid metadata version found in plain text signature: "
				"version=%u.%u, mdec-addr=%p", major, minor,
				mdec);
			status = CTF_METADATA_DECODER_STATUS_INVAL_VERSION;
			goto end;
		}

		if (fseek(fp, init_pos, SEEK_SET)) {
			BT_LOGE("Cannot seek metadata file stream to initial position: %s: "
				"mdec-addr=%p", strerror(errno), mdec);
			status = CTF_METADATA_DECODER_STATUS_ERROR;
			goto end;
		}
	}

	if (BT_LOG_ON_VERBOSE) {
		yydebug = 1;
	}

	/* Allocate a scanner and append the metadata text content */
	scanner = ctf_scanner_alloc();
	if (!scanner) {
		BT_LOGE("Cannot allocate a metadata lexical scanner: "
			"mdec-addr=%p", mdec);
		status = CTF_METADATA_DECODER_STATUS_ERROR;
		goto end;
	}

	assert(fp);
	ret = ctf_scanner_append_ast(scanner, fp);
	if (ret) {
		BT_LOGE("Cannot create the metadata AST out of the metadata text: "
			"mdec-addr=%p", mdec);
		status = CTF_METADATA_DECODER_STATUS_INCOMPLETE;
		goto end;
	}

	ret = ctf_visitor_semantic_check(0, &scanner->ast->root);
	if (ret) {
		BT_LOGE("Validation of the metadata semantics failed: "
			"mdec-addr=%p", mdec);
		status = CTF_METADATA_DECODER_STATUS_ERROR;
		goto end;
	}

	ret = ctf_visitor_generate_ir_visit_node(mdec->visitor,
		&scanner->ast->root);
	switch (ret) {
	case 0:
		/* Success */
		break;
	case -EINCOMPLETE:
		BT_LOGD("While visiting metadata AST: incomplete data: "
			"mdec-addr=%p", mdec);
		status = CTF_METADATA_DECODER_STATUS_INCOMPLETE;
		goto end;
	default:
		BT_LOGE("Failed to visit AST node to create CTF IR objects: "
			"mdec-addr=%p, ret=%d", mdec, ret);
		status = CTF_METADATA_DECODER_STATUS_IR_VISITOR_ERROR;
		goto end;
	}

end:
	if (scanner) {
		ctf_scanner_free(scanner);
	}

	yydebug = 0;

	if (fp && close_fp) {
		if (fclose(fp)) {
			BT_LOGE("Cannot close metadata file stream: "
				"mdec-addr=%p", mdec);
		}
	}

	if (buf) {
		free(buf);
	}

	return status;
}

BT_HIDDEN
struct bt_trace *ctf_metadata_decoder_get_trace(
		struct ctf_metadata_decoder *mdec)
{
	return ctf_visitor_generate_ir_get_trace(mdec->visitor);
}