From 71d3169070a4c9e0df87a9d825dd7520022385a7 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Wed, 8 May 2013 14:52:42 -0400 Subject: [PATCH] Fix: add provider ABI compatibility check There is not much we can do for this compatibility bug in lttng-ust 2.0 and 2.1 (already stable). Adding this check so that starting with lttng-ust 2.2, when liblttng-ust encounters a probe provider with a provider version major number higher than it supports, it will reject it. Fixes #502 Signed-off-by: Mathieu Desnoyers --- include/lttng/ust-events.h | 13 ++++++++- include/lttng/ust-tracepoint-event.h | 2 ++ liblttng-ust/lttng-probes.c | 40 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h index 749478a6..0b8664c3 100644 --- a/include/lttng/ust-events.h +++ b/include/lttng/ust-events.h @@ -37,6 +37,15 @@ #define LTTNG_UST_UUID_LEN 16 +/* + * Tracepoint provider version. Compatibility based on the major number. + * Older tracepoint providers can always register to newer lttng-ust + * library, but the opposite is rejected: a newer tracepoint provider is + * rejected by an older lttng-ust library. + */ +#define LTTNG_UST_PROVIDER_MAJOR 1 +#define LTTNG_UST_PROVIDER_MINOR 0 + struct lttng_channel; struct lttng_session; struct lttng_ust_lib_ring_buffer_ctx; @@ -251,7 +260,7 @@ struct lttng_event_desc { } u; }; -#define LTTNG_UST_PROBE_DESC_PADDING 20 +#define LTTNG_UST_PROBE_DESC_PADDING 12 struct lttng_probe_desc { const char *provider; const struct lttng_event_desc **event_desc; @@ -259,6 +268,8 @@ struct lttng_probe_desc { struct cds_list_head head; /* chain registered probes */ struct cds_list_head lazy_init_head; int lazy; /* lazy registration */ + uint32_t major; + uint32_t minor; char padding[LTTNG_UST_PROBE_DESC_PADDING]; }; diff --git a/include/lttng/ust-tracepoint-event.h b/include/lttng/ust-tracepoint-event.h index e46cc1a1..c7bceef6 100644 --- a/include/lttng/ust-tracepoint-event.h +++ b/include/lttng/ust-tracepoint-event.h @@ -652,6 +652,8 @@ static struct lttng_probe_desc _TP_COMBINE_TOKENS(__probe_desc___, TRACEPOINT_PR .provider = __tp_stringify(TRACEPOINT_PROVIDER), .event_desc = _TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER), .nr_events = _TP_ARRAY_SIZE(_TP_COMBINE_TOKENS(__event_desc___, TRACEPOINT_PROVIDER)), + .major = LTTNG_UST_PROVIDER_MAJOR, + .minor = LTTNG_UST_PROVIDER_MINOR, }; /* diff --git a/liblttng-ust/lttng-probes.c b/liblttng-ust/lttng-probes.c index f028ccab..433171cf 100644 --- a/liblttng-ust/lttng-probes.c +++ b/liblttng-ust/lttng-probes.c @@ -160,10 +160,47 @@ const struct lttng_probe_desc *find_provider(const char *provider) return NULL; } +static +int check_provider_version(struct lttng_probe_desc *desc) +{ + /* + * Check tracepoint provider version compatibility. + */ + if (desc->major <= LTTNG_UST_PROVIDER_MAJOR) { + DBG("Provider \"%s\" accepted, version %u.%u is compatible " + "with LTTng UST provider version %u.%u.", + desc->provider, desc->major, desc->minor, + LTTNG_UST_PROVIDER_MAJOR, + LTTNG_UST_PROVIDER_MINOR); + if (desc->major < LTTNG_UST_PROVIDER_MAJOR) { + DBG("However, some LTTng UST features might not be " + "available for this provider unless it is " + "recompiled against a more recent LTTng UST."); + } + return 1; /* accept */ + } else { + ERR("Provider \"%s\" rejected, version %u.%u is incompatible " + "with LTTng UST provider version %u.%u. Please upgrade " + "LTTng UST.", + desc->provider, desc->major, desc->minor, + LTTNG_UST_PROVIDER_MAJOR, + LTTNG_UST_PROVIDER_MINOR); + return 0; /* reject */ + } +} + + int lttng_probe_register(struct lttng_probe_desc *desc) { int ret = 0; + /* + * If version mismatch, don't register, but don't trigger assert + * on caller. The version check just prints an error. + */ + if (!check_provider_version(desc)) + return 0; + ust_lock(); /* @@ -197,6 +234,9 @@ int ltt_probe_register(struct lttng_probe_desc *desc) void lttng_probe_unregister(struct lttng_probe_desc *desc) { + if (!check_provider_version(desc)) + return; + ust_lock(); if (!desc->lazy) cds_list_del(&desc->head); -- 2.34.1