lttng_ust_init_thread: initialise cached context values
[lttng-ust.git] / src / lib / lttng-ust / lttng-probes.c
index 4552e5e82880d48f800093675f3986b4f6a30cba..2d47bf19c050e475ca0a506e5dff1d5e17adf5bf 100644 (file)
@@ -39,17 +39,98 @@ static CDS_LIST_HEAD(lazy_probe_init);
  */
 static int lazy_nesting;
 
+static
+int check_provider_version(const struct lttng_ust_probe_desc *desc)
+{
+       /*
+        * Check tracepoint provider version compatibility.
+        */
+       if (desc->major <= LTTNG_UST_PROVIDER_MAJOR &&
+                       desc->major >= LTTNG_UST_PROVIDER_MAJOR_OLDEST_COMPATIBLE) {
+               DBG("Provider \"%s\" accepted, version %u.%u is compatible "
+                       "with LTTng UST provider version %u.%u.",
+                       desc->provider_name, 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_name, desc->major, desc->minor,
+                       LTTNG_UST_PROVIDER_MAJOR,
+                       LTTNG_UST_PROVIDER_MINOR);
+               return 0;               /* reject */
+       }
+}
+
+static
+bool check_type_provider(const struct lttng_ust_type_common *type);
+
+static
+bool check_type_provider(const struct lttng_ust_type_common *type)
+{
+       switch (type->type) {
+       case lttng_ust_type_integer:
+               return true;
+       case lttng_ust_type_string:
+               return true;
+       case lttng_ust_type_float:
+               return true;
+       case lttng_ust_type_dynamic:
+               return true;
+       case lttng_ust_type_enum:
+       {
+               const struct lttng_ust_type_enum *enum_type = caa_container_of(type, const struct lttng_ust_type_enum, parent);
+
+               return check_provider_version(enum_type->desc->probe_desc);
+       }
+       case lttng_ust_type_array:
+       {
+               const struct lttng_ust_type_array *array_type = caa_container_of(type, const struct lttng_ust_type_array, parent);
+
+               return check_type_provider(array_type->elem_type);
+       }
+       case lttng_ust_type_sequence:
+       {
+               const struct lttng_ust_type_sequence *sequence_type = caa_container_of(type, const struct lttng_ust_type_sequence, parent);
+
+               return check_type_provider(sequence_type->elem_type);
+       }
+       case lttng_ust_type_struct:
+       {
+               const struct lttng_ust_type_struct *struct_type = caa_container_of(type, const struct lttng_ust_type_struct, parent);
+               size_t i;
+
+               for (i = 0; i < struct_type->nr_fields; i++) {
+                       if (!check_type_provider(struct_type->fields[i]->type))
+                               return false;
+               }
+               return true;
+       }
+       default:
+               return false;
+       }
+}
+
 /*
  * Validate that each event within the probe provider refers to the
- * right probe, and that the resulting name is not too long.
+ * right probe, that the resulting name is not too long, and that the
+ * event class belongs to a provider with compatible version.
  */
 static
 bool check_event_provider(const struct lttng_ust_probe_desc *probe_desc)
 {
-       int i;
+       int i, j;
 
        for (i = 0; i < probe_desc->nr_events; i++) {
                const struct lttng_ust_event_desc *event_desc = probe_desc->event_desc[i];
+               const struct lttng_ust_tracepoint_class *tp_class = event_desc->tp_class;
 
                if (event_desc->probe_desc != probe_desc) {
                        ERR("Error registering probe provider '%s'. Event '%s:%s' refers to the wrong provider descriptor.",
@@ -61,6 +142,20 @@ bool check_event_provider(const struct lttng_ust_probe_desc *probe_desc)
                                probe_desc->provider_name, probe_desc->provider_name, event_desc->event_name);
                        return false;   /* provider mismatch */
                }
+               if (!check_provider_version(tp_class->probe_desc)) {
+                       ERR("Error registering probe provider '%s'. Event '%s:%s' refers to an event class in a provider with incompatible version.",
+                               probe_desc->provider_name, probe_desc->provider_name, event_desc->event_name);
+                       return false;
+               }
+               for (j = 0; j < tp_class->nr_fields; j++) {
+                       const struct lttng_ust_event_field *field = tp_class->fields[j];
+
+                       if (!check_type_provider(field->type)) {
+                               ERR("Error registering probe provider '%s'. Event '%s:%s' contains a field which refers to an provider with incompatible version.",
+                                       probe_desc->provider_name, probe_desc->provider_name, event_desc->event_name);
+                               return false;
+                       }
+               }
        }
        return true;
 }
