Implement field listing command
[lttng-ust.git] / liblttng-ust / lttng-ust-abi.c
index 435763d7e4e6f5f2ffd6754c15be1439f65f41f8..c16a617ceb98710b28466e6dc72080d463d173cc 100644 (file)
@@ -52,6 +52,8 @@ static int lttng_ust_abi_close_in_progress;
 
 static
 int lttng_abi_tracepoint_list(void);
+static
+int lttng_abi_tracepoint_field_list(void);
 
 /*
  * Object descriptor table. Should be protected from concurrent access
@@ -220,6 +222,7 @@ static const struct lttng_ust_objd_ops lttng_event_ops;
 static const struct lttng_ust_objd_ops lttng_wildcard_ops;
 static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops;
 static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops;
+static const struct lttng_ust_objd_ops lttng_tracepoint_field_list_ops;
 
 enum channel_type {
        PER_CPU_CHANNEL,
@@ -303,6 +306,8 @@ long lttng_abi_add_context(int objd,
  *             Returns the LTTng kernel tracer version
  *     LTTNG_UST_TRACEPOINT_LIST
  *             Returns a file descriptor listing available tracepoints
+ *     LTTNG_UST_TRACEPOINT_FIELD_LIST
+ *             Returns a file descriptor listing available tracepoint fields
  *     LTTNG_UST_WAIT_QUIESCENT
  *             Returns after all previously running probes have completed
  *
@@ -320,6 +325,8 @@ long lttng_cmd(int objd, unsigned int cmd, unsigned long arg,
                                (struct lttng_ust_tracer_version *) arg);
        case LTTNG_UST_TRACEPOINT_LIST:
                return lttng_abi_tracepoint_list();
+       case LTTNG_UST_TRACEPOINT_FIELD_LIST:
+               return lttng_abi_tracepoint_field_list();
        case LTTNG_UST_WAIT_QUIESCENT:
                synchronize_trace();
                return 0;
@@ -602,6 +609,89 @@ static const struct lttng_ust_objd_ops lttng_tracepoint_list_ops = {
        .cmd = lttng_tracepoint_list_cmd,
 };
 
+static
+long lttng_tracepoint_field_list_cmd(int objd, unsigned int cmd,
+       unsigned long arg, union ust_args *uargs)
+{
+       struct lttng_ust_field_list *list = objd_private(objd);
+       struct lttng_ust_field_iter *tp =
+               (struct lttng_ust_field_iter *) arg;
+       struct lttng_ust_field_iter *iter;
+
+       switch (cmd) {
+       case LTTNG_UST_TRACEPOINT_FIELD_LIST_GET:
+       {
+       retry:
+               iter = lttng_ust_field_list_get_iter_next(list);
+               if (!iter)
+                       return -ENOENT;
+               if (!strcmp(iter->event_name, "lttng_ust:metadata"))
+                       goto retry;
+               memcpy(tp, iter, sizeof(*tp));
+               return 0;
+       }
+       default:
+               return -EINVAL;
+       }
+}
+
+static
+int lttng_abi_tracepoint_field_list(void)
+{
+       int list_objd, ret;
+       struct lttng_ust_field_list *list;
+
+       list_objd = objd_alloc(NULL, &lttng_tracepoint_field_list_ops);
+       if (list_objd < 0) {
+               ret = list_objd;
+               goto objd_error;
+       }
+       list = zmalloc(sizeof(*list));
+       if (!list) {
+               ret = -ENOMEM;
+               goto alloc_error;
+       }
+       objd_set_private(list_objd, list);
+
+       /* populate list by walking on all registered probes. */
+       ret = ltt_probes_get_field_list(list);
+       if (ret) {
+               goto list_error;
+       }
+       return list_objd;
+
+list_error:
+       free(list);
+alloc_error:
+       {
+               int err;
+
+               err = lttng_ust_objd_unref(list_objd);
+               assert(!err);
+       }
+objd_error:
+       return ret;
+}
+
+static
+int lttng_release_tracepoint_field_list(int objd)
+{
+       struct lttng_ust_field_list *list = objd_private(objd);
+
+       if (list) {
+               ltt_probes_prune_field_list(list);
+               free(list);
+               return 0;
+       } else {
+               return -EINVAL;
+       }
+}
+
+static const struct lttng_ust_objd_ops lttng_tracepoint_field_list_ops = {
+       .release = lttng_release_tracepoint_field_list,
+       .cmd = lttng_tracepoint_field_list_cmd,
+};
+
 struct stream_priv_data {
        struct lttng_ust_lib_ring_buffer *buf;
        struct ltt_channel *ltt_chan;
This page took 0.023746 seconds and 4 git commands to generate.