Implement event notifier group create
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Wed, 5 Feb 2020 19:13:42 +0000 (14:13 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 18 Nov 2020 18:07:21 +0000 (13:07 -0500)
Event notifier groups will contain the event notifiers.
All event notifiers of a group will share the same ring buffer to save
the tracer notifications.

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I7c38fbfd26517d00c8de38ca1981da623d570529

include/lttng/abi.h
include/lttng/events.h
src/lttng-abi.c
src/lttng-events.c

index 0e3b5d15661a7e2cdc9b323c33d6020f07b6fd51..8ef9c11261eecd6c0078c24ed922f8a972d20d9c 100644 (file)
@@ -264,6 +264,7 @@ struct lttng_kernel_tracker_args {
 #define LTTNG_KERNEL_SYSCALL_LIST              _IO(0xF6, 0x4A)
 #define LTTNG_KERNEL_TRACER_ABI_VERSION                \
        _IOR(0xF6, 0x4B, struct lttng_kernel_tracer_abi_version)
+#define LTTNG_KERNEL_EVENT_NOTIFIER_GROUP_CREATE    _IO(0xF6, 0x4C)
 
 /* Session FD ioctl */
 /* lttng/abi-old.h reserve 0x50, 0x51, 0x52, and 0x53. */
index 06bde3207bfa0bc693b4d5380b3e6b0e93d80cc6..1e84000d45f090589f7e82a3d447f88c806f26d8 100644 (file)
@@ -557,6 +557,16 @@ struct lttng_session {
        char creation_time[LTTNG_KERNEL_SESSION_CREATION_TIME_ISO8601_LEN];
 };
 
+struct lttng_event_notifier_group {
+       struct file *file;              /* File associated to event notifier group */
+       struct list_head node;          /* event notifier group list */
+       struct lttng_ctx *ctx;          /* Contexts for filters. */
+       struct lttng_channel_ops *ops;
+       struct lttng_transport *transport;
+       struct channel *chan;           /* Ring buffer channel for event notifier group. */
+       struct lib_ring_buffer *buf;    /* Ring buffer for event notifier group. */
+};
+
 struct lttng_metadata_cache {
        char *data;                     /* Metadata cache */
        unsigned int cache_alloc;       /* Metadata allocated size (bytes) */
@@ -592,6 +602,10 @@ int lttng_session_metadata_regenerate(struct lttng_session *session);
 int lttng_session_statedump(struct lttng_session *session);
 void metadata_cache_destroy(struct kref *kref);
 
+struct lttng_event_notifier_group *lttng_event_notifier_group_create(void);
+void lttng_event_notifier_group_destroy(
+               struct lttng_event_notifier_group *event_notifier_group);
+
 struct lttng_channel *lttng_channel_create(struct lttng_session *session,
                                       const char *transport_name,
                                       void *buf_addr,
index 3bc2d1fb7c3df1a979ef1992f14554079dbddff3..00d0a34eb7251fc6be3fd25d7d71f8b6604adf21 100644 (file)
@@ -59,6 +59,7 @@ static const struct file_operations lttng_proc_ops;
 #endif
 
 static const struct file_operations lttng_session_fops;
+static const struct file_operations lttng_event_notifier_group_fops;
 static const struct file_operations lttng_channel_fops;
 static const struct file_operations lttng_metadata_fops;
 static const struct file_operations lttng_event_fops;
@@ -105,6 +106,41 @@ fd_error:
        return ret;
 }
 
+static
+int lttng_abi_create_event_notifier_group(void)
+{
+       struct lttng_event_notifier_group *event_notifier_group;
+       struct file *event_notifier_group_file;
+       int event_notifier_group_fd, ret;
+
+       event_notifier_group = lttng_event_notifier_group_create();
+       if (!event_notifier_group)
+               return -ENOMEM;
+
+       event_notifier_group_fd = lttng_get_unused_fd();
+       if (event_notifier_group_fd < 0) {
+               ret = event_notifier_group_fd;
+               goto fd_error;
+       }
+       event_notifier_group_file = anon_inode_getfile("[lttng_event_notifier_group]",
+                                         &lttng_event_notifier_group_fops,
+                                         event_notifier_group, O_RDWR);
+       if (IS_ERR(event_notifier_group_file)) {
+               ret = PTR_ERR(event_notifier_group_file);
+               goto file_error;
+       }
+
+       event_notifier_group->file = event_notifier_group_file;
+       fd_install(event_notifier_group_fd, event_notifier_group_file);
+       return event_notifier_group_fd;
+
+file_error:
+       put_unused_fd(event_notifier_group_fd);
+fd_error:
+       lttng_event_notifier_group_destroy(event_notifier_group);
+       return ret;
+}
+
 static
 int lttng_abi_tracepoint_list(void)
 {
@@ -306,6 +342,8 @@ long lttng_abi_add_context(struct file *file,
  *             Returns after all previously running probes have completed
  *     LTTNG_KERNEL_TRACER_ABI_VERSION
  *             Returns the LTTng kernel tracer ABI version
+ *     LTTNG_KERNEL_EVENT_NOTIFIER_GROUP_CREATE
+ *             Returns a LTTng event notifier group file descriptor
  *
  * The returned session will be deleted when its file descriptor is closed.
  */
@@ -316,6 +354,8 @@ long lttng_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
        case LTTNG_KERNEL_OLD_SESSION:
        case LTTNG_KERNEL_SESSION:
                return lttng_abi_create_session();
+       case LTTNG_KERNEL_EVENT_NOTIFIER_GROUP_CREATE:
+               return lttng_abi_create_event_notifier_group();
        case LTTNG_KERNEL_OLD_TRACER_VERSION:
        {
                struct lttng_kernel_tracer_version v;
@@ -1398,6 +1438,37 @@ fd_error:
        return ret;
 }
 
+static
+long lttng_event_notifier_group_ioctl(struct file *file, unsigned int cmd,
+               unsigned long arg)
+{
+       switch (cmd) {
+       default:
+               return -ENOIOCTLCMD;
+       }
+       return 0;
+}
+
+static
+int lttng_event_notifier_group_release(struct inode *inode, struct file *file)
+{
+       struct lttng_event_notifier_group *event_notifier_group =
+                       file->private_data;
+
+       if (event_notifier_group)
+               lttng_event_notifier_group_destroy(event_notifier_group);
+       return 0;
+}
+
+static const struct file_operations lttng_event_notifier_group_fops = {
+       .owner = THIS_MODULE,
+       .release = lttng_event_notifier_group_release,
+       .unlocked_ioctl = lttng_event_notifier_group_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = lttng_event_notifier_group_ioctl,
+#endif
+};
+
 /**
  *     lttng_channel_ioctl - lttng syscall through ioctl
  *
index e868525dd039e3ed9250958a45a070e01e48e935..246c71029dcc23d9f4dd602a645a5b069b0abcd1 100644 (file)
@@ -48,6 +48,7 @@
 #define METADATA_CACHE_DEFAULT_SIZE 4096
 
 static LIST_HEAD(sessions);
+static LIST_HEAD(event_notifier_groups);
 static LIST_HEAD(lttng_transport_list);
 /*
  * Protect the sessions and metadata caches.
@@ -189,6 +190,64 @@ err:
        return NULL;
 }
 
+struct lttng_event_notifier_group *lttng_event_notifier_group_create(void)
+{
+       struct lttng_transport *transport = NULL;
+       struct lttng_event_notifier_group *event_notifier_group;
+       const char *transport_name = "relay-event-notifier";
+       size_t subbuf_size = 4096;      //TODO
+       size_t num_subbuf = 16;         //TODO
+       unsigned int switch_timer_interval = 0;
+       unsigned int read_timer_interval = 0;
+
+       mutex_lock(&sessions_mutex);
+
+       transport = lttng_transport_find(transport_name);
+       if (!transport) {
+               printk(KERN_WARNING "LTTng: transport %s not found\n",
+                      transport_name);
+               goto notransport;
+       }
+       if (!try_module_get(transport->owner)) {
+               printk(KERN_WARNING "LTTng: Can't lock transport %s module.\n",
+                      transport_name);
+               goto notransport;
+       }
+
+       event_notifier_group = lttng_kvzalloc(sizeof(struct lttng_event_notifier_group),
+                                      GFP_KERNEL);
+       if (!event_notifier_group)
+               goto nomem;
+
+       /*
+        * Initialize the ring buffer used to store event notifier
+        * notifications.
+        */
+       event_notifier_group->ops = &transport->ops;
+       event_notifier_group->chan = transport->ops.channel_create(
+                       transport_name, event_notifier_group, NULL,
+                       subbuf_size, num_subbuf, switch_timer_interval,
+                       read_timer_interval);
+       if (!event_notifier_group->chan)
+               goto create_error;
+
+       event_notifier_group->transport = transport;
+       list_add(&event_notifier_group->node, &event_notifier_groups);
+
+       mutex_unlock(&sessions_mutex);
+
+       return event_notifier_group;
+
+create_error:
+       lttng_kvfree(event_notifier_group);
+nomem:
+       if (transport)
+               module_put(transport->owner);
+notransport:
+       mutex_unlock(&sessions_mutex);
+       return NULL;
+}
+
 void metadata_cache_destroy(struct kref *kref)
 {
        struct lttng_metadata_cache *cache =
@@ -245,6 +304,19 @@ void lttng_session_destroy(struct lttng_session *session)
        lttng_kvfree(session);
 }
 
+void lttng_event_notifier_group_destroy(struct lttng_event_notifier_group *event_notifier_group)
+{
+       if (!event_notifier_group)
+               return;
+
+       mutex_lock(&sessions_mutex);
+       event_notifier_group->ops->channel_destroy(event_notifier_group->chan);
+       module_put(event_notifier_group->transport->owner);
+       list_del(&event_notifier_group->node);
+       mutex_unlock(&sessions_mutex);
+       lttng_kvfree(event_notifier_group);
+}
+
 int lttng_session_statedump(struct lttng_session *session)
 {
        int ret;
This page took 0.03085 seconds and 4 git commands to generate.