@@ -131,40 +226,12 @@ struct cds_list_head *lttng_get_probe_list_head(void)
        return &_probe_list;
 }
 
-static
-int check_provider_version(const struct lttng_ust_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_name, 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_name, desc->major, desc->minor,
-                       LTTNG_UST_PROVIDER_MAJOR,
-                       LTTNG_UST_PROVIDER_MINOR);
-               return 0;               /* reject */
-       }
-}
 
 struct lttng_ust_registered_probe *lttng_ust_probe_register(const struct lttng_ust_probe_desc *desc)
 {
        struct lttng_ust_registered_probe *reg_probe = NULL;
 
-       lttng_ust_fixup_tls();
+       lttng_ust_common_init_thread(0);
 
        /*
         * If version mismatch, don't register, but don't trigger assert
@@ -202,7 +269,7 @@ end:
 
 void lttng_ust_probe_unregister(struct lttng_ust_registered_probe *reg_probe)
 {
-       lttng_ust_fixup_tls();
+       lttng_ust_common_init_thread(0);
 
        if (!reg_probe)
                return;
@@ -259,7 +326,7 @@ int lttng_probes_get_event_list(struct lttng_ust_tracepoint_list *list)
                        cds_list_add(&list_entry->head, &list->head);
                        lttng_ust_format_event_name(event_desc, list_entry->tp.name);
                        if (!event_desc->loglevel) {
-                               list_entry->tp.loglevel = TRACE_DEFAULT;
+                               list_entry->tp.loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT;
                        } else {
                                list_entry->tp.loglevel = *(*event_desc->loglevel);
                        }
@@ -326,7 +393,7 @@ int lttng_probes_get_field_list(struct lttng_ust_field_list *list)
                                probe_desc->event_desc[i];
                        int j;
 
-                       if (event_desc->nr_fields == 0) {
+                       if (event_desc->tp_class->nr_fields == 0) {
                                /* Events without fields. */
                                struct tp_field_list_entry *list_entry;
 
@@ -341,16 +408,16 @@ int lttng_probes_get_field_list(struct lttng_ust_field_list *list)
                                list_entry->field.field_name[0] = '\0';
                                list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
                                if (!event_desc->loglevel) {
-                                       list_entry->field.loglevel = TRACE_DEFAULT;
+                                       list_entry->field.loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT;
                                } else {
                                        list_entry->field.loglevel = *(*event_desc->loglevel);
                                }
                                list_entry->field.nowrite = 1;
                        }
 
-                       for (j = 0; j < event_desc->nr_fields; j++) {
+                       for (j = 0; j < event_desc->tp_class->nr_fields; j++) {
                                const struct lttng_ust_event_field *event_field =
-                                       event_desc->fields[j];
+                                       event_desc->tp_class->fields[j];
                                struct tp_field_list_entry *list_entry;
 
                                /* Skip event if name is too long. */
@@ -394,7 +461,7 @@ int lttng_probes_get_field_list(struct lttng_ust_field_list *list)
                                        list_entry->field.type = LTTNG_UST_ABI_FIELD_OTHER;
                                }
                                if (!event_desc->loglevel) {
-                                       list_entry->field.loglevel = TRACE_DEFAULT;
+                                       list_entry->field.loglevel = LTTNG_UST_TRACEPOINT_LOGLEVEL_DEFAULT;
                                } else {
                                        list_entry->field.loglevel = *(*event_desc->loglevel);
                                }
This page took 0.026892 seconds and 4 git commands to generate.