enum ustctl_abstract_types {
ustctl_atype_integer,
- ustctl_atype_enum,
- ustctl_atype_array,
- ustctl_atype_sequence,
+ ustctl_atype_enum, /* legacy */
+ ustctl_atype_array, /* legacy */
+ ustctl_atype_sequence, /* legacy */
ustctl_atype_string,
ustctl_atype_float,
- ustctl_atype_variant,
- ustctl_atype_struct,
+ ustctl_atype_variant, /* legacy */
+ ustctl_atype_struct, /* legacy */
+ ustctl_atype_enum_nestable,
+ ustctl_atype_array_nestable,
+ ustctl_atype_sequence_nestable,
+ ustctl_atype_struct_nestable,
+ ustctl_atype_variant_nestable,
NR_USTCTL_ABSTRACT_TYPES,
};
} u;
} LTTNG_PACKED;
+/* legacy */
#define USTCTL_UST_BASIC_TYPE_PADDING 296
union _ustctl_basic_type {
struct ustctl_integer_type integer;
char padding[USTCTL_UST_BASIC_TYPE_PADDING];
} LTTNG_PACKED;
+/* legacy */
struct ustctl_basic_type {
enum ustctl_abstract_types atype;
union {
} u;
} LTTNG_PACKED;
-#define USTCTL_UST_TYPE_PADDING 128
+/*
+ * Padding is derived from largest member: u.legacy.sequence which
+ * contains two basic types, each with USTCTL_UST_BASIC_TYPE_PADDING.
+ */
+#define USTCTL_UST_TYPE_PADDING (2 * USTCTL_UST_BASIC_TYPE_PADDING)
struct ustctl_type {
enum ustctl_abstract_types atype;
union {
- union _ustctl_basic_type basic;
+ struct ustctl_integer_type integer;
+ struct ustctl_float_type _float;
+ struct {
+ int32_t encoding; /* enum ustctl_string_encodings */
+ } string;
+ struct {
+ char name[LTTNG_UST_SYM_NAME_LEN];
+ uint64_t id; /* enum ID in sessiond. */
+ /* container_type follows after this struct ustctl_field. */
+ } enum_nestable;
struct {
- struct ustctl_basic_type elem_type;
uint32_t length; /* num. elems. */
- } array;
+ uint32_t alignment;
+ /* elem_type follows after this struct ustctl_field. */
+ } array_nestable;
struct {
- struct ustctl_basic_type length_type;
- struct ustctl_basic_type elem_type;
- } sequence;
+ char length_name[LTTNG_UST_SYM_NAME_LEN];
+ uint32_t alignment; /* Alignment before elements. */
+ /* elem_type follows after the length_type. */
+ } sequence_nestable;
+ struct {
+ uint32_t nr_fields;
+ uint32_t alignment;
+ /* Followed by nr_fields struct ustctl_field. */
+ } struct_nestable;
struct {
uint32_t nr_choices;
char tag_name[LTTNG_UST_SYM_NAME_LEN];
+ uint32_t alignment;
/* Followed by nr_choices struct ustctl_field. */
- } variant;
- struct {
- uint32_t nr_fields;
- /* Followed by nr_fields struct ustctl_field. */
- } _struct;
+ } variant_nestable;
+
+ /* Legacy ABI */
+ union {
+ union _ustctl_basic_type basic;
+ struct {
+ struct ustctl_basic_type elem_type;
+ uint32_t length; /* num. elems. */
+ } array;
+ struct {
+ struct ustctl_basic_type length_type;
+ struct ustctl_basic_type elem_type;
+ } sequence;
+ struct {
+ uint32_t nr_fields;
+ /* Followed by nr_fields struct ustctl_field. */
+ } _struct;
+ struct {
+ uint32_t nr_choices;
+ char tag_name[LTTNG_UST_SYM_NAME_LEN];
+ /* Followed by nr_choices struct ustctl_field. */
+ } variant;
+ } legacy;
char padding[USTCTL_UST_TYPE_PADDING];
} u;
} LTTNG_PACKED;
case ustctl_atype_string:
case ustctl_atype_float:
if (!match_ustctl_field_raw_basic_type(first->type.atype,
- &first->type.u.basic, second->type.atype,
- &second->type.u.basic)) {
+ &first->type.u.legacy.basic, second->type.atype,
+ &second->type.u.legacy.basic)) {
goto no_match;
}
break;
case ustctl_atype_sequence:
/* Match element type of the sequence. */
- if (!match_ustctl_field_basic_type(&first->type.u.sequence.elem_type,
- &second->type.u.sequence.elem_type)) {
+ if (!match_ustctl_field_basic_type(&first->type.u.legacy.sequence.elem_type,
+ &second->type.u.legacy.sequence.elem_type)) {
goto no_match;
}
/* Match length type of the sequence. */
- if (!match_ustctl_field_basic_type(&first->type.u.sequence.length_type,
- &second->type.u.sequence.length_type)) {
+ if (!match_ustctl_field_basic_type(&first->type.u.legacy.sequence.length_type,
+ &second->type.u.legacy.sequence.length_type)) {
goto no_match;
}
break;
case ustctl_atype_array:
/* Match element type of the array. */
- if (!match_ustctl_field_basic_type(&first->type.u.array.elem_type,
- &second->type.u.array.elem_type)) {
+ if (!match_ustctl_field_basic_type(&first->type.u.legacy.array.elem_type,
+ &second->type.u.legacy.array.elem_type)) {
goto no_match;
}
/* Match length of the array. */
- if (first->type.u.array.length != second->type.u.array.length) {
+ if (first->type.u.legacy.array.length != second->type.u.legacy.array.length) {
goto no_match;
}
break;
case ustctl_atype_variant:
/* Compare number of choice of the variants. */
- if (first->type.u.variant.nr_choices !=
- second->type.u.variant.nr_choices) {
+ if (first->type.u.legacy.variant.nr_choices !=
+ second->type.u.legacy.variant.nr_choices) {
goto no_match;
}
/* Compare tag name of the variants. */
- if (strncmp(first->type.u.variant.tag_name,
- second->type.u.variant.tag_name,
+ if (strncmp(first->type.u.legacy.variant.tag_name,
+ second->type.u.legacy.variant.tag_name,
LTTNG_UST_SYM_NAME_LEN)) {
goto no_match;
}
break;
case ustctl_atype_struct:
/* Compare number of fields of the structs. */
- if (first->type.u._struct.nr_fields != second->type.u._struct.nr_fields) {
+ if (first->type.u.legacy._struct.nr_fields != second->type.u.legacy._struct.nr_fields) {
+ goto no_match;
+ }
+ break;
+ case ustctl_atype_sequence_nestable:
+ if (first->type.u.sequence_nestable.alignment != second->type.u.sequence_nestable.alignment) {
+ goto no_match;
+ }
+ /* Compare length_name of the sequences. */
+ if (strncmp(first->type.u.sequence_nestable.length_name,
+ second->type.u.sequence_nestable.length_name,
+ LTTNG_UST_SYM_NAME_LEN)) {
+ goto no_match;
+ }
+ /* Comparison will be done when marshalling following items. */
+ break;
+ case ustctl_atype_array_nestable:
+ if (first->type.u.array_nestable.alignment != second->type.u.array_nestable.alignment) {
+ goto no_match;
+ }
+ /* Match length of the array. */
+ if (first->type.u.array_nestable.length != second->type.u.array_nestable.length) {
+ goto no_match;
+ }
+ /* Comparison of element type will be done when marshalling following item. */
+ break;
+ case ustctl_atype_enum_nestable:
+ if (first->type.u.enum_nestable.id != second->type.u.enum_nestable.id) {
+ goto no_match;
+ }
+ /* Compare name of the enums. */
+ if (strncmp(first->type.u.enum_nestable.name,
+ second->type.u.enum_nestable.name,
+ LTTNG_UST_SYM_NAME_LEN)) {
+ goto no_match;
+ }
+ /* Comparison of element type will be done when marshalling following item. */
+ break;
+ case ustctl_atype_struct_nestable:
+ if (first->type.u.struct_nestable.alignment != second->type.u.struct_nestable.alignment) {
+ goto no_match;
+ }
+ /* Compare number of fields of the structs. */
+ if (first->type.u.struct_nestable.nr_fields != second->type.u.struct_nestable.nr_fields) {
+ goto no_match;
+ }
+ break;
+ case ustctl_atype_variant_nestable:
+ if (first->type.u.variant_nestable.alignment != second->type.u.variant_nestable.alignment) {
+ goto no_match;
+ }
+ /* Compare number of choice of the variants. */
+ if (first->type.u.variant_nestable.nr_choices !=
+ second->type.u.variant_nestable.nr_choices) {
+ goto no_match;
+ }
+
+ /* Compare tag name of the variants. */
+ if (strncmp(first->type.u.variant_nestable.tag_name,
+ second->type.u.variant_nestable.tag_name,
+ LTTNG_UST_SYM_NAME_LEN)) {
goto no_match;
}
break;
static
int _lttng_variant_statedump(struct ust_registry_session *session,
+ uint32_t nr_choices, const char *tag_name,
+ uint32_t alignment,
const struct ustctl_field *fields, size_t nr_fields,
size_t *iter_field, size_t nesting)
{
const struct ustctl_field *variant = &fields[*iter_field];
- uint32_t nr_choices, i;
+ uint32_t i;
int ret;
char identifier[LTTNG_UST_SYM_NAME_LEN];
ret = -EINVAL;
goto end;
}
- nr_choices = variant->type.u.variant.nr_choices;
(*iter_field)++;
- sanitize_ctf_identifier(identifier, variant->type.u.variant.tag_name);
+ sanitize_ctf_identifier(identifier, tag_name);
+ if (alignment) {
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "struct { } align(%u) _%s_padding;\n",
+ alignment * CHAR_BIT,
+ variant->name);
+ if (ret) {
+ goto end;
+ }
+ }
ret = print_tabs(session, nesting);
if (ret) {
goto end;
}
ret = lttng_metadata_printf(session,
"integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s;\n",
- field->type.u.basic.integer.size,
- field->type.u.basic.integer.alignment,
- field->type.u.basic.integer.signedness,
- (field->type.u.basic.integer.encoding == ustctl_encode_none)
+ field->type.u.integer.size,
+ field->type.u.integer.alignment,
+ field->type.u.integer.signedness,
+ (field->type.u.integer.encoding == ustctl_encode_none)
? "none"
- : (field->type.u.basic.integer.encoding == ustctl_encode_UTF8)
+ : (field->type.u.integer.encoding == ustctl_encode_UTF8)
? "UTF8"
: "ASCII",
- field->type.u.basic.integer.base,
- field->type.u.basic.integer.reverse_byte_order ? bo_reverse : bo_native,
+ field->type.u.integer.base,
+ field->type.u.integer.reverse_byte_order ? bo_reverse : bo_native,
field->name);
(*iter_field)++;
break;
case ustctl_atype_enum:
ret = ust_metadata_enum_statedump(session,
- field->type.u.basic.enumeration.name,
- field->type.u.basic.enumeration.id,
- &field->type.u.basic.enumeration.container_type,
+ field->type.u.legacy.basic.enumeration.name,
+ field->type.u.legacy.basic.enumeration.id,
+ &field->type.u.legacy.basic.enumeration.container_type,
field->name, iter_field, nesting);
break;
case ustctl_atype_float:
}
ret = lttng_metadata_printf(session,
"floating_point { exp_dig = %u; mant_dig = %u; align = %u;%s } _%s;\n",
- field->type.u.basic._float.exp_dig,
- field->type.u.basic._float.mant_dig,
- field->type.u.basic._float.alignment,
- field->type.u.basic.integer.reverse_byte_order ? bo_reverse : bo_native,
+ field->type.u._float.exp_dig,
+ field->type.u._float.mant_dig,
+ field->type.u._float.alignment,
+ field->type.u._float.reverse_byte_order ? bo_reverse : bo_native,
field->name);
(*iter_field)++;
break;
if (ret) {
goto end;
}
- elem_type = &field->type.u.array.elem_type;
+ elem_type = &field->type.u.legacy.array.elem_type;
+ /* Only integers are currently supported in arrays. */
+ if (elem_type->atype != ustctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
ret = lttng_metadata_printf(session,
"integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
elem_type->u.basic.integer.size,
: "ASCII",
elem_type->u.basic.integer.base,
elem_type->u.basic.integer.reverse_byte_order ? bo_reverse : bo_native,
- field->name, field->type.u.array.length);
+ field->name, field->type.u.legacy.array.length);
+ (*iter_field)++;
+ break;
+ }
+ case ustctl_atype_array_nestable:
+ {
+ uint32_t array_length;
+ const struct ustctl_field *array_nestable;
+ const struct ustctl_type *elem_type;
+
+ array_length = field->type.u.array_nestable.length;
+ (*iter_field)++;
+
+ if (*iter_field >= nr_fields) {
+ ret = -EOVERFLOW;
+ goto end;
+ }
+ array_nestable = &fields[*iter_field];
+ elem_type = &array_nestable->type;
+
+ /* Only integers are currently supported in arrays. */
+ if (elem_type->atype != ustctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ if (field->type.u.array_nestable.alignment) {
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "struct { } align(%u) _%s_padding;\n",
+ field->type.u.array_nestable.alignment * CHAR_BIT,
+ field->name);
+ if (ret) {
+ goto end;
+ }
+ }
+
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[%u];\n",
+ elem_type->u.integer.size,
+ elem_type->u.integer.alignment,
+ elem_type->u.integer.signedness,
+ (elem_type->u.integer.encoding == ustctl_encode_none)
+ ? "none"
+ : (elem_type->u.integer.encoding == ustctl_encode_UTF8)
+ ? "UTF8"
+ : "ASCII",
+ elem_type->u.integer.base,
+ elem_type->u.integer.reverse_byte_order ? bo_reverse : bo_native,
+ field->name, array_length);
(*iter_field)++;
break;
}
const struct ustctl_basic_type *elem_type;
const struct ustctl_basic_type *length_type;
- elem_type = &field->type.u.sequence.elem_type;
- length_type = &field->type.u.sequence.length_type;
+ elem_type = &field->type.u.legacy.sequence.elem_type;
+ length_type = &field->type.u.legacy.sequence.length_type;
ret = print_tabs(session, nesting);
if (ret) {
goto end;
}
+
+ /* Only integers are currently supported in sequences. */
+ if (elem_type->atype != ustctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+
ret = lttng_metadata_printf(session,
"integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } __%s_length;\n",
length_type->u.basic.integer.size,
(*iter_field)++;
break;
}
+ case ustctl_atype_sequence_nestable:
+ {
+ const struct ustctl_field *sequence_nestable;
+ const struct ustctl_type *elem_type;
+
+ (*iter_field)++;
+ if (*iter_field >= nr_fields) {
+ ret = -EOVERFLOW;
+ goto end;
+ }
+ sequence_nestable = &fields[*iter_field];
+ elem_type = &sequence_nestable->type;
+
+ /* Only integers are currently supported in sequences. */
+ if (elem_type->atype != ustctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+
+ if (field->type.u.sequence_nestable.alignment) {
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "struct { } align(%u) _%s_padding;\n",
+ field->type.u.sequence_nestable.alignment * CHAR_BIT,
+ field->name);
+ if (ret) {
+ goto end;
+ }
+ }
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ ret = lttng_metadata_printf(session,
+ "integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u;%s } _%s[ _%s ];\n",
+ elem_type->u.integer.size,
+ (unsigned int) elem_type->u.integer.alignment,
+ elem_type->u.integer.signedness,
+ (elem_type->u.integer.encoding == ustctl_encode_none)
+ ? "none"
+ : ((elem_type->u.integer.encoding == ustctl_encode_UTF8)
+ ? "UTF8"
+ : "ASCII"),
+ elem_type->u.integer.base,
+ elem_type->u.integer.reverse_byte_order ? bo_reverse : bo_native,
+ field->name,
+ field->type.u.sequence_nestable.length_name);
+ (*iter_field)++;
+ break;
+ }
case ustctl_atype_string:
/* Default encoding is UTF8 */
ret = print_tabs(session, nesting);
}
ret = lttng_metadata_printf(session,
"string%s _%s;\n",
- field->type.u.basic.string.encoding == ustctl_encode_ASCII ?
+ field->type.u.string.encoding == ustctl_encode_ASCII ?
" { encoding = ASCII; }" : "",
field->name);
(*iter_field)++;
break;
case ustctl_atype_variant:
- ret = _lttng_variant_statedump(session, fields, nr_fields, iter_field, nesting);
+ ret = _lttng_variant_statedump(session,
+ field->type.u.legacy.variant.nr_choices,
+ field->type.u.legacy.variant.tag_name,
+ 0,
+ fields, nr_fields, iter_field, nesting);
+ if (ret) {
+ goto end;
+ }
+ break;
+ case ustctl_atype_variant_nestable:
+ ret = _lttng_variant_statedump(session,
+ field->type.u.variant_nestable.nr_choices,
+ field->type.u.variant_nestable.tag_name,
+ field->type.u.variant_nestable.alignment,
+ fields, nr_fields, iter_field, nesting);
if (ret) {
goto end;
}
break;
case ustctl_atype_struct:
+ if (field->type.u.legacy._struct.nr_fields != 0) {
+ /* Currently only 0-length structures are supported. */
+ ret = -EINVAL;
+ goto end;
+ }
ret = print_tabs(session, nesting);
if (ret) {
goto end;
field->name);
(*iter_field)++;
break;
+ case ustctl_atype_struct_nestable:
+ if (field->type.u.struct_nestable.nr_fields != 0) {
+ /* Currently only 0-length structures are supported. */
+ ret = -EINVAL;
+ goto end;
+ }
+ ret = print_tabs(session, nesting);
+ if (ret) {
+ goto end;
+ }
+ if (field->type.u.struct_nestable.alignment) {
+ ret = lttng_metadata_printf(session,
+ "struct {} align(%u) _%s;\n",
+ field->type.u.struct_nestable.alignment * CHAR_BIT,
+ field->name);
+ if (ret) {
+ goto end;
+ }
+ } else {
+ ret = lttng_metadata_printf(session,
+ "struct {} _%s;\n",
+ field->name);
+ }
+ (*iter_field)++;
+ break;
+ case ustctl_atype_enum_nestable:
+ {
+ const struct ustctl_field *container_field;
+ const struct ustctl_type *container_type;
+
+ (*iter_field)++;
+ if (*iter_field >= nr_fields) {
+ ret = -EOVERFLOW;
+ goto end;
+ }
+ container_field = &fields[*iter_field];
+ container_type = &container_field->type;
+
+ /* Only integers are supported as container types. */
+ if (container_type->atype != ustctl_atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+ ret = ust_metadata_enum_statedump(session,
+ field->type.u.enum_nestable.name,
+ field->type.u.enum_nestable.id,
+ &container_type->u.integer,
+ field->name, iter_field, nesting);
+ break;
+ }
default:
ret = -EINVAL;
}
event->name,
event->id,
chan->chan_id);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = lttng_metadata_printf(session,
" loglevel = %d;\n",
event->loglevel_value);
- if (ret)
+ if (ret) {
goto end;
+ }
if (event->model_emf_uri) {
ret = lttng_metadata_printf(session,
" model.emf.uri = \"%s\";\n",
event->model_emf_uri);
- if (ret)
+ if (ret) {
goto end;
+ }
}
ret = lttng_metadata_printf(session,
" fields := struct {\n"
);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = _lttng_fields_metadata_statedump(session, event);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = lttng_metadata_printf(session,
" };\n"
"};\n\n");
- if (ret)
+ if (ret) {
goto end;
+ }
event->metadata_dumped = 1;
end:
chan->header_type == USTCTL_CHANNEL_HEADER_COMPACT ?
"struct event_header_compact" :
"struct event_header_large");
- if (ret)
+ if (ret) {
goto end;
+ }
if (chan->ctx_fields) {
ret = lttng_metadata_printf(session,
" event.context := struct {\n");
- if (ret)
+ if (ret) {
goto end;
+ }
}
ret = _lttng_context_metadata_statedump(session,
chan->nr_ctx_fields,
chan->ctx_fields);
- if (ret)
+ if (ret) {
goto end;
+ }
if (chan->ctx_fields) {
ret = lttng_metadata_printf(session,
" };\n");
- if (ret)
+ if (ret) {
goto end;
+ }
}
ret = lttng_metadata_printf(session,
uuid_s,
session->byte_order == BIG_ENDIAN ? "be" : "le"
);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = lttng_metadata_printf(session,
"env {\n"
ret = lttng_metadata_printf(session,
"};\n\n"
);
- if (ret)
+ if (ret) {
goto end;
-
+ }
ret = lttng_metadata_printf(session,
"clock {\n"
" name = \"%s\";\n",
trace_clock_name()
);
- if (ret)
+ if (ret) {
goto end;
+ }
if (!trace_clock_uuid(clock_uuid_s)) {
ret = lttng_metadata_printf(session,
" uuid = \"%s\";\n",
clock_uuid_s
);
- if (ret)
+ if (ret) {
goto end;
+ }
}
ret = lttng_metadata_printf(session,
trace_clock_freq(),
measure_clock_offset()
);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = lttng_metadata_printf(session,
"typealias integer {\n"
session->uint64_t_alignment,
trace_clock_name()
);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = _lttng_stream_packet_context_declare(session);
- if (ret)
+ if (ret) {
goto end;
+ }
ret = _lttng_event_header_declare(session);
- if (ret)
+ if (ret) {
goto end;
+ }
end:
return ret;