Refactor enumeration, sequence, array, structure, and variant types.
Implement internal data structures to support nested types.
All probe providers using ctf_enum(), ctf_array*() and ctf_sequence*()
are switched to this new binary layout, and the prior enum, array and
sequence abstract types are kept only for backward compatibility with
probe providers generated by older lttng-ust headers.
Each of sequence, array, struct and variant gain a "alignment" property,
which is a feature which was needed in lttng-modules to express
alignment for an array or sequence of bits.
The ust-ctl protocol with session daemon is extended to support those
new types.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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;
/* Update the astract_types name table in lttng-types.c along with this enum */
enum lttng_abstract_types {
atype_integer,
- atype_enum,
- atype_array,
- atype_sequence,
+ atype_enum, /* legacy */
+ atype_array, /* legacy */
+ atype_sequence, /* legacy */
atype_string,
atype_float,
atype_dynamic,
- atype_struct,
+ atype_struct, /* legacy */
+ atype_enum_nestable,
+ atype_array_nestable,
+ atype_sequence_nestable,
+ atype_struct_nestable,
NR_ABSTRACT_TYPES,
};
.atype = atype_integer, \
.u = \
{ \
- .basic = \
+ .integer = \
{ \
- .integer = \
- { \
- .size = sizeof(_type) * CHAR_BIT, \
- .alignment = lttng_alignof(_type) * CHAR_BIT, \
- .signedness = lttng_is_signed_type(_type), \
- .reverse_byte_order = _byte_order != BYTE_ORDER, \
- .base = _base, \
- .encoding = lttng_encode_##_encoding, \
- } \
+ .size = sizeof(_type) * CHAR_BIT, \
+ .alignment = lttng_alignof(_type) * CHAR_BIT, \
+ .signedness = lttng_is_signed_type(_type), \
+ .reverse_byte_order = _byte_order != BYTE_ORDER, \
+ .base = _base, \
+ .encoding = lttng_encode_##_encoding, \
} \
}, \
} \
.atype = atype_float, \
.u = \
{ \
- .basic = \
+ ._float = \
{ \
- ._float = \
- { \
- .exp_dig = sizeof(_type) * CHAR_BIT \
- - _float_mant_dig(_type), \
- .mant_dig = _float_mant_dig(_type), \
- .alignment = lttng_alignof(_type) * CHAR_BIT, \
- .reverse_byte_order = BYTE_ORDER != FLOAT_WORD_ORDER, \
- } \
+ .exp_dig = sizeof(_type) * CHAR_BIT \
+ - _float_mant_dig(_type), \
+ .mant_dig = _float_mant_dig(_type), \
+ .alignment = lttng_alignof(_type) * CHAR_BIT, \
+ .reverse_byte_order = BYTE_ORDER != FLOAT_WORD_ORDER, \
} \
- }, \
+ } \
} \
#define LTTNG_UST_FLOAT_TYPE_PADDING 24
char padding[LTTNG_UST_FLOAT_TYPE_PADDING];
};
+/* legacy */
#define LTTNG_UST_BASIC_TYPE_PADDING 128
union _lttng_basic_type {
- struct lttng_integer_type integer;
+ struct lttng_integer_type integer; /* legacy */
struct {
const struct lttng_enum_desc *desc; /* Enumeration mapping */
struct lttng_integer_type container_type;
- } enumeration;
+ } enumeration; /* legacy */
struct {
enum lttng_string_encodings encoding;
- } string;
- struct lttng_float_type _float;
+ } string; /* legacy */
+ struct lttng_float_type _float; /* legacy */
char padding[LTTNG_UST_BASIC_TYPE_PADDING];
};
+/* legacy */
struct lttng_basic_type {
enum lttng_abstract_types atype;
union {
struct lttng_type {
enum lttng_abstract_types atype;
union {
- union _lttng_basic_type basic;
+ /* provider ABI 2.0 */
+ struct lttng_integer_type integer;
+ struct lttng_float_type _float;
+ struct {
+ enum lttng_string_encodings encoding;
+ } string;
+ struct {
+ const struct lttng_enum_desc *desc; /* Enumeration mapping */
+ struct lttng_type *container_type;
+ } enum_nestable;
struct {
- struct lttng_basic_type elem_type;
- unsigned int length; /* num. elems. */
- } array;
+ const struct lttng_type *elem_type;
+ unsigned int length; /* Num. elems. */
+ unsigned int alignment;
+ } array_nestable;
struct {
- struct lttng_basic_type length_type;
- struct lttng_basic_type elem_type;
- } sequence;
+ const char *length_name; /* Length field name. */
+ const struct lttng_type *elem_type;
+ unsigned int alignment; /* Alignment before elements. */
+ } sequence_nestable;
struct {
- uint32_t nr_fields;
- struct lttng_event_field *fields; /* Array of fields. */
- } _struct;
+ unsigned int nr_fields;
+ const struct lttng_event_field *fields; /* Array of fields. */
+ unsigned int alignment;
+ } struct_nestable;
+
+ union {
+ /* legacy provider ABI 1.0 */
+ union _lttng_basic_type basic; /* legacy */
+ struct {
+ struct lttng_basic_type elem_type;
+ unsigned int length; /* Num. elems. */
+ } array; /* legacy */
+ struct {
+ struct lttng_basic_type length_type;
+ struct lttng_basic_type elem_type;
+ } sequence; /* legacy */
+ struct {
+ unsigned int nr_fields;
+ struct lttng_event_field *fields; /* Array of fields. */
+ } _struct; /* legacy */
+ } legacy;
char padding[LTTNG_UST_TYPE_PADDING];
} u;
};
const char *name;
struct lttng_type type;
unsigned int nowrite; /* do not write into trace */
- char padding[LTTNG_UST_EVENT_FIELD_PADDING];
+ union {
+ struct {
+ unsigned int nofilter:1; /* do not consider for filter */
+ } ext;
+ char padding[LTTNG_UST_EVENT_FIELD_PADDING];
+ } u;
};
enum lttng_ust_dynamic_type {
.name = #_item, \
.type = __type_integer(_type, _byte_order, _base, none),\
.nowrite = _nowrite, \
+ .u = { \
+ .ext = { \
+ .nofilter = 0, \
+ }, \
+ }, \
},
#undef _ctf_float
.name = #_item, \
.type = __type_float(_type), \
.nowrite = _nowrite, \
+ .u = { \
+ .ext = { \
+ .nofilter = 0, \
+ }, \
+ }, \
},
#undef _ctf_array_encoded
.name = #_item, \
.type = \
{ \
- .atype = atype_array, \
+ .atype = atype_array_nestable, \
.u = \
{ \
- .array = \
+ .array_nestable = \
{ \
- .elem_type = __type_integer(_type, _byte_order, _elem_type_base, _encoding), \
+ .elem_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \
+ __type_integer(_type, _byte_order, _elem_type_base, _encoding)), \
.length = _length, \
+ .alignment = 0, \
} \
} \
}, \
.nowrite = _nowrite, \
+ .u = { \
+ .ext = { \
+ .nofilter = 0, \
+ }, \
+ }, \
},
#undef _ctf_sequence_encoded
#define _ctf_sequence_encoded(_type, _item, _src, _byte_order, \
_length_type, _src_length, _encoding, _nowrite, \
_elem_type_base) \
+ { \
+ .name = "_" #_item "_length", \
+ .type = __type_integer(_length_type, BYTE_ORDER, 10, none), \
+ .nowrite = _nowrite, \
+ .u = { \
+ .ext = { \
+ .nofilter = 1, \
+ }, \
+ }, \
+ }, \
{ \
.name = #_item, \
.type = \
{ \
- .atype = atype_sequence, \
+ .atype = atype_sequence_nestable, \
.u = \
{ \
- .sequence = \
+ .sequence_nestable = \
{ \
- .length_type = __type_integer(_length_type, BYTE_ORDER, 10, none), \
- .elem_type = __type_integer(_type, _byte_order, _elem_type_base, _encoding), \
+ .length_name = "_" #_item "_length", \
+ .elem_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \
+ __type_integer(_type, _byte_order, _elem_type_base, _encoding)), \
+ .alignment = 0, \
}, \
}, \
}, \
.nowrite = _nowrite, \
+ .u = { \
+ .ext = { \
+ .nofilter = 0, \
+ }, \
+ }, \
},
#undef _ctf_string
.atype = atype_string, \
.u = \
{ \
- .basic = { .string = { .encoding = lttng_encode_UTF8 } } \
+ .string = { .encoding = lttng_encode_UTF8 } \
}, \
}, \
.nowrite = _nowrite, \
+ .u = { \
+ .ext = { \
+ .nofilter = 0, \
+ }, \
+ }, \
},
#undef _ctf_enum
{ \
.name = #_item, \
.type = { \
- .atype = atype_enum, \
+ .atype = atype_enum_nestable, \
.u = { \
- .basic = { \
- .enumeration = { \
- .desc = &__enum_##_provider##_##_name, \
- .container_type = { \
- .size = sizeof(_type) * CHAR_BIT, \
- .alignment = lttng_alignof(_type) * CHAR_BIT, \
- .signedness = lttng_is_signed_type(_type), \
- .reverse_byte_order = 0, \
- .base = 10, \
- .encoding = lttng_encode_none, \
- }, \
- }, \
- }, \
+ .enum_nestable = { \
+ .desc = &__enum_##_provider##_##_name, \
+ .container_type = __LTTNG_COMPOUND_LITERAL(struct lttng_type, \
+ __type_integer(_type, BYTE_ORDER, 10, none)), \
+ }, \
}, \
}, \
.nowrite = _nowrite, \
+ .u = { \
+ .ext = { \
+ .nofilter = 0, \
+ }, \
+ }, \
},
#undef TP_FIELDS
int serialize_one_field(struct lttng_session *session,
struct ustctl_field *fields, size_t *iter_output,
const struct lttng_event_field *lf);
+static
+int serialize_fields(struct lttng_session *session,
+ struct ustctl_field *ustctl_fields,
+ size_t *iter_output, size_t nr_lttng_fields,
+ const struct lttng_event_field *lttng_fields);
/*
* Human readable error message.
case atype_sequence:
return 1;
case atype_struct:
- //TODO: implement non-empty struct.
- return 1;
+ return count_fields_recursive(lt->u.legacy._struct.nr_fields,
+ lt->u.legacy._struct.fields);
+ case atype_enum_nestable:
+ return count_one_type(lt->u.enum_nestable.container_type) + 1;
+ case atype_array_nestable:
+ return count_one_type(lt->u.array_nestable.elem_type) + 1;
+ case atype_sequence_nestable:
+ return count_one_type(lt->u.sequence_nestable.elem_type) + 1;
+ case atype_struct_nestable:
+ return count_fields_recursive(lt->u.struct_nestable.nr_fields,
+ lt->u.struct_nestable.fields);
+
case atype_dynamic:
{
const struct lttng_event_field *choices;
*/
return count_fields_recursive(nr_choices, choices) + 2;
}
+
default:
return -EINVAL;
}
break;
}
case atype_array:
+ case atype_array_nestable:
case atype_sequence:
+ case atype_sequence_nestable:
+ case atype_enum_nestable:
default:
return -EINVAL;
}
static
int serialize_dynamic_type(struct lttng_session *session,
struct ustctl_field *fields, size_t *iter_output,
- const struct lttng_event_field *lf)
+ const char *field_name)
{
const struct lttng_event_field *choices;
char tag_field_name[LTTNG_UST_SYM_NAME_LEN];
tag_type = &tag_field_generic->type;
/* Serialize enum field. */
- strncpy(tag_field_name, lf->name, LTTNG_UST_SYM_NAME_LEN);
+ strncpy(tag_field_name, field_name, LTTNG_UST_SYM_NAME_LEN);
tag_field_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
strncat(tag_field_name,
"_tag",
if (ret)
return ret;
- strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
+ strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
uf->type.atype = ustctl_atype_variant;
- uf->type.u.variant.nr_choices = nr_choices;
- strncpy(uf->type.u.variant.tag_name,
+ uf->type.u.variant_nestable.nr_choices = nr_choices;
+ strncpy(uf->type.u.variant_nestable.tag_name,
tag_field_name,
LTTNG_UST_SYM_NAME_LEN);
- uf->type.u.variant.tag_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ uf->type.u.variant_nestable.tag_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ uf->type.u.variant_nestable.alignment = 0;
(*iter_output)++;
/* Serialize choice fields after variant. */
}
static
-int serialize_one_field(struct lttng_session *session,
+int serialize_one_type(struct lttng_session *session,
struct ustctl_field *fields, size_t *iter_output,
- const struct lttng_event_field *lf)
+ const char *field_name, const struct lttng_type *lt)
{
- const struct lttng_type *lt = &lf->type;
int ret;
- /* skip 'nowrite' fields */
- if (lf->nowrite)
- return 0;
+ /*
+ * Serializing a type (rather than a field) generates a ustctl_field
+ * entry with 0-length name.
+ */
switch (lt->atype) {
case atype_integer:
struct ustctl_type *ut = &uf->type;
enum ustctl_abstract_types atype;
- strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
- uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ if (field_name) {
+ strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
+ uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ } else {
+ uf->name[0] = '\0';
+ }
ret = serialize_basic_type(session, &atype, lt->atype,
- &ut->u.basic, <->u.basic);
+ &ut->u.legacy.basic, <->u.legacy.basic);
if (ret)
return ret;
ut->atype = atype;
const struct lttng_basic_type *lbt;
enum ustctl_abstract_types atype;
- strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
- uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
- uf->type.atype = ustctl_atype_array;
- ubt = &ut->u.array.elem_type;
- lbt = <->u.array.elem_type;
- ut->u.array.length = lt->u.array.length;
+ if (field_name) {
+ strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
+ uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ } else {
+ uf->name[0] = '\0';
+ }
+ ut->atype = ustctl_atype_array;
+ ubt = &ut->u.legacy.array.elem_type;
+ lbt = <->u.legacy.array.elem_type;
+ ut->u.legacy.array.length = lt->u.legacy.array.length;
ret = serialize_basic_type(session, &atype, lbt->atype,
&ubt->u.basic, &lbt->u.basic);
if (ret)
return -EINVAL;
ubt->atype = atype;
- ut->atype = ustctl_atype_array;
(*iter_output)++;
break;
}
+ case atype_array_nestable:
+ {
+ struct ustctl_field *uf = &fields[*iter_output];
+ struct ustctl_type *ut = &uf->type;
+
+ if (field_name) {
+ strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
+ uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ } else {
+ uf->name[0] = '\0';
+ }
+ ut->atype = ustctl_atype_array_nestable;
+ ut->u.array_nestable.length = lt->u.array_nestable.length;
+ ut->u.array_nestable.alignment = lt->u.array_nestable.alignment;
+ (*iter_output)++;
+
+ ret = serialize_one_type(session, fields, iter_output, NULL,
+ lt->u.array_nestable.elem_type);
+ if (ret)
+ return -EINVAL;
+ break;
+ }
case atype_sequence:
{
struct ustctl_field *uf = &fields[*iter_output];
struct ustctl_basic_type *ubt;
const struct lttng_basic_type *lbt;
enum ustctl_abstract_types atype;
- int ret;
- strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
- uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ if (field_name) {
+ strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
+ uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ } else {
+ uf->name[0] = '\0';
+ }
uf->type.atype = ustctl_atype_sequence;
- ubt = &ut->u.sequence.length_type;
- lbt = <->u.sequence.length_type;
+ ubt = &ut->u.legacy.sequence.length_type;
+ lbt = <->u.legacy.sequence.length_type;
ret = serialize_basic_type(session, &atype, lbt->atype,
&ubt->u.basic, &lbt->u.basic);
if (ret)
return -EINVAL;
ubt->atype = atype;
- ubt = &ut->u.sequence.elem_type;
- lbt = <->u.sequence.elem_type;
+ ubt = &ut->u.legacy.sequence.elem_type;
+ lbt = <->u.legacy.sequence.elem_type;
ret = serialize_basic_type(session, &atype, lbt->atype,
&ubt->u.basic, &lbt->u.basic);
if (ret)
return -EINVAL;
ubt->atype = atype;
- ut->atype = ustctl_atype_sequence;
(*iter_output)++;
break;
}
+ case atype_sequence_nestable:
+ {
+ struct ustctl_field *uf = &fields[*iter_output];
+ struct ustctl_type *ut = &uf->type;
+
+ if (field_name) {
+ strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
+ uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ } else {
+ uf->name[0] = '\0';
+ }
+ ut->atype = ustctl_atype_sequence_nestable;
+ strncpy(ut->u.sequence_nestable.length_name,
+ lt->u.sequence_nestable.length_name,
+ LTTNG_UST_SYM_NAME_LEN);
+ ut->u.sequence_nestable.length_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ ut->u.sequence_nestable.alignment = lt->u.sequence_nestable.alignment;
+ (*iter_output)++;
+
+ ret = serialize_one_type(session, fields, iter_output, NULL,
+ lt->u.sequence_nestable.elem_type);
+ if (ret)
+ return -EINVAL;
+ break;
+ }
case atype_dynamic:
{
- ret = serialize_dynamic_type(session, fields, iter_output, lf);
+ ret = serialize_dynamic_type(session, fields, iter_output,
+ field_name);
if (ret)
return -EINVAL;
break;
{
struct ustctl_field *uf = &fields[*iter_output];
- /*
- * TODO: add support for non-empty struct.
- */
- if (lf->type.u._struct.nr_fields != 0) {
- return -EINVAL;
+ if (field_name) {
+ strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
+ uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ } else {
+ uf->name[0] = '\0';
}
- strncpy(uf->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
- uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
uf->type.atype = ustctl_atype_struct;
- uf->type.u._struct.nr_fields = 0;
+ uf->type.u.legacy._struct.nr_fields = lt->u.legacy._struct.nr_fields;
(*iter_output)++;
+
+ ret = serialize_fields(session, fields, iter_output,
+ lt->u.legacy._struct.nr_fields,
+ lt->u.legacy._struct.fields);
+ if (ret)
+ return -EINVAL;
+ break;
+ }
+ case atype_struct_nestable:
+ {
+ struct ustctl_field *uf = &fields[*iter_output];
+
+ if (field_name) {
+ strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
+ uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ } else {
+ uf->name[0] = '\0';
+ }
+ uf->type.atype = ustctl_atype_struct_nestable;
+ uf->type.u.struct_nestable.nr_fields = lt->u.struct_nestable.nr_fields;
+ uf->type.u.struct_nestable.alignment = lt->u.struct_nestable.alignment;
+ (*iter_output)++;
+
+ ret = serialize_fields(session, fields, iter_output,
+ lt->u.struct_nestable.nr_fields,
+ lt->u.struct_nestable.fields);
+ if (ret)
+ return -EINVAL;
+ break;
+ }
+ case atype_enum_nestable:
+ {
+ struct ustctl_field *uf = &fields[*iter_output];
+ struct ustctl_type *ut = &uf->type;
+
+ if (field_name) {
+ strncpy(uf->name, field_name, LTTNG_UST_SYM_NAME_LEN);
+ uf->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ } else {
+ uf->name[0] = '\0';
+ }
+ strncpy(ut->u.enum_nestable.name, lt->u.enum_nestable.desc->name,
+ LTTNG_UST_SYM_NAME_LEN);
+ ut->u.enum_nestable.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ ut->atype = ustctl_atype_enum_nestable;
+ (*iter_output)++;
+
+ ret = serialize_one_type(session, fields, iter_output, NULL,
+ lt->u.enum_nestable.container_type);
+ if (ret)
+ return -EINVAL;
+ if (session) {
+ const struct lttng_enum *_enum;
+
+ _enum = lttng_ust_enum_get_from_desc(session, lt->u.enum_nestable.desc);
+ if (!_enum)
+ return -EINVAL;
+ ut->u.enum_nestable.id = _enum->id;
+ } else {
+ ut->u.enum_nestable.id = -1ULL;
+ }
break;
}
default:
return 0;
}
+static
+int serialize_one_field(struct lttng_session *session,
+ struct ustctl_field *fields, size_t *iter_output,
+ const struct lttng_event_field *lf)
+{
+ /* skip 'nowrite' fields */
+ if (lf->nowrite)
+ return 0;
+
+ return serialize_one_type(session, fields, iter_output, lf->name, &lf->type);
+}
+
static
int serialize_fields(struct lttng_session *session,
+ struct ustctl_field *ustctl_fields,
+ size_t *iter_output, size_t nr_lttng_fields,
+ const struct lttng_event_field *lttng_fields)
+{
+ int ret;
+ size_t i;
+
+ for (i = 0; i < nr_lttng_fields; i++) {
+ ret = serialize_one_field(session, ustctl_fields,
+ iter_output, <tng_fields[i]);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static
+int alloc_serialize_fields(struct lttng_session *session,
size_t *_nr_write_fields,
struct ustctl_field **ustctl_fields,
size_t nr_fields,
{
struct ustctl_field *fields;
int ret;
- size_t i, iter_output = 0;
+ size_t iter_output = 0;
ssize_t nr_write_fields;
nr_write_fields = count_fields_recursive(nr_fields, lttng_fields);
if (!fields)
return -ENOMEM;
- for (i = 0; i < nr_fields; i++) {
- ret = serialize_one_field(session, fields, &iter_output,
- <tng_fields[i]);
- if (ret)
- goto error_type;
- }
+ ret = serialize_fields(session, fields, &iter_output, nr_fields,
+ lttng_fields);
+ if (ret)
+ goto error_type;
*_nr_write_fields = nr_write_fields;
*ustctl_fields = fields;
/* Calculate fields len, serialize fields. */
if (nr_fields > 0) {
- ret = serialize_fields(session, &nr_write_fields, &fields,
+ ret = alloc_serialize_fields(session, &nr_write_fields, &fields,
nr_fields, lttng_fields);
if (ret)
return ret;
}
field->event_field.name = "cgroup_ns";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = cgroup_ns_get_size;
field->record = cgroup_ns_record;
field->get_value = cgroup_ns_get_value;
}
field->event_field.name = "cpu_id";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(int) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(int) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(int);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(int) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(int) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(int);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = cpu_id_get_size;
field->record = cpu_id_record;
field->get_value = cpu_id_get_value;
}
field->event_field.name = "ip";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(void *) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(void *) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(void *);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 16;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(void *) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(void *) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(void *);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 16;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = ip_get_size;
field->record = ip_record;
lttng_context_update(*ctx);
}
field->event_field.name = "ipc_ns";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = ipc_ns_get_size;
field->record = ipc_ns_record;
field->get_value = ipc_ns_get_value;
}
field->event_field.name = "mnt_ns";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = mnt_ns_get_size;
field->record = mnt_ns_record;
field->get_value = mnt_ns_get_value;
}
field->event_field.name = "net_ns";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = net_ns_get_size;
field->record = net_ns_record;
field->get_value = net_ns_get_value;
field->event_field.name = name_alloc;
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size =
+ field->event_field.type.u.integer.size =
sizeof(uint64_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment =
+ field->event_field.type.u.integer.alignment =
lttng_alignof(uint64_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness =
+ field->event_field.type.u.integer.signedness =
lttng_is_signed_type(uint64_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = perf_counter_get_size;
field->record = perf_counter_record;
field->get_value = perf_counter_get_value;
}
field->event_field.name = "pid_ns";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = pid_ns_get_size;
field->record = pid_ns_record;
field->get_value = pid_ns_get_value;
value->u.str = wrapper_getprocname();
}
+static const struct lttng_type procname_array_elem_type =
+ __type_integer(char, BYTE_ORDER, 10, UTF8);
+
int lttng_add_procname_to_ctx(struct lttng_ctx **ctx)
{
struct lttng_ctx_field *field;
return -EEXIST;
}
field->event_field.name = "procname";
- field->event_field.type.atype = atype_array;
- field->event_field.type.u.array.elem_type.atype = atype_integer;
- field->event_field.type.u.array.elem_type.u.basic.integer.size = sizeof(char) * CHAR_BIT;
- field->event_field.type.u.array.elem_type.u.basic.integer.alignment = lttng_alignof(char) * CHAR_BIT;
- field->event_field.type.u.array.elem_type.u.basic.integer.signedness = lttng_is_signed_type(char);
- field->event_field.type.u.array.elem_type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.array.elem_type.u.basic.integer.base = 10;
- field->event_field.type.u.array.elem_type.u.basic.integer.encoding = lttng_encode_UTF8;
- field->event_field.type.u.array.length = LTTNG_UST_PROCNAME_LEN;
+ field->event_field.type.atype = atype_array_nestable;
+ field->event_field.type.u.array_nestable.elem_type =
+ &procname_array_elem_type;
+ field->event_field.type.u.array_nestable.length = LTTNG_UST_PROCNAME_LEN;
field->get_size = procname_get_size;
field->record = procname_record;
field->get_value = procname_get_value;
}
field->event_field.name = "pthread_id";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(unsigned long) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned long);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(unsigned long) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(unsigned long);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = pthread_id_get_size;
field->record = pthread_id_record;
field->get_value = pthread_id_get_value;
}
field->event_field.name = "user_ns";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = user_ns_get_size;
field->record = user_ns_record;
field->get_value = user_ns_get_value;
}
field->event_field.name = "uts_ns";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(ino_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = uts_ns_get_size;
field->record = uts_ns_record;
field->get_value = uts_ns_get_value;
}
field->event_field.name = "vegid";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(gid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(gid_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(gid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(gid_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = vegid_get_size;
field->record = vegid_record;
field->get_value = vegid_get_value;
}
field->event_field.name = "veuid";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(uid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uid_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(uid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(uid_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = veuid_get_size;
field->record = veuid_record;
field->get_value = veuid_get_value;
}
field->event_field.name = "vgid";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(gid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(gid_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(gid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(gid_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = vgid_get_size;
field->record = vgid_record;
field->get_value = vgid_get_value;
}
field->event_field.name = "vpid";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(pid_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(pid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(pid_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = vpid_get_size;
field->record = vpid_record;
field->get_value = vpid_get_value;
}
field->event_field.name = "vsgid";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(gid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(gid_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(gid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(gid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(gid_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = vsgid_get_size;
field->record = vsgid_record;
field->get_value = vsgid_get_value;
}
field->event_field.name = "vsuid";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(uid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uid_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(uid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(uid_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = vsuid_get_size;
field->record = vsuid_record;
field->get_value = vsuid_get_value;
}
field->event_field.name = "vtid";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(pid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(pid_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(pid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(pid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(pid_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = vtid_get_size;
field->record = vtid_record;
field->get_value = vtid_get_value;
}
field->event_field.name = "vuid";
field->event_field.type.atype = atype_integer;
- field->event_field.type.u.basic.integer.size = sizeof(uid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT;
- field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(uid_t);
- field->event_field.type.u.basic.integer.reverse_byte_order = 0;
- field->event_field.type.u.basic.integer.base = 10;
- field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+ field->event_field.type.u.integer.size = sizeof(uid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.alignment = lttng_alignof(uid_t) * CHAR_BIT;
+ field->event_field.type.u.integer.signedness = lttng_is_signed_type(uid_t);
+ field->event_field.type.u.integer.reverse_byte_order = 0;
+ field->event_field.type.u.integer.base = 10;
+ field->event_field.type.u.integer.encoding = lttng_encode_none;
field->get_size = vuid_get_size;
field->record = vuid_record;
field->get_value = vuid_get_value;
type = &ctx->fields[i].event_field.type;
switch (type->atype) {
case atype_integer:
- field_align = type->u.basic.integer.alignment;
+ field_align = type->u.integer.alignment;
break;
case atype_array:
{
struct lttng_basic_type *btype;
- btype = &type->u.array.elem_type;
+ btype = &type->u.legacy.array.elem_type;
switch (btype->atype) {
case atype_integer:
field_align = btype->u.basic.integer.alignment;
break;
case atype_array:
+ case atype_array_nestable:
case atype_sequence:
+ case atype_sequence_nestable:
default:
WARN_ON_ONCE(1);
break;
}
break;
}
+ case atype_array_nestable:
+ {
+ const struct lttng_type *nested_type;
+
+ nested_type = type->u.array_nestable.elem_type;
+ switch (nested_type->atype) {
+ case atype_integer:
+ field_align = nested_type->u.integer.alignment;
+ break;
+ case atype_string:
+ break;
+
+ case atype_array:
+ case atype_array_nestable:
+ case atype_sequence:
+ case atype_sequence_nestable:
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+ field_align = max_t(size_t, field_align,
+ type->u.array_nestable.alignment);
+ break;
+ }
case atype_sequence:
{
struct lttng_basic_type *btype;
- btype = &type->u.sequence.length_type;
+ btype = &type->u.legacy.sequence.length_type;
switch (btype->atype) {
case atype_integer:
field_align = btype->u.basic.integer.alignment;
case atype_string:
case atype_array:
+ case atype_array_nestable:
case atype_sequence:
+ case atype_sequence_nestable:
default:
WARN_ON_ONCE(1);
break;
}
- btype = &type->u.sequence.elem_type;
+ btype = &type->u.legacy.sequence.elem_type;
switch (btype->atype) {
case atype_integer:
field_align = max_t(size_t,
break;
case atype_array:
+ case atype_array_nestable:
+ case atype_sequence:
+ case atype_sequence_nestable:
+ default:
+ WARN_ON_ONCE(1);
+ break;
+ }
+ break;
+ }
+ case atype_sequence_nestable:
+ {
+ const struct lttng_type *nested_type;
+
+ nested_type = type->u.sequence_nestable.elem_type;
+ switch (nested_type->atype) {
+ case atype_integer:
+ field_align = nested_type->u.integer.alignment;
+ break;
+
+ case atype_string:
+ break;
+
+ case atype_array:
+ case atype_array_nestable:
case atype_sequence:
+ case atype_sequence_nestable:
default:
WARN_ON_ONCE(1);
break;
}
+ field_align = max_t(size_t, field_align,
+ type->u.sequence_nestable.alignment);
break;
}
case atype_string:
case atype_dynamic:
break;
case atype_enum:
+ case atype_enum_nestable:
default:
WARN_ON_ONCE(1);
break;
const struct lttng_enum_desc *enum_desc;
int ret;
- enum_desc = type->u.basic.enumeration.desc;
+ enum_desc = type->u.legacy.basic.enumeration.desc;
+ ret = lttng_enum_create(enum_desc, session);
+ if (ret && ret != -EEXIST) {
+ DBG("Unable to create enum error: (%d)", ret);
+ return ret;
+ }
+ break;
+ }
+ case atype_enum_nestable:
+ {
+ const struct lttng_enum_desc *enum_desc;
+ int ret;
+
+ enum_desc = type->u.enum_nestable.desc;
ret = lttng_enum_create(enum_desc, session);
if (ret && ret != -EEXIST) {
DBG("Unable to create enum error: (%d)", ret);
int ret;
tag_field_generic = lttng_ust_dynamic_type_tag_field();
- enum_desc = tag_field_generic->type.u.basic.enumeration.desc;
+ enum_desc = tag_field_generic->type.u.enum_nestable.desc;
ret = lttng_enum_create(enum_desc, session);
if (ret && ret != -EEXIST) {
DBG("Unable to create enum error: (%d)", ret);
struct lttng_enum *curr_enum;
field = &(event->desc->fields[j]);
- if (field->type.atype != atype_enum) {
+ switch (field->type.atype) {
+ case atype_enum:
+ enum_desc = field->type.u.legacy.basic.enumeration.desc;
+ break;
+ case atype_enum_nestable:
+ enum_desc = field->type.u.enum_nestable.desc;
+ break;
+ default:
continue;
}
-
- enum_desc = field->type.u.basic.enumeration.desc;
curr_enum = lttng_ust_enum_get_from_desc(session, enum_desc);
if (curr_enum) {
_lttng_enum_destroy(curr_enum);
switch (field->type.atype) {
case atype_integer:
ctx_field->get_value(ctx_field, &v);
- if (field->type.u.basic.integer.signedness) {
+ if (field->type.u.integer.signedness) {
ptr->object_type = OBJECT_TYPE_S64;
ptr->u.s64 = v.u.s64;
ptr->ptr = &ptr->u.s64;
ptr->ptr = &ptr->u.u64;
}
break;
- case atype_enum:
+ case atype_enum: /* Fall-through */
+ case atype_enum_nestable:
{
- const struct lttng_integer_type *itype =
- &field->type.u.basic.enumeration.container_type;
+ const struct lttng_integer_type *itype;
+ if (field->type.atype == atype_enum) {
+ itype = &field->type.u.legacy.basic.enumeration.container_type;
+ } else {
+ itype = &field->type.u.enum_nestable.container_type->u.integer;
+ }
ctx_field->get_value(ctx_field, &v);
if (itype->signedness) {
ptr->object_type = OBJECT_TYPE_S64;
break;
}
case atype_array:
- if (field->type.u.array.elem_type.atype != atype_integer) {
+ if (field->type.u.legacy.array.elem_type.atype != atype_integer) {
+ ERR("Array nesting only supports integer types.");
+ return -EINVAL;
+ }
+ if (field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) {
+ ERR("Only string arrays are supported for contexts.");
+ return -EINVAL;
+ }
+ ptr->object_type = OBJECT_TYPE_STRING;
+ ctx_field->get_value(ctx_field, &v);
+ ptr->ptr = v.u.str;
+ break;
+ case atype_array_nestable:
+ if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
ERR("Array nesting only supports integer types.");
return -EINVAL;
}
- if (field->type.u.array.elem_type.u.basic.integer.encoding == lttng_encode_none) {
+ if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
ERR("Only string arrays are supported for contexts.");
return -EINVAL;
}
ptr->ptr = v.u.str;
break;
case atype_sequence:
- if (field->type.u.sequence.elem_type.atype != atype_integer) {
+ if (field->type.u.legacy.sequence.elem_type.atype != atype_integer) {
+ ERR("Sequence nesting only supports integer types.");
+ return -EINVAL;
+ }
+ if (field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) {
+ ERR("Only string sequences are supported for contexts.");
+ return -EINVAL;
+ }
+ ptr->object_type = OBJECT_TYPE_STRING;
+ ctx_field->get_value(ctx_field, &v);
+ ptr->ptr = v.u.str;
+ break;
+ case atype_sequence_nestable:
+ if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
ERR("Sequence nesting only supports integer types.");
return -EINVAL;
}
- if (field->type.u.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) {
+ if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
ERR("Only string sequences are supported for contexts.");
return -EINVAL;
}
switch (stack_top->load.object_type) {
case OBJECT_TYPE_ARRAY:
{
+ const struct lttng_integer_type *integer_type;
const struct lttng_event_field *field;
uint32_t elem_len, num_elems;
int signedness;
field = stack_top->load.field;
- elem_len = field->type.u.array.elem_type.u.basic.integer.size;
- signedness = field->type.u.array.elem_type.u.basic.integer.signedness;
- num_elems = field->type.u.array.length;
+ switch (field->type.atype) {
+ case atype_array:
+ integer_type = &field->type.u.legacy.array.elem_type.u.basic.integer;
+ num_elems = field->type.u.legacy.array.length;
+ break;
+ case atype_array_nestable:
+ if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+ integer_type = &field->type.u.array_nestable.elem_type->u.integer;
+ num_elems = field->type.u.array_nestable.length;
+ break;
+ default:
+ ret = -EINVAL;
+ goto end;
+ }
+ elem_len = integer_type->size;
+ signedness = integer_type->signedness;
if (index >= num_elems) {
ret = -EINVAL;
goto end;
gid.array_len = num_elems * (elem_len / CHAR_BIT);
gid.elem.type = stack_top->load.object_type;
gid.elem.len = elem_len;
- if (field->type.u.array.elem_type.u.basic.integer.reverse_byte_order)
+ if (integer_type->reverse_byte_order)
gid.elem.rev_bo = true;
stack_top->load.rev_bo = gid.elem.rev_bo;
break;
}
case OBJECT_TYPE_SEQUENCE:
{
+ const struct lttng_integer_type *integer_type;
const struct lttng_event_field *field;
uint32_t elem_len;
int signedness;
field = stack_top->load.field;
- elem_len = field->type.u.sequence.elem_type.u.basic.integer.size;
- signedness = field->type.u.sequence.elem_type.u.basic.integer.signedness;
+ switch (field->type.atype) {
+ case atype_sequence:
+ integer_type = &field->type.u.legacy.sequence.elem_type.u.basic.integer;
+ break;
+ case atype_sequence_nestable:
+ if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
+ ret = -EINVAL;
+ goto end;
+ }
+ integer_type = &field->type.u.sequence_nestable.elem_type->u.integer;
+ break;
+ default:
+ ret = -EINVAL;
+ goto end;
+ }
+ elem_len = integer_type->size;
+ signedness = integer_type->signedness;
ret = specialize_get_index_object_type(&stack_top->load.object_type,
signedness, elem_len);
if (ret)
gid.offset = index * (elem_len / CHAR_BIT);
gid.elem.type = stack_top->load.object_type;
gid.elem.len = elem_len;
- if (field->type.u.sequence.elem_type.u.basic.integer.reverse_byte_order)
+ if (integer_type->reverse_byte_order)
gid.elem.rev_bo = true;
stack_top->load.rev_bo = gid.elem.rev_bo;
break;
*/
switch (field->type.atype) {
case atype_integer:
- if (field->type.u.basic.integer.signedness)
+ if (field->type.u.integer.signedness)
load->object_type = OBJECT_TYPE_S64;
else
load->object_type = OBJECT_TYPE_U64;
load->rev_bo = false;
break;
case atype_enum:
+ case atype_enum_nestable:
{
- const struct lttng_integer_type *itype =
- &field->type.u.basic.enumeration.container_type;
+ const struct lttng_integer_type *itype;
+ if (field->type.atype == atype_enum) {
+ itype = &field->type.u.legacy.basic.enumeration.container_type;
+ } else {
+ itype = &field->type.u.enum_nestable.container_type->u.integer;
+ }
if (itype->signedness)
load->object_type = OBJECT_TYPE_S64;
else
break;
}
case atype_array:
- if (field->type.u.array.elem_type.atype != atype_integer) {
+ if (field->type.u.legacy.array.elem_type.atype != atype_integer) {
+ ERR("Array nesting only supports integer types.");
+ return -EINVAL;
+ }
+ if (is_context) {
+ load->object_type = OBJECT_TYPE_STRING;
+ } else {
+ if (field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none) {
+ load->object_type = OBJECT_TYPE_ARRAY;
+ load->field = field;
+ } else {
+ load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
+ }
+ }
+ break;
+ case atype_array_nestable:
+ if (field->type.u.array_nestable.elem_type->atype != atype_integer) {
ERR("Array nesting only supports integer types.");
return -EINVAL;
}
if (is_context) {
load->object_type = OBJECT_TYPE_STRING;
} else {
- if (field->type.u.array.elem_type.u.basic.integer.encoding == lttng_encode_none) {
+ if (field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
load->object_type = OBJECT_TYPE_ARRAY;
load->field = field;
} else {
}
break;
case atype_sequence:
- if (field->type.u.sequence.elem_type.atype != atype_integer) {
+ if (field->type.u.legacy.sequence.elem_type.atype != atype_integer) {
+ ERR("Sequence nesting only supports integer types.");
+ return -EINVAL;
+ }
+ if (is_context) {
+ load->object_type = OBJECT_TYPE_STRING;
+ } else {
+ if (field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) {
+ load->object_type = OBJECT_TYPE_SEQUENCE;
+ load->field = field;
+ } else {
+ load->object_type = OBJECT_TYPE_STRING_SEQUENCE;
+ }
+ }
+ break;
+ case atype_sequence_nestable:
+ if (field->type.u.sequence_nestable.elem_type->atype != atype_integer) {
ERR("Sequence nesting only supports integer types.");
return -EINVAL;
}
if (is_context) {
load->object_type = OBJECT_TYPE_STRING;
} else {
- if (field->type.u.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none) {
+ if (field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none) {
load->object_type = OBJECT_TYPE_SEQUENCE;
load->field = field;
} else {
}
}
break;
+
case atype_string:
load->object_type = OBJECT_TYPE_STRING;
break;
name = runtime->p.bc->bc.data + runtime->p.bc->bc.reloc_offset + offset;
for (i = 0; i < nr_fields; i++) {
field = &desc->fields[i];
+ if (field->u.ext.nofilter) {
+ continue;
+ }
if (!strcmp(field->name, name)) {
found = true;
break;
switch (field->type.atype) {
case atype_integer:
case atype_enum:
+ case atype_enum_nestable:
field_offset += sizeof(int64_t);
break;
case atype_array:
+ case atype_array_nestable:
case atype_sequence:
+ case atype_sequence_nestable:
field_offset += sizeof(unsigned long);
field_offset += sizeof(void *);
break;
return -EINVAL;
nr_fields = desc->nr_fields;
for (i = 0; i < nr_fields; i++) {
+ if (fields[i].u.ext.nofilter) {
+ continue;
+ }
if (!strcmp(fields[i].name, field_name)) {
field = &fields[i];
break;
switch (fields[i].type.atype) {
case atype_integer:
case atype_enum:
+ case atype_enum_nestable:
field_offset += sizeof(int64_t);
break;
case atype_array:
+ case atype_array_nestable:
case atype_sequence:
+ case atype_sequence_nestable:
field_offset += sizeof(unsigned long);
field_offset += sizeof(void *);
break;
switch (field->type.atype) {
case atype_integer:
case atype_enum:
+ case atype_enum_nestable:
op->op = FILTER_OP_LOAD_FIELD_REF_S64;
break;
case atype_array:
+ case atype_array_nestable:
case atype_sequence:
+ case atype_sequence_nestable:
op->op = FILTER_OP_LOAD_FIELD_REF_SEQUENCE;
break;
case atype_string:
switch (ctx_field->event_field.type.atype) {
case atype_integer:
case atype_enum:
+ case atype_enum_nestable:
op->op = FILTER_OP_GET_CONTEXT_REF_S64;
break;
/* Sequence and array supported as string */
case atype_string:
case atype_array:
+ case atype_array_nestable:
case atype_sequence:
+ case atype_sequence_nestable:
op->op = FILTER_OP_GET_CONTEXT_REF_STRING;
break;
case atype_float:
list_entry->field.type = LTTNG_UST_FIELD_STRING;
break;
case atype_array:
- if (event_field->type.u.array.elem_type.atype != atype_integer
- || event_field->type.u.array.elem_type.u.basic.integer.encoding == lttng_encode_none)
+ if (event_field->type.u.legacy.array.elem_type.atype != atype_integer
+ || event_field->type.u.legacy.array.elem_type.u.basic.integer.encoding == lttng_encode_none)
+ list_entry->field.type = LTTNG_UST_FIELD_OTHER;
+ else
+ list_entry->field.type = LTTNG_UST_FIELD_STRING;
+ break;
+ case atype_array_nestable:
+ if (event_field->type.u.array_nestable.elem_type->atype != atype_integer
+ || event_field->type.u.array_nestable.elem_type->u.integer.encoding == lttng_encode_none)
list_entry->field.type = LTTNG_UST_FIELD_OTHER;
else
list_entry->field.type = LTTNG_UST_FIELD_STRING;
break;
case atype_sequence:
- if (event_field->type.u.sequence.elem_type.atype != atype_integer
- || event_field->type.u.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none)
+ if (event_field->type.u.legacy.sequence.elem_type.atype != atype_integer
+ || event_field->type.u.legacy.sequence.elem_type.u.basic.integer.encoding == lttng_encode_none)
+ list_entry->field.type = LTTNG_UST_FIELD_OTHER;
+ else
+ list_entry->field.type = LTTNG_UST_FIELD_STRING;
+ break;
+ case atype_sequence_nestable:
+ if (event_field->type.u.sequence_nestable.elem_type->atype != atype_integer
+ || event_field->type.u.sequence_nestable.elem_type->u.integer.encoding == lttng_encode_none)
list_entry->field.type = LTTNG_UST_FIELD_OTHER;
else
list_entry->field.type = LTTNG_UST_FIELD_STRING;
case atype_float:
list_entry->field.type = LTTNG_UST_FIELD_FLOAT;
break;
- case atype_enum:
+ case atype_enum: /* Fall-through */
+ case atype_enum_nestable:
list_entry->field.type = LTTNG_UST_FIELD_ENUM;
break;
default:
[LTTNG_UST_DYNAMIC_TYPE_NONE] = {
.name = "none",
.type = {
- .atype = atype_struct,
- .u._struct.nr_fields = 0, /* empty struct. */
+ .atype = atype_struct_nestable,
+ .u.struct_nestable.nr_fields = 0, /* empty struct. */
+ .u.struct_nestable.alignment = 0,
},
.nowrite = 0,
},
.name = "string",
.type = {
.atype = atype_string,
- .u.basic.string.encoding = lttng_encode_UTF8,
+ .u.string.encoding = lttng_encode_UTF8,
},
.nowrite = 0,
},
static const struct lttng_event_field dt_enum_field = {
.name = NULL,
- .type.atype = atype_enum,
- .type.u.basic.enumeration.desc = &dt_enum_desc,
- .type.u.basic.enumeration.container_type = {
- .size = sizeof(char) * CHAR_BIT,
- .alignment = lttng_alignof(char) * CHAR_BIT,
- .signedness = lttng_is_signed_type(char),
- .reverse_byte_order = 0,
- .base = 10,
- .encoding = lttng_encode_none,
- },
+ .type.atype = atype_enum_nestable,
+ .type.u.enum_nestable.desc = &dt_enum_desc,
+ .type.u.enum_nestable.container_type =
+ __LTTNG_COMPOUND_LITERAL(struct lttng_type,
+ __type_integer(char, BYTE_ORDER, 10, none)),
.nowrite = 0,
};
static const struct lttng_event_field myfields[] = {
[0] = {
.name = "mytag",
- .type.atype = atype_enum,
- .type.u.basic.enumeration.desc = &myenum_desc,
- .type.u.basic.enumeration.container_type = {
- .size = sizeof(char) * CHAR_BIT,
- .alignment = lttng_alignof(char) * CHAR_BIT,
- .signedness = lttng_is_signed_type(char),
- .reverse_byte_order = 0,
- .base = 10,
- .encoding = lttng_encode_none,
- },
+ .type.atype = atype_enum_nestable,
+ .type.u.enum_nestable.desc = &myenum_desc,
+ .type.u.enum_nestable.container_type =
+ __LTTNG_COMPOUND_LITERAL(struct lttng_type,
+ __type_integer(char, BYTE_ORDER, 10, none)),
.nowrite = 0,
},
[1] = {
.name = "myfield",
.type = {
- .atype = atype_variant,
- .u.variant = &myvariant,
+ .atype = atype_variant_nestable,
+ .u.variant_nestable = &myvariant,
},
.nowrite = 0,
},