X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fust-metadata.c;h=984d5f813ccf9277e6e221b7299f8f80a7d50954;hb=d50967fb42672ebeef8736cf6047ef92cfaff0fb;hp=379429285ad6af7f033ce3950c29190eacf706ac;hpb=6c1c0768320135c6936c371b09731851b508c023;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/ust-metadata.c b/src/bin/lttng-sessiond/ust-metadata.c index 379429285..984d5f813 100644 --- a/src/bin/lttng-sessiond/ust-metadata.c +++ b/src/bin/lttng-sessiond/ust-metadata.c @@ -19,7 +19,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE #define _LGPL_SOURCE #include #include @@ -38,6 +37,7 @@ #define max_t(type, a, b) ((type) ((a) > (b) ? (a) : (b))) #endif +#define NSEC_PER_SEC 1000000000ULL #define NR_CLOCK_OFFSET_SAMPLES 10 struct offset_sample { @@ -120,6 +120,23 @@ ssize_t metadata_reserve(struct ust_registry_session *session, size_t len) return ret; } +static +int metadata_file_append(struct ust_registry_session *session, + const char *str, size_t len) +{ + ssize_t written; + + if (session->metadata_fd < 0) { + return 0; + } + /* Write to metadata file */ + written = lttng_write(session->metadata_fd, str, len); + if (written != len) { + return -1; + } + return 0; +} + /* * We have exclusive access to our metadata buffer (protected by the * ust_lock), so we can do racy operations such as looking for @@ -149,6 +166,11 @@ int lttng_metadata_printf(struct ust_registry_session *session, goto end; } memcpy(&session->metadata[offset], str, len); + ret = metadata_file_append(session, str, len); + if (ret) { + PERROR("Error appending to metadata file"); + goto end; + } DBG3("Append to metadata: \"%s\"", str); ret = 0; @@ -157,6 +179,102 @@ end: return ret; } +/* Called with session registry mutex held. */ +static +int ust_metadata_enum_statedump(struct ust_registry_session *session, + const char *enum_name, + uint64_t enum_id, + const struct ustctl_integer_type *container_type, + const char *field_name) +{ + struct ust_registry_enum *reg_enum; + const struct ustctl_enum_entry *entries; + size_t nr_entries; + int ret = 0; + size_t i; + + rcu_read_lock(); + reg_enum = ust_registry_lookup_enum_by_id(session, enum_name, enum_id); + rcu_read_unlock(); + /* reg_enum can still be used because session registry mutex is held. */ + if (!reg_enum) { + ret = -ENOENT; + goto end; + } + entries = reg_enum->entries; + nr_entries = reg_enum->nr_entries; + + ret = lttng_metadata_printf(session, + " enum : integer { size = %u; align = %u; signed = %u; encoding = %s; base = %u; } {\n", + container_type->size, + container_type->alignment, + container_type->signedness, + (container_type->encoding == ustctl_encode_none) + ? "none" + : (container_type->encoding == ustctl_encode_UTF8) + ? "UTF8" + : "ASCII", + container_type->base); + if (ret) { + goto end; + } + /* Dump all entries */ + for (i = 0; i < nr_entries; i++) { + const struct ustctl_enum_entry *entry = &entries[i]; + int j, len; + + ret = lttng_metadata_printf(session, + " \""); + if (ret) { + goto end; + } + len = strlen(entry->string); + /* Escape the character '"' */ + for (j = 0; j < len; j++) { + char c = entry->string[j]; + + switch (c) { + case '"': + ret = lttng_metadata_printf(session, + "\\\""); + break; + case '\\': + ret = lttng_metadata_printf(session, + "\\\\"); + break; + default: + ret = lttng_metadata_printf(session, + "%c", c); + break; + } + if (ret) { + goto end; + } + } + ret = lttng_metadata_printf(session, + "\" = "); + if (ret) { + goto end; + } + if (entry->start == entry->end) { + ret = lttng_metadata_printf(session, + "%d,\n", + entry->start); + } else { + ret = lttng_metadata_printf(session, + "%d ... %d,\n", + entry->start, entry->end); + } + if (ret) { + goto end; + } + } + ret = lttng_metadata_printf(session, " } _%s;\n", + field_name); +end: + return ret; +} + static int _lttng_field_statedump(struct ust_registry_session *session, const struct ustctl_field *field) @@ -188,6 +306,13 @@ int _lttng_field_statedump(struct ust_registry_session *session, field->type.u.basic.integer.reverse_byte_order ? bo_reverse : bo_native, field->name); 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->name); + break; case ustctl_atype_float: ret = lttng_metadata_printf(session, " floating_point { exp_dig = %u; mant_dig = %u; align = %u;%s } _%s;\n", @@ -197,8 +322,6 @@ int _lttng_field_statedump(struct ust_registry_session *session, field->type.u.basic.integer.reverse_byte_order ? bo_reverse : bo_native, field->name); break; - case ustctl_atype_enum: - return -EINVAL; case ustctl_atype_array: { const struct ustctl_basic_type *elem_type; @@ -336,7 +459,7 @@ int ust_metadata_event_statedump(struct ust_registry_session *session, ret = lttng_metadata_printf(session, " loglevel = %d;\n", - event->loglevel); + event->loglevel_value); if (ret) goto end; @@ -348,23 +471,6 @@ int ust_metadata_event_statedump(struct ust_registry_session *session, goto end; } -#if 0 /* context for events not supported */ - if (event->ctx) { - ret = lttng_metadata_printf(session, - " context := struct {\n"); - if (ret) - goto end; - } - ret = _lttng_context_metadata_statedump(session, event->ctx); - if (ret) - goto end; - if (event->ctx) { - ret = lttng_metadata_printf(session, - " };\n"); - if (ret) - goto end; - } -#endif ret = lttng_metadata_printf(session, " fields := struct {\n" ); @@ -502,6 +608,7 @@ static int measure_single_clock_offset(struct offset_sample *sample) { uint64_t offset, monotonic[2], measure_delta, realtime; + uint64_t tcf = trace_clock_freq(); struct timespec rts = { 0, 0 }; int ret; @@ -520,8 +627,12 @@ int measure_single_clock_offset(struct offset_sample *sample) return 0; } offset = (monotonic[0] + monotonic[1]) >> 1; - realtime = (uint64_t) rts.tv_sec * 1000000000ULL; - realtime += rts.tv_nsec; + realtime = (uint64_t) rts.tv_sec * tcf; + if (tcf == NSEC_PER_SEC) { + realtime += rts.tv_nsec; + } else { + realtime += (uint64_t) rts.tv_nsec * tcf / NSEC_PER_SEC; + } offset = realtime - offset; sample->offset = offset; sample->measure_delta = measure_delta; @@ -575,6 +686,15 @@ int ust_metadata_session_statedump(struct ust_registry_session *session, uuid_c[8], uuid_c[9], uuid_c[10], uuid_c[11], uuid_c[12], uuid_c[13], uuid_c[14], uuid_c[15]); + /* For crash ABI */ + ret = lttng_metadata_printf(session, + "/* CTF %u.%u */\n\n", + CTF_SPEC_MAJOR, + CTF_SPEC_MINOR); + if (ret) { + goto end; + } + ret = lttng_metadata_printf(session, "typealias integer { size = 8; align = %u; signed = false; } := uint8_t;\n" "typealias integer { size = 16; align = %u; signed = false; } := uint16_t;\n" @@ -654,8 +774,8 @@ int ust_metadata_session_statedump(struct ust_registry_session *session, ret = lttng_metadata_printf(session, "clock {\n" - " name = %s;\n", - "monotonic" + " name = \"%s\";\n", + trace_clock_name() ); if (ret) goto end; @@ -670,11 +790,12 @@ int ust_metadata_session_statedump(struct ust_registry_session *session, } ret = lttng_metadata_printf(session, - " description = \"Monotonic Clock\";\n" + " description = \"%s\";\n" " freq = %" PRIu64 "; /* Frequency, in Hz */\n" " /* clock value offset from Epoch is: offset * (1/freq) */\n" " offset = %" PRIu64 ";\n" "};\n\n", + trace_clock_description(), trace_clock_freq(), measure_clock_offset() ); @@ -684,20 +805,23 @@ int ust_metadata_session_statedump(struct ust_registry_session *session, ret = lttng_metadata_printf(session, "typealias integer {\n" " size = 27; align = 1; signed = false;\n" - " map = clock.monotonic.value;\n" + " map = clock.%s.value;\n" "} := uint27_clock_monotonic_t;\n" "\n" "typealias integer {\n" " size = 32; align = %u; signed = false;\n" - " map = clock.monotonic.value;\n" + " map = clock.%s.value;\n" "} := uint32_clock_monotonic_t;\n" "\n" "typealias integer {\n" " size = 64; align = %u; signed = false;\n" - " map = clock.monotonic.value;\n" + " map = clock.%s.value;\n" "} := uint64_clock_monotonic_t;\n\n", + trace_clock_name(), session->uint32_t_alignment, - session->uint64_t_alignment + trace_clock_name(), + session->uint64_t_alignment, + trace_clock_name() ); if (ret) goto end;