filter: add seqnum field to filter command
[lttng-ust.git] / liblttng-ust / ltt-probes.c
index b24cab13f37bcaa8647193e3d3ec0980c8da3b09..aeb6db65224340a311ca320142b841800b9e9772 100644 (file)
@@ -1,11 +1,23 @@
 /*
  * ltt-probes.c
  *
- * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
  * Holds LTTng probes registry.
  *
- * Dual LGPL v2.1/GPL v2 license.
+ * Copyright 2010-2012 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <string.h>
@@ -14,6 +26,7 @@
 #include <urcu/hlist.h>
 #include <lttng/ust-events.h>
 #include <lttng/tracepoint.h>
+#include "tracepoint-internal.h"
 #include <assert.h>
 #include <helper.h>
 #include <ctype.h>
@@ -98,7 +111,12 @@ desc_added:
         * fix the events awaiting probe load.
         */
        for (i = 0; i < desc->nr_events; i++) {
-               ret = pending_probe_fix_events(desc->event_desc[i]);
+               const struct lttng_event_desc *ed;
+
+               ed = desc->event_desc[i];
+               DBG("Registered event probe \"%s\" with signature \"%s\"",
+                       ed->name, ed->signature);
+               ret = pending_probe_fix_events(ed);
                assert(!ret);
        }
 end:
@@ -201,6 +219,142 @@ struct lttng_ust_tracepoint_iter *
        return &entry->tp;
 }
 
+void ltt_probes_prune_field_list(struct lttng_ust_field_list *list)
+{
+       struct tp_field_list_entry *list_entry, *tmp;
+
+       cds_list_for_each_entry_safe(list_entry, tmp, &list->head, head) {
+               cds_list_del(&list_entry->head);
+               free(list_entry);
+       }
+}
+
+/*
+ * called with UST lock held.
+ */
+int ltt_probes_get_field_list(struct lttng_ust_field_list *list)
+{
+       struct lttng_probe_desc *probe_desc;
+       int i;
+
+       CDS_INIT_LIST_HEAD(&list->head);
+       cds_list_for_each_entry(probe_desc, &probe_list, head) {
+               for (i = 0; i < probe_desc->nr_events; i++) {
+                       const struct lttng_event_desc *event_desc =
+                               probe_desc->event_desc[i];
+                       int j;
+
+                       if (event_desc->nr_fields == 0) {
+                               /* Events without fields. */
+                               struct tp_field_list_entry *list_entry;
+
+                               list_entry = zmalloc(sizeof(*list_entry));
+                               if (!list_entry)
+                                       goto err_nomem;
+                               cds_list_add(&list_entry->head, &list->head);
+                               strncpy(list_entry->field.event_name,
+                                       event_desc->name,
+                                       LTTNG_UST_SYM_NAME_LEN);
+                               list_entry->field.event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+                               list_entry->field.field_name[0] = '\0';
+                               list_entry->field.type = LTTNG_UST_FIELD_OTHER;
+                               if (!event_desc->loglevel) {
+                                       list_entry->field.loglevel = TRACE_DEFAULT;
+                               } else {
+                                       list_entry->field.loglevel = *(*event_desc->loglevel);
+                               }
+                               list_entry->field.nowrite = 1;
+                       }
+
+                       for (j = 0; j < event_desc->nr_fields; j++) {
+                               const struct lttng_event_field *event_field =
+                                       &event_desc->fields[j];
+                               struct tp_field_list_entry *list_entry;
+
+                               list_entry = zmalloc(sizeof(*list_entry));
+                               if (!list_entry)
+                                       goto err_nomem;
+                               cds_list_add(&list_entry->head, &list->head);
+                               strncpy(list_entry->field.event_name,
+                                       event_desc->name,
+                                       LTTNG_UST_SYM_NAME_LEN);
+                               list_entry->field.event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+                               strncpy(list_entry->field.field_name,
+                                       event_field->name,
+                                       LTTNG_UST_SYM_NAME_LEN);
+                               list_entry->field.field_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+                               switch (event_field->type.atype) {
+                               case atype_integer:
+                                       list_entry->field.type = LTTNG_UST_FIELD_INTEGER;
+                                       break;
+                               case atype_string:
+                                       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)
+                                               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)
+                                               list_entry->field.type = LTTNG_UST_FIELD_OTHER;
+                                       else
+                                               list_entry->field.type = LTTNG_UST_FIELD_STRING;
+                                       break;
+                               case atype_float:
+                                       list_entry->field.type = LTTNG_UST_FIELD_FLOAT;
+                                       break;
+                               case atype_enum:
+                                       list_entry->field.type = LTTNG_UST_FIELD_ENUM;
+                                       break;
+                               default:
+                                       list_entry->field.type = LTTNG_UST_FIELD_OTHER;
+                               }
+                               if (!event_desc->loglevel) {
+                                       list_entry->field.loglevel = TRACE_DEFAULT;
+                               } else {
+                                       list_entry->field.loglevel = *(*event_desc->loglevel);
+                               }
+                               list_entry->field.nowrite = event_field->nowrite;
+                       }
+               }
+       }
+       if (cds_list_empty(&list->head))
+               list->iter = NULL;
+       else
+               list->iter =
+                       cds_list_first_entry(&list->head,
+                               struct tp_field_list_entry, head);
+       return 0;
+
+err_nomem:
+       ltt_probes_prune_field_list(list);
+       return -ENOMEM;
+}
+
+/*
+ * Return current iteration position, advance internal iterator to next.
+ * Return NULL if end of list.
+ */
+struct lttng_ust_field_iter *
+       lttng_ust_field_list_get_iter_next(struct lttng_ust_field_list *list)
+{
+       struct tp_field_list_entry *entry;
+
+       if (!list->iter)
+               return NULL;
+       entry = list->iter;
+       if (entry->head.next == &list->head)
+               list->iter = NULL;
+       else
+               list->iter = cds_list_entry(entry->head.next,
+                               struct tp_field_list_entry, head);
+       return &entry->field;
+}
+
 /*
  * marshall all probes/all events and create those that fit the
  * wildcard. Add them to the events list as created.
@@ -236,13 +390,13 @@ void ltt_probes_create_wildcard_events(struct wildcard_entry *entry,
 
                                memcpy(&event_param, &wildcard->event_param,
                                                sizeof(event_param));
-                               memcpy(event_param.name,
+                               strncpy(event_param.name,
                                        event_desc->name,
                                        sizeof(event_param.name));
+                               event_param.name[sizeof(event_param.name) - 1] = '\0';
                                /* create event */
                                ret = ltt_event_create(wildcard->chan,
-                                       &event_param, NULL,
-                                       &ev);
+                                       &event_param, &ev);
                                if (ret) {
                                        DBG("Error creating event");
                                        continue;
@@ -252,5 +406,6 @@ void ltt_probes_create_wildcard_events(struct wildcard_entry *entry,
                        }
                }
        }
+       lttng_filter_wildcard_link_bytecode(wildcard);
 }
 
This page took 0.026054 seconds and 4 git commands to generate.