libust ABI: export streams
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 22 Sep 2011 14:51:55 +0000 (10:51 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 22 Sep 2011 14:51:55 +0000 (10:51 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/lttng-ust-comm.h
include/ust/lttng-events.h
include/ust/lttng-ust-abi.h
libringbuffer/frontend.h
libringbuffer/ring_buffer_backend.c
libringbuffer/ring_buffer_frontend.c
libringbuffer/shm.h
libust/ltt-ring-buffer-client.h
libust/ltt-ring-buffer-metadata-client.h
libust/lttng-ust-abi.c
libust/lttng-ust-comm.c

index a5220a436bc6e13d06bbc3a663fead7bea842549..d792074e3810eb5a0ed5e54428cdc4a10a27b4a7 100644 (file)
@@ -126,6 +126,7 @@ struct lttcomm_ust_msg {
        union {
                struct lttng_ust_tracer_version version;
                struct lttng_ust_channel channel;
+               struct lttng_ust_stream stream;
                struct lttng_ust_event event;
                struct lttng_ust_context context;
        } u;
@@ -141,6 +142,9 @@ struct lttcomm_ust_reply {
        uint32_t ret_code;      /* enum enum lttcomm_return_code */
        uint32_t ret_val;       /* return value */
        union {
+               struct {
+                       uint64_t memory_map_size;
+               } stream;
        } u;
 };
 
index 303d0dafc0a9d6393bb25ff8ff12b789c1e26455..db475cdb25959fa48eb17abb2d92603352689088 100644 (file)
@@ -209,7 +209,9 @@ struct ltt_channel_ops {
                                unsigned int read_timer_interval);
        void (*channel_destroy)(struct ltt_channel *ltt_chan);
        struct lib_ring_buffer *(*buffer_read_open)(struct channel *chan,
-                               struct shm_handle *handle);
+                               struct shm_handle *handle,
+                               int *shm_fd, int *wait_fd,
+                               uint64_t *memory_map_size);
        void (*buffer_read_close)(struct lib_ring_buffer *buf,
                                struct shm_handle *handle);
        int (*event_reserve)(struct lib_ring_buffer_ctx *ctx,
index 56fa8b9e076767e664e0bb9db76661c182acd907..73eb61f3f4d11cbb48c0dd4ead8a1b7a98f7c548 100644 (file)
@@ -43,6 +43,16 @@ struct lttng_ust_channel {
        enum lttng_ust_output output;           /* output mode */
 };
 
+/*
+ * This structure is only used internally within UST. It is not per-se
+ * part of the communication between sessiond and UST.
+ */
+struct lttng_ust_stream {
+       int shm_fd;
+       int wait_fd;
+       uint64_t memory_map_size;
+};
+
 struct lttng_ust_event {
        char name[LTTNG_UST_SYM_NAME_LEN];      /* event name */
        enum lttng_ust_instrumentation instrumentation;
index 2385d392e68f985c9061e02ee1f6690692b3ff09..c1d8dd4276962b769395df9e6407dd934b9da11a 100644 (file)
@@ -67,7 +67,9 @@ void *channel_destroy(struct channel *chan, struct shm_handle *handle);
 extern struct lib_ring_buffer *channel_get_ring_buffer(
                                const struct lib_ring_buffer_config *config,
                                struct channel *chan, int cpu,
-                               struct shm_handle *handle);
+                               struct shm_handle *handle,
+                               int *shm_fd, int *wait_fd,
+                               uint64_t *memory_map_size);
 extern int lib_ring_buffer_open_read(struct lib_ring_buffer *buf,
                                     struct shm_handle *handle);
 extern void lib_ring_buffer_release_read(struct lib_ring_buffer *buf,
index 3e202978465ba73923a5c75645011ede0ff18954..72ddacf3d54e5abd395e9acb4ab999e9ab744153 100644 (file)
@@ -482,7 +482,6 @@ void *lib_ring_buffer_offset_address(struct lib_ring_buffer_backend *bufb,
        struct channel_backend *chanb = &shmp(handle, bufb->chan)->backend;
        const struct lib_ring_buffer_config *config = chanb->config;
        unsigned long sb_bindex, id;
-       void *ret;
 
        offset &= chanb->buf_size - 1;
        sbidx = offset >> chanb->subbuf_size_order;
index bd774dfa4645633708dc82c68f35a074436e73c2..7dab1594c3061a178d0c279e7f2c5fdb19d7eefd 100644 (file)
@@ -577,12 +577,23 @@ void *channel_destroy(struct channel *chan, struct shm_handle *handle)
 struct lib_ring_buffer *channel_get_ring_buffer(
                                        const struct lib_ring_buffer_config *config,
                                        struct channel *chan, int cpu,
-                                       struct shm_handle *handle)
+                                       struct shm_handle *handle,
+                                       int *shm_fd, int *wait_fd,
+                                       uint64_t *memory_map_size)
 {
-       if (config->alloc == RING_BUFFER_ALLOC_GLOBAL)
+       struct shm_ref *ref;
+
+       if (config->alloc == RING_BUFFER_ALLOC_GLOBAL) {
+               ref = &chan->backend.buf[0].shmp._ref;
+               shm_get_object_data(handle, ref, shm_fd, wait_fd,
+                       memory_map_size);
                return shmp(handle, chan->backend.buf[0].shmp);
-       else
+       } else {
+               ref = &chan->backend.buf[cpu].shmp._ref;
+               shm_get_object_data(handle, ref, shm_fd, wait_fd,
+                       memory_map_size);
                return shmp(handle, chan->backend.buf[cpu].shmp);
+       }
 }
 
 int lib_ring_buffer_open_read(struct lib_ring_buffer *buf,
index 22c9afdcbd2beaf557aa894ca37cd975908f3b37..5785b71d8483d26c3684bdd8875c70aa13f00ca2 100644 (file)
@@ -103,4 +103,22 @@ int shm_get_wait_fd(struct shm_handle *handle, struct shm_ref *ref)
        return obj->wait_fd[0];
 }
 
+static inline
+int shm_get_object_data(struct shm_handle *handle, struct shm_ref *ref,
+               int *shm_fd, int *wait_fd, uint64_t *memory_map_size)
+{
+       struct shm_object_table *table = handle->table;
+       struct shm_object *obj;
+       size_t index;
+
+       index = (size_t) ref->index;
+       if (unlikely(index >= table->allocated_len))
+               return -EPERM;
+       obj = &table->objects[index];
+       *shm_fd = obj->shm_fd;
+       *wait_fd = obj->wait_fd[0];
+       *memory_map_size = obj->memory_map_size;
+       return 0;
+}
+
 #endif /* _LIBRINGBUFFER_SHM_H */
index 2fe854a383d8821df6e2f1855df13c40b26e6c9a..605a28284e7e32c74664ff25190db46b7c7ddad5 100644 (file)
@@ -399,13 +399,17 @@ void ltt_channel_destroy(struct ltt_channel *ltt_chan)
 
 static
 struct lib_ring_buffer *ltt_buffer_read_open(struct channel *chan,
-                                            struct shm_handle *handle)
+                                            struct shm_handle *handle,
+                                            int *shm_fd, int *wait_fd,
+                                            uint64_t *memory_map_size)
 {
        struct lib_ring_buffer *buf;
        int cpu;
 
        for_each_channel_cpu(cpu, chan) {
-               buf = channel_get_ring_buffer(&client_config, chan, cpu, handle);
+               buf = channel_get_ring_buffer(&client_config, chan,
+                               cpu, handle, shm_fd, wait_fd,
+                               memory_map_size);
                if (!lib_ring_buffer_open_read(buf, handle))
                        return buf;
        }
index 3e16890ef68f8bf0bf247d8209c91e477f203055..dd168465655f5a646c8c62f4a3ded71210c03e26 100644 (file)
@@ -179,11 +179,14 @@ void ltt_channel_destroy(struct ltt_channel *ltt_chan)
 
 static
 struct lib_ring_buffer *ltt_buffer_read_open(struct channel *chan,
-                                            struct shm_handle *handle)
+                                            struct shm_handle *handle,
+                                            int *shm_fd, int *wait_fd,
+                                            uint64_t *memory_map_size)
 {
        struct lib_ring_buffer *buf;
 
-       buf = channel_get_ring_buffer(&client_config, chan, 0, handle);
+       buf = channel_get_ring_buffer(&client_config, chan,
+                       0, handle, shm_fd, wait_fd, memory_map_size);
        if (!lib_ring_buffer_open_read(buf, handle))
                return buf;
        return NULL;
index ccaa17fa9ba56bbf3a9cf8a81b0d134ca27fe1bb..0c0d6bb726f9c62804f9f17ee7f726bd5627bf93 100644 (file)
@@ -204,6 +204,7 @@ static const struct objd_ops lttng_session_ops;
 static const struct objd_ops lttng_channel_ops;
 static const struct objd_ops lttng_metadata_ops;
 static const struct objd_ops lttng_event_ops;
+static const struct objd_ops lib_ring_buffer_objd_ops;
 
 enum channel_type {
        PER_CPU_CHANNEL,
@@ -505,35 +506,46 @@ static const struct objd_ops lttng_session_ops = {
        .cmd = lttng_session_cmd,
 };
 
-#if 0
+struct stream_priv_data {
+       struct lib_ring_buffer *buf;
+       struct ltt_channel *ltt_chan;
+};
+
 static
-int lttng_abi_open_stream(int channel_objd)
+int lttng_abi_open_stream(int channel_objd, struct lttng_ust_stream *info)
 {
        struct ltt_channel *channel = objd_private(channel_objd);
        struct lib_ring_buffer *buf;
+       struct stream_priv_data *priv;
        int stream_objd, ret;
 
-       buf = channel->ops->buffer_read_open(channel->chan);
+       buf = channel->ops->buffer_read_open(channel->chan, channel->handle,
+                       &info->shm_fd, &info->wait_fd, &info->memory_map_size);
        if (!buf)
                return -ENOENT;
 
-       stream_objd = objd_alloc(buf, &lib_ring_buffer_objd_ops);
+       priv = zmalloc(sizeof(*priv));
+       if (!priv) {
+               ret = -ENOMEM;
+               goto alloc_error;
+       }
+       priv->buf = buf;
+       priv->ltt_chan = channel;
+       stream_objd = objd_alloc(priv, &lib_ring_buffer_objd_ops);
        if (stream_objd < 0) {
                ret = stream_objd;
                goto objd_error;
        }
-       /*
-        * The stream holds a reference to the channel within the generic ring
-        * buffer library, so no need to hold a refcount on the channel and
-        * session files here.
-        */
+       /* Hold a reference on the channel object descriptor */
+       objd_ref(channel_objd);
        return stream_objd;
 
 objd_error:
-       channel->ops->buffer_read_close(buf);
+       free(priv);
+alloc_error:
+       channel->ops->buffer_read_close(buf, channel->handle);
        return ret;
 }
-#endif //0
 
 static
 int lttng_abi_create_event(int channel_objd,
@@ -603,8 +615,13 @@ long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg)
 
        switch (cmd) {
        case LTTNG_UST_STREAM:
-               return -ENOSYS; //TODO
-               //return lttng_abi_open_stream(objd);
+       {
+               struct lttng_ust_stream *stream;
+
+               stream = (struct lttng_ust_stream *) arg;
+               /* stream used as output */
+               return lttng_abi_open_stream(objd, stream);
+       }
        case LTTNG_UST_EVENT:
                return lttng_abi_create_event(objd, (struct lttng_ust_event *) arg);
        case LTTNG_UST_CONTEXT:
@@ -638,8 +655,13 @@ long lttng_metadata_cmd(int objd, unsigned int cmd, unsigned long arg)
 {
        switch (cmd) {
        case LTTNG_UST_STREAM:
-               return -ENOSYS; //TODO
-               //return lttng_abi_open_stream(objd);
+       {
+               struct lttng_ust_stream *stream;
+
+               stream = (struct lttng_ust_stream *) arg;
+               /* stream used as output */
+               return lttng_abi_open_stream(objd, stream);
+       }
        default:
                return -EINVAL;
        }
@@ -696,6 +718,50 @@ static const struct objd_ops lttng_metadata_ops = {
        .cmd = lttng_metadata_cmd,
 };
 
+/**
+ *     lttng_rb_cmd - lttng ring buffer control through object descriptors
+ *
+ *     @objd: the object descriptor
+ *     @cmd: the command
+ *     @arg: command arg
+ *
+ *     This object descriptor implements lttng commands:
+ *             (None for now. Access is done directly though shm.)
+ *             TODO: Add buffer flush.
+ */
+static
+long lttng_rb_cmd(int objd, unsigned int cmd, unsigned long arg)
+{
+       struct stream_priv_data *priv = objd_private(objd);
+
+       switch (cmd) {
+       default:
+               return -EINVAL;
+       }
+}
+
+static
+int lttng_rb_release(int objd)
+{
+       struct stream_priv_data *priv = objd_private(objd);
+       struct lib_ring_buffer *buf;
+       struct ltt_channel *channel;
+
+       if (priv) {
+               buf = priv->buf;
+               channel = priv->ltt_chan;
+               free(priv);
+
+               return objd_unref(channel->objd);
+       }
+       return 0;
+}
+
+static const struct objd_ops lib_ring_buffer_objd_ops = {
+       .release = lttng_rb_release,
+       .cmd = lttng_rb_cmd,
+};
+
 /**
  *     lttng_event_cmd - lttng control through object descriptors
  *
index c5a3064ae216f222771e7acd99199ea12a520085..d88c4afb2346c000dedd5a96c9fa5239f37bb265 100644 (file)
@@ -282,8 +282,33 @@ end:
        } else {
                lur.ret_code = LTTCOMM_SESSION_FAIL;
        }
+       if (lum->cmd == LTTNG_UST_STREAM) {
+               /*
+                * Special-case reply to send stream info.
+                * Use lum.u output.
+                */
+               lur.u.stream.memory_map_size = lum->u.stream.memory_map_size;
+       }
        ret = send_reply(sock, &lur);
 
+       if (lum->cmd == LTTNG_UST_STREAM && ret >= 0) {
+               /* we also need to send the file descriptors. */
+               ret = lttcomm_send_fds_unix_sock(sock,
+                       &lum->u.stream.shm_fd, &lum->u.stream.shm_fd,
+                       1, sizeof(int));
+               if (ret < 0) {
+                       perror("send shm_fd");
+                       goto error;
+               }
+               ret = lttcomm_send_fds_unix_sock(sock,
+                       &lum->u.stream.wait_fd, &lum->u.stream.wait_fd,
+                       1, sizeof(int));
+               if (ret < 0) {
+                       perror("send wait_fd");
+                       goto error;
+               }
+       }
+error:
        ust_unlock();
        return ret;
 }
This page took 0.029797 seconds and 4 git commands to generate.