Exemple #1
0
static
struct bt_value *bt_attributes_get_field_by_name(
		struct bt_value *attr_obj, const char *name)
{
	uint64_t i;
	int64_t attr_size;
	struct bt_value *value_obj = NULL;
	struct bt_value *attr_field_name_obj = NULL;

	attr_size = bt_value_array_size(attr_obj);
	if (attr_size < 0) {
		BT_LOGE("Cannot get array value's size: value-addr=%p",
			attr_obj);
		goto error;
	}

	for (i = 0; i < attr_size; ++i) {
		int ret;
		const char *field_name;

		value_obj = bt_value_array_get(attr_obj, i);
		if (!value_obj) {
			BT_LOGE("Cannot get attributes object's array value's element by index: "
				"value-addr=%p, index=%" PRIu64, attr_obj, i);
			goto error;
		}

		attr_field_name_obj = bt_value_array_get(value_obj, 0);
		if (!attr_field_name_obj) {
			BT_LOGE("Cannot get attribute array value's element by index: "
				"value-addr=%p, index=%" PRIu64,
				value_obj, (int64_t) 0);
			goto error;
		}

		ret = bt_value_string_get(attr_field_name_obj, &field_name);
		if (ret) {
			BT_LOGE("Cannot get raw value from string value: value-addr=%p",
				attr_field_name_obj);
			goto error;
		}

		if (!strcmp(field_name, name)) {
			BT_PUT(attr_field_name_obj);
			break;
		}

		BT_PUT(attr_field_name_obj);
		BT_PUT(value_obj);
	}

	return value_obj;

error:
	BT_PUT(attr_field_name_obj);
	BT_PUT(value_obj);

	return value_obj;
}
Exemple #2
0
static
int set_trace_name(bt_trace *trace, const char *name_suffix)
{
	int ret = 0;
	const bt_trace_class *tc = bt_trace_borrow_class_const(trace);
	const bt_value *val;
	GString *name;

	name = g_string_new(NULL);
	if (!name) {
		BT_LOGE_STR("Failed to allocate a GString.");
		ret = -1;
		goto end;
	}

	/*
	 * Check if we have a trace environment string value named `hostname`.
	 * If so, use it as the trace name's prefix.
	 */
	val = bt_trace_class_borrow_environment_entry_value_by_name_const(
		tc, "hostname");
	if (val && bt_value_is_string(val)) {
		g_string_append(name, bt_value_string_get(val));

		if (name_suffix) {
			g_string_append_c(name, G_DIR_SEPARATOR);
		}
	}

	if (name_suffix) {
		g_string_append(name, name_suffix);
	}

	ret = bt_trace_set_name(trace, name->str);
	if (ret) {
		goto end;
	}

	goto end;

end:
	if (name) {
		g_string_free(name, TRUE);
	}

	return ret;
}
Exemple #3
0
BT_HIDDEN
const char *bt_attributes_get_field_name(struct bt_value *attr_obj,
		uint64_t index)
{
	int rc;
	const char *ret = NULL;
	struct bt_value *attr_field_obj = NULL;
	struct bt_value *attr_field_name_obj = NULL;

	if (!attr_obj) {
		BT_LOGW_STR("Invalid parameter: attributes object is NULL.");
		goto end;
	}

	attr_field_obj = bt_value_array_get(attr_obj, index);
	if (!attr_field_obj) {
		BT_LOGE("Cannot get attributes object's array value's element by index: "
			"value-addr=%p, index=%" PRIu64, attr_obj, index);
		goto end;
	}

	attr_field_name_obj = bt_value_array_get(attr_field_obj,
		BT_ATTR_NAME_INDEX);
	if (!attr_field_name_obj) {
		BT_LOGE("Cannot get attribute array value's element by index: "
			"value-addr=%p, index=%" PRIu64, attr_field_obj,
			(uint64_t) BT_ATTR_NAME_INDEX);
		goto end;
	}

	rc = bt_value_string_get(attr_field_name_obj, &ret);
	if (rc) {
		BT_LOGE("Cannot get raw value from string value: value-addr=%p",
			attr_field_name_obj);
		ret = NULL;
	}

end:
	BT_PUT(attr_field_name_obj);
	BT_PUT(attr_field_obj);
	return ret;
}
Exemple #4
0
int ctf_fs_component_create_ctf_fs_traces(bt_self_component_source *self_comp,
		struct ctf_fs_component *ctf_fs,
		const bt_value *paths_value)
{
	int ret = 0;
	uint64_t i;

	for (i = 0; i < bt_value_array_get_size(paths_value); i++) {
		const bt_value *path_value = bt_value_array_borrow_element_by_index_const(paths_value, i);
		const char *path = bt_value_string_get(path_value);

		ret = ctf_fs_component_create_ctf_fs_traces_one_root(self_comp, ctf_fs, path);
		if (ret) {
			goto end;
		}
	}

	merge_traces_with_same_uuid(ctf_fs);

end:
	return ret;
}
BT_HIDDEN
const char *bt_ctf_event_class_get_name(struct bt_ctf_event_class *event_class)
{
	struct bt_value *obj = NULL;
	const char *name = NULL;

	if (!event_class) {
		goto end;
	}

	obj = bt_ctf_attributes_get_field_value(event_class->attributes,
		BT_CTF_EVENT_CLASS_ATTR_NAME_INDEX);
	if (!obj) {
		goto end;
	}

	if (bt_value_string_get(obj, &name)) {
		name = NULL;
	}

end:
	BT_PUT(obj);
	return name;
}
Exemple #6
0
static
void append_env_metadata(struct bt_ctf_trace *trace,
		struct metadata_context *context)
{
	int i;
	int env_size;

	env_size = bt_ctf_attributes_get_count(trace->environment);

	if (env_size <= 0) {
		return;
	}

	g_string_append(context->string, "env {\n");

	for (i = 0; i < env_size; ++i) {
		struct bt_value *env_field_value_obj = NULL;
		const char *entry_name;

		entry_name = bt_ctf_attributes_get_field_name(
			trace->environment, i);
		env_field_value_obj = bt_ctf_attributes_get_field_value(
			trace->environment, i);

		if (!entry_name || !env_field_value_obj) {
			goto loop_next;
		}

		switch (bt_value_get_type(env_field_value_obj)) {
		case BT_VALUE_TYPE_INTEGER:
		{
			int ret;
			int64_t int_value;

			ret = bt_value_integer_get(env_field_value_obj,
				&int_value);

			if (ret) {
				goto loop_next;
			}

			g_string_append_printf(context->string,
				"\t%s = %" PRId64 ";\n", entry_name,
				int_value);
			break;
		}
		case BT_VALUE_TYPE_STRING:
		{
			int ret;
			const char *str_value;
			char *escaped_str = NULL;

			ret = bt_value_string_get(env_field_value_obj,
				&str_value);

			if (ret) {
				goto loop_next;
			}

			escaped_str = g_strescape(str_value, NULL);

			if (!escaped_str) {
				goto loop_next;
			}

			g_string_append_printf(context->string,
				"\t%s = \"%s\";\n", entry_name, escaped_str);
			free(escaped_str);
			break;
		}

		default:
			goto loop_next;
		}

loop_next:
		BT_PUT(env_field_value_obj);
	}

	g_string_append(context->string, "};\n\n");
}
BT_HIDDEN
int bt_ctf_event_class_serialize(struct bt_ctf_event_class *event_class,
		struct metadata_context *context)
{
	int i;
	int count;
	int ret = 0;
	struct bt_value *attr_value = NULL;

	assert(event_class);
	assert(context);

	context->current_indentation_level = 1;
	g_string_assign(context->field_name, "");
	g_string_append(context->string, "event {\n");
	count = bt_ctf_event_class_get_attribute_count(event_class);

	if (count < 0) {
		ret = -1;
		goto end;
	}

	for (i = 0; i < count; ++i) {
		const char *attr_name = NULL;

		attr_name = bt_ctf_event_class_get_attribute_name(
			event_class, i);
		attr_value = bt_ctf_event_class_get_attribute_value(
			event_class, i);

		if (!attr_name || !attr_value) {
			ret = -1;
			goto end;
		}

		switch (bt_value_get_type(attr_value)) {
		case BT_VALUE_TYPE_INTEGER:
		{
			int64_t value;

			ret = bt_value_integer_get(attr_value, &value);

			if (ret) {
				goto end;
			}

			g_string_append_printf(context->string,
				"\t%s = %" PRId64 ";\n", attr_name, value);
			break;
		}

		case BT_VALUE_TYPE_STRING:
		{
			const char *value;

			ret = bt_value_string_get(attr_value, &value);

			if (ret) {
				goto end;
			}

			g_string_append_printf(context->string,
				"\t%s = \"%s\";\n", attr_name, value);
			break;
		}

		default:
			/* should never happen */
			assert(false);
			break;
		}

		BT_PUT(attr_value);
	}

	if (event_class->context) {
		g_string_append(context->string, "\tcontext := ");
		ret = bt_ctf_field_type_serialize(event_class->context,
			context);
		if (ret) {
			goto end;
		}
		g_string_append(context->string, ";\n");
	}

	if (event_class->fields) {
		g_string_append(context->string, "\tfields := ");
		ret = bt_ctf_field_type_serialize(event_class->fields, context);
		if (ret) {
			goto end;
		}
		g_string_append(context->string, ";\n");
	}

	g_string_append(context->string, "};\n\n");
end:
	context->current_indentation_level = 0;
	BT_PUT(attr_value);
	return ret;
}
Exemple #8
0
/*
 * Parses a timestamp, figuring out its format.
 *
 * Returns a negative value if anything goes wrong.
 *
 * Expected formats:
 *
 *   YYYY-MM-DD hh:mm:ss.ns
 *   hh:mm:ss.ns
 *   -ss.ns
 *   ss.ns
 *   YYYY-MM-DD hh:mm:ss
 *   hh:mm:ss
 *   -ss
 *   ss
 */
static
int timestamp_from_arg(const char *arg, struct trimmer *trimmer,
		struct trimmer_bound *result_bound, bt_bool gmt)
{
	int ret;
	int64_t value;
	unsigned int year, month, day, hh, mm, ss, ns;

	/* YYYY-MM-DD hh:mm:ss.ns */
	ret = sscanf(arg, "%u-%u-%u %u:%u:%u.%u",
		&year, &month, &day, &hh, &mm, &ss, &ns);
	if (ret == 7) {
		struct tm tm = {
			.tm_sec = ss,
			.tm_min = mm,
			.tm_hour = hh,
			.tm_mday = day,
			.tm_mon = month - 1,
			.tm_year = year - 1900,
			.tm_isdst = -1,
		};
		time_t result;

		if (gmt) {
			result = bt_timegm(&tm);
			if (result < 0) {
				return -1;
			}
		} else {
			result = mktime(&tm);
			if (result < 0) {
				return -1;
			}
		}
		value = (int64_t) result;
		value *= NSEC_PER_SEC;
		value += ns;
		if (!trimmer->date) {
			trimmer->year = year;
			trimmer->month = month;
			trimmer->day = day;
			trimmer->date = true;
		}
		goto set;
	}
	/* hh:mm:ss.ns */
	ret = sscanf(arg, "%u:%u:%u.%u",
		&hh, &mm, &ss, &ns);
	if (ret == 4) {
		if (!trimmer->date) {
			/* We don't know which day until we get an event. */
			result_bound->lazy_values.hh = hh;
			result_bound->lazy_values.mm = mm;
			result_bound->lazy_values.ss = ss;
			result_bound->lazy_values.ns = ns;
			result_bound->lazy_values.gmt = gmt;
			goto lazy;
		} else {
			struct tm tm = {
				.tm_sec = ss,
				.tm_min = mm,
				.tm_hour = hh,
				.tm_mday = trimmer->day,
				.tm_mon = trimmer->month - 1,
				.tm_year = trimmer->year - 1900,
				.tm_isdst = -1,
			};
			time_t result;

			if (gmt) {
				result = bt_timegm(&tm);
				if (result < 0) {
					return -1;
				}
			} else {
				result = mktime(&tm);
				if (result < 0) {
					return -1;
				}
			}
			value = (int64_t) result;
			value *= NSEC_PER_SEC;
			value += ns;
			goto set;
		}
	}
	/* -ss.ns */
	ret = sscanf(arg, "-%u.%u",
		&ss, &ns);
	if (ret == 2) {
		value = -ss * NSEC_PER_SEC;
		value -= ns;
		goto set;
	}
	/* ss.ns */
	ret = sscanf(arg, "%u.%u",
		&ss, &ns);
	if (ret == 2) {
		value = ss * NSEC_PER_SEC;
		value += ns;
		goto set;
	}

	/* YYYY-MM-DD hh:mm:ss */
	ret = sscanf(arg, "%u-%u-%u %u:%u:%u",
		&year, &month, &day, &hh, &mm, &ss);
	if (ret == 6) {
		struct tm tm = {
			.tm_sec = ss,
			.tm_min = mm,
			.tm_hour = hh,
			.tm_mday = day,
			.tm_mon = month - 1,
			.tm_year = year - 1900,
			.tm_isdst = -1,
		};

		if (gmt) {
			value = bt_timegm(&tm);
			if (value < 0) {
				return -1;
			}
		} else {
			value = mktime(&tm);
			if (value < 0) {
				return -1;
			}
		}
		value *= NSEC_PER_SEC;
		if (!trimmer->date) {
			trimmer->year = year;
			trimmer->month = month;
			trimmer->day = day;
			trimmer->date = true;
		}
		goto set;
	}
	/* hh:mm:ss */
	ret = sscanf(arg, "%u:%u:%u",
		&hh, &mm, &ss);
	if (ret == 3) {
		if (!trimmer->date) {
			/* We don't know which day until we get an event. */
			result_bound->lazy_values.hh = hh;
			result_bound->lazy_values.mm = mm;
			result_bound->lazy_values.ss = ss;
			result_bound->lazy_values.ns = 0;
			result_bound->lazy_values.gmt = gmt;
			goto lazy;
		} else {
			struct tm tm = {
				.tm_sec = ss,
				.tm_min = mm,
				.tm_hour = hh,
				.tm_mday = trimmer->day,
				.tm_mon = trimmer->month - 1,
				.tm_year = trimmer->year - 1900,
				.tm_isdst = -1,
			};
			time_t result;

			if (gmt) {
				result = bt_timegm(&tm);
				if (result < 0) {
					return -1;
				}
			} else {
				result = mktime(&tm);
				if (result < 0) {
					return -1;
				}
			}
			value = (int64_t) result;
			value *= NSEC_PER_SEC;
			goto set;
		}
	}
	/* -ss */
	ret = sscanf(arg, "-%u",
		&ss);
	if (ret == 1) {
		value = -ss * NSEC_PER_SEC;
		goto set;
	}
	/* ss */
	ret = sscanf(arg, "%u",
		&ss);
	if (ret == 1) {
		value = ss * NSEC_PER_SEC;
		goto set;
	}

	/* Not found. */
	return -1;

set:
	result_bound->value = value;
	result_bound->set = true;
	return 0;

lazy:
	result_bound->lazy = true;
	return 0;
}

static
enum bt_component_status init_from_params(struct trimmer *trimmer,
		struct bt_value *params)
{
	struct bt_value *value = NULL;
	bt_bool gmt = BT_FALSE;
	enum bt_component_status ret = BT_COMPONENT_STATUS_OK;

	assert(params);

        value = bt_value_map_get(params, "clock-gmt");
	if (value) {
		enum bt_value_status value_ret;

		value_ret = bt_value_bool_get(value, &gmt);
		if (value_ret) {
			ret = BT_COMPONENT_STATUS_INVALID;
			printf_error("Failed to retrieve clock-gmt value. Expecting a boolean");
		}
	}
	bt_put(value);
	if (ret != BT_COMPONENT_STATUS_OK) {
		goto end;
	}

        value = bt_value_map_get(params, "begin");
	if (value) {
		enum bt_value_status value_ret;
		const char *str;

		value_ret = bt_value_string_get(value, &str);
		if (value_ret || timestamp_from_arg(str,
				trimmer, &trimmer->begin, gmt)) {
			ret = BT_COMPONENT_STATUS_INVALID;
			printf_error("Failed to retrieve begin value. Expecting a timestamp string");
		}
	}
	bt_put(value);
	if (ret != BT_COMPONENT_STATUS_OK) {
		goto end;
	}

        value = bt_value_map_get(params, "end");
	if (value) {
		enum bt_value_status value_ret;
		const char *str;

		value_ret = bt_value_string_get(value, &str);
		if (value_ret || timestamp_from_arg(str,
				trimmer, &trimmer->end, gmt)) {
			ret = BT_COMPONENT_STATUS_INVALID;
			printf_error("Failed to retrieve end value. Expecting a timestamp string");
		}
	}
	bt_put(value);
end:
	if (trimmer->begin.set && trimmer->end.set) {
		if (trimmer->begin.value > trimmer->end.value) {
			printf_error("Unexpected: time range begin value is above end value");
			ret = BT_COMPONENT_STATUS_INVALID;
		}
	}
	return ret;
}

enum bt_component_status trimmer_component_init(
	struct bt_private_component *component, struct bt_value *params,
	UNUSED_VAR void *init_method_data)
{
	enum bt_component_status ret;
	struct trimmer *trimmer = create_trimmer_data();

	if (!trimmer) {
		ret = BT_COMPONENT_STATUS_NOMEM;
		goto end;
	}

	/* Create input and output ports */
	ret = bt_private_component_filter_add_input_private_port(
		component, "in", NULL, NULL);
	if (ret != BT_COMPONENT_STATUS_OK) {
		goto error;
	}

	ret = bt_private_component_filter_add_output_private_port(
		component, "out", NULL, NULL);
	if (ret != BT_COMPONENT_STATUS_OK) {
		goto error;
	}

	ret = bt_private_component_set_user_data(component, trimmer);
	if (ret != BT_COMPONENT_STATUS_OK) {
		goto error;
	}

	ret = init_from_params(trimmer, params);
end:
	return ret;
error:
	destroy_trimmer_data(trimmer);
	ret = BT_COMPONENT_STATUS_ERROR;
	return ret;
}