UST support: add UST control commands
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 27 Oct 2011 12:33:28 +0000 (14:33 +0200)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 27 Oct 2011 12:33:28 +0000 (14:33 +0200)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
19 files changed:
include/lttng-sessiond-comm.h
liblttng-sessiond-comm/lttng-sessiond-comm.c
ltt-sessiond/Makefile.am
ltt-sessiond/channel.c
ltt-sessiond/context.c
ltt-sessiond/context.h
ltt-sessiond/event.c
ltt-sessiond/event.h
ltt-sessiond/lttng-ust-abi.h
ltt-sessiond/lttng-ust-ctl.h [new file with mode: 0644]
ltt-sessiond/main.c
ltt-sessiond/trace-kernel.h
ltt-sessiond/trace-ust.c
ltt-sessiond/trace-ust.h
ltt-sessiond/ust-comm.c [deleted file]
ltt-sessiond/ust-comm.h [deleted file]
ltt-sessiond/ust-ctl.c [deleted file]
ltt-sessiond/ust-ctl.h
lttng/commands/enable_events.c

index 7da343a9d899a2509db98cb6caee827523541c39..1b2c4b88e85d99515ebc40a5303e629d64a2b6a7 100644 (file)
@@ -114,8 +114,23 @@ enum lttcomm_return_code {
        LTTCOMM_KERN_NO_SESSION,                /* No kernel session found */
        LTTCOMM_KERN_LIST_FAIL,                 /* Kernel listing events failed */
        LTTCOMM_UST_SESS_FAIL,                  /* UST create session failed */
+       LTTCOMM_UST_CHAN_FAIL,                  /* UST create channel failed */
        LTTCOMM_UST_CHAN_NOT_FOUND,     /* UST channel not found */
-       LTTCOMM_UST_CHAN_FAIL,          /* UST create channel failed */
+       LTTCOMM_UST_CHAN_DISABLE_FAIL, /* UST disable channel failed */
+       LTTCOMM_UST_CHAN_ENABLE_FAIL,  /* UST enable channel failed */
+       LTTCOMM_UST_CONTEXT_FAIL,      /* UST add context failed */
+       LTTCOMM_UST_ENABLE_FAIL,                /* UST enable event failed */
+       LTTCOMM_UST_DISABLE_FAIL,               /* UST disable event failed */
+       LTTCOMM_UST_META_FAIL,                  /* UST open metadata failed */
+       LTTCOMM_UST_START_FAIL,         /* UST start trace failed */
+       LTTCOMM_UST_STOP_FAIL,                  /* UST stop trace failed */
+       LTTCOMM_UST_CONSUMER_FAIL,              /* UST consumer start failed */
+       LTTCOMM_UST_STREAM_FAIL,                /* UST create stream failed */
+       LTTCOMM_UST_DIR_FAIL,                   /* UST trace directory creation failed */
+       LTTCOMM_UST_DIR_EXIST,                  /* UST trace directory exist */
+       LTTCOMM_UST_NO_SESSION,         /* No UST session found */
+       LTTCOMM_UST_LIST_FAIL,                  /* UST listing events failed */
+
        CONSUMERD_COMMAND_SOCK_READY,           /* when consumerd command socket ready */
        CONSUMERD_SUCCESS_RECV_FD,              /* success on receiving fds */
        CONSUMERD_ERROR_RECV_FD,                /* error on receiving fds */
index 6e0e83b792cf64e5d2746ee81789c7ea95d9b3ae..01851de5f3612cd158deaa433fceb90d0fda0781 100644 (file)
@@ -74,8 +74,22 @@ static const char *lttcomm_readable_code[] = {
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_NO_SESSION) ] = "No kernel session found",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_KERN_LIST_FAIL) ] = "Listing kernel events failed",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_SESS_FAIL) ] = "UST create session failed",
-       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CHAN_NOT_FOUND) ] = "UST channel not found",
        [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CHAN_FAIL) ] = "UST create channel failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CHAN_NOT_FOUND) ] = "UST channel not found",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CHAN_DISABLE_FAIL) ] = "Disable UST channel failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CHAN_ENABLE_FAIL) ] = "Enable UST channel failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CONTEXT_FAIL) ] = "Add UST context failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_ENABLE_FAIL) ] = "Enable UST event failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_DISABLE_FAIL) ] = "Disable UST event failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_META_FAIL) ] = "Opening metadata failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_START_FAIL) ] = "Starting UST trace failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_STOP_FAIL) ] = "Stoping UST trace failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_CONSUMER_FAIL) ] = "UST consumer start failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_STREAM_FAIL) ] = "UST create stream failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_DIR_FAIL) ] = "UST trace directory creation failed",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_DIR_EXIST) ] = "UST trace directory already exist",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_NO_SESSION) ] = "No UST session found",
+       [ LTTCOMM_ERR_INDEX(LTTCOMM_UST_LIST_FAIL) ] = "Listing UST events failed",
        [ LTTCOMM_ERR_INDEX(CONSUMERD_COMMAND_SOCK_READY) ] = "consumerd command socket ready",
        [ LTTCOMM_ERR_INDEX(CONSUMERD_SUCCESS_RECV_FD) ] = "consumerd success on receiving fds",
        [ LTTCOMM_ERR_INDEX(CONSUMERD_ERROR_RECV_FD) ] = "consumerd error on receiving fds",
index ecc977ab1b8f95090544779e5ece676bb0c99fd9..f9301896e5df0f50fd95bd83969cb154989b49aa 100644 (file)
@@ -29,9 +29,7 @@ ltt_sessiond_SOURCES = utils.c utils.h \
 if LTTNG_TOOLS_HAVE_UST
 ltt_sessiond_SOURCES += \
                        trace-ust.c \
-                       ust-app.c \
-                       ust-comm.c ust-comm.h \
-                       ust-ctl.c
+                       ust-app.c
 endif
 
 # link on liblttngctl for check if sessiond is already alive.
@@ -41,5 +39,5 @@ ltt_sessiond_LDADD = -lrt \
                 $(top_builddir)/liblttngctl/liblttngctl.la
 
 if LTTNG_TOOLS_HAVE_UST
-ltt_sessiond_LDADD += -llttng-ust-comm
+ltt_sessiond_LDADD += -llttng-ust-comm -lustctl
 endif
index 10635536c0fbcf5726a666ad9a25ce8d5897752b..b61e1fb6792b8d1eaa5c1ac79a8f5ce94a7a6420 100644 (file)
 #include <lttng/lttng.h>
 #include <lttng-sessiond-comm.h>
 #include <lttngerr.h>
+#ifdef CONFIG_LTTNG_TOOLS_HAVE_UST
+#include <ust/lttng-ust-ctl.h>
+#include <ust/lttng-ust-abi.h>
+#else
+#include "lttng-ust-ctl.h"
+#include "lttng-ust-abi.h"
+#endif
 
 #include "channel.h"
 #include "kernel-ctl.h"
@@ -56,6 +63,7 @@ struct lttng_channel *channel_new_default_attr(int dom)
                        chan->attr.num_subbuf = DEFAULT_KERNEL_CHANNEL_SUBBUF_NUM;
                        chan->attr.output = DEFAULT_KERNEL_CHANNEL_OUTPUT;
                        break;
+               case LTTNG_DOMAIN_UST:
                case LTTNG_DOMAIN_UST_PID:
                        chan->attr.subbuf_size = DEFAULT_UST_CHANNEL_SUBBUF_SIZE;
                        chan->attr.num_subbuf = DEFAULT_UST_CHANNEL_SUBBUF_NUM;
@@ -164,6 +172,7 @@ int channel_kernel_create(struct ltt_kernel_session *ksession,
 
        /* Creating channel attributes if needed */
        if (attr == NULL) {
+               /* FIXME: this appears to be a memory leak */
                attr = channel_new_default_attr(LTTNG_DOMAIN_KERNEL);
                if (attr == NULL) {
                        ret = LTTCOMM_FATAL;
@@ -199,23 +208,55 @@ int channel_ust_create(struct ltt_ust_session *usession,
 {
        int ret;
        struct lttng_channel *attr = chan;
+       struct ltt_ust_channel *suchan;
+       struct lttng_ust_channel_attr uattr;
+       struct object_data *obj;
 
        /* Creating channel attributes if needed */
        if (attr == NULL) {
-               attr = channel_new_default_attr(LTTNG_DOMAIN_UST_PID);
+               /* FIXME: this appears to be a memory leak */
+               /* TODO: get default for other UST domains */
+               attr = channel_new_default_attr(LTTNG_DOMAIN_UST);
                if (attr == NULL) {
                        ret = LTTCOMM_FATAL;
                        goto error;
                }
        }
 
-       ret = ustctl_create_channel(sock, usession, attr);
+       suchan = trace_ust_create_channel(attr, usession->path);
+       if (suchan == NULL) {
+               ret = LTTCOMM_FATAL;
+               goto error;
+       }
+       uattr.overwrite = attr->attr.overwrite;
+       uattr.subbuf_size = attr->attr.subbuf_size;
+       uattr.num_subbuf = attr->attr.num_subbuf;
+       uattr.switch_timer_interval = attr->attr.switch_timer_interval;
+       uattr.read_timer_interval = attr->attr.read_timer_interval;
+       uattr.output = attr->attr.output;
+       ret = ustctl_create_channel(sock, usession->handle,
+                       &uattr, &obj);
        if (ret < 0) {
                ret = LTTCOMM_UST_CHAN_FAIL;
                goto error;
        }
-
-       DBG2("Channel %s UST create successfully for sock:%d", attr->name, sock);
+       suchan->attr.overwrite = uattr.overwrite;
+       suchan->attr.subbuf_size = uattr.subbuf_size;
+       suchan->attr.num_subbuf = uattr.num_subbuf;
+       suchan->attr.switch_timer_interval = uattr.switch_timer_interval;
+       suchan->attr.read_timer_interval = uattr.read_timer_interval;
+       suchan->attr.output = uattr.output;
+       suchan->handle = obj->handle;
+       suchan->attr.shm_fd = obj->shm_fd;
+       suchan->attr.wait_fd = obj->wait_fd;
+       suchan->attr.memory_map_size = obj->memory_map_size;
+       suchan->obj = obj;
+
+       /* Add channel to session */
+       cds_list_add(&suchan->list, &usession->channels.head);
+       usession->channels.count++;
+
+       DBG2("Channel %s UST create successfully for sock:%d", suchan->name, sock);
 
        ret = LTTCOMM_OK;
 
@@ -229,18 +270,20 @@ error:
 int channel_ust_enable(struct ltt_ust_session *usession,
                struct ltt_ust_channel *uchan, int sock)
 {
-       int ret;
-       ret = LTTCOMM_OK;
-
-       ret = ustctl_enable_channel(sock, usession, uchan);
+       int ret = LTTCOMM_OK;
+       struct object_data obj;
+
+       obj.handle = uchan->handle;
+       obj.shm_fd = uchan->attr.shm_fd;
+       obj.wait_fd = uchan->attr.wait_fd;
+       obj.memory_map_size = uchan->attr.memory_map_size;
+       ret = ustctl_enable(sock, &obj);
        if (ret < 0) {
                ret = LTTCOMM_UST_CHAN_FAIL;
-               goto error;
+               goto end;
        }
-
        ret = LTTCOMM_OK;
-
-error:
+end:
        return ret;
 }
 
@@ -250,17 +293,19 @@ error:
 int channel_ust_disable(struct ltt_ust_session *usession,
                struct ltt_ust_channel *uchan, int sock)
 {
-       int ret;
-       ret = LTTCOMM_OK;
-
-       ret = ustctl_disable_channel(sock, usession, uchan);
+       int ret = LTTCOMM_OK;
+       struct object_data obj;
+
+       obj.handle = uchan->handle;
+       obj.shm_fd = uchan->attr.shm_fd;
+       obj.wait_fd = uchan->attr.wait_fd;
+       obj.memory_map_size = uchan->attr.memory_map_size;
+       ret = ustctl_disable(sock, &obj);
        if (ret < 0) {
                ret = LTTCOMM_UST_CHAN_FAIL;
-               goto error;
+               goto end;
        }
-
        ret = LTTCOMM_OK;
-
-error:
+end:
        return ret;
 }
index 35cb50b7b0c8cde13b8ee1c56bdec2341033e41e..c7765c0e851056a329a97594164e8815ca5409ec 100644 (file)
 #include <lttng-sessiond-comm.h>
 #include <lttngerr.h>
 
+#ifdef CONFIG_LTTNG_TOOLS_HAVE_UST
+#include <ust/lttng-ust-ctl.h>
+#include <ust/lttng-ust-abi.h>
+#else
+#include "lttng-ust-ctl.h"
+#include "lttng-ust-abi.h"
+#endif
+
 #include "context.h"
 #include "kernel-ctl.h"
 
@@ -191,3 +199,174 @@ int context_kernel_add(struct ltt_kernel_session *ksession,
 error:
        return ret;
 }
+
+/*
+ * UST support.
+ */
+
+/*
+ * Add UST context to an event of a specific channel.
+ */
+static int add_ustctx_to_event(struct ltt_ust_session *ustsession,
+               struct lttng_ust_context *ustctx,
+               struct ltt_ust_channel *ustchan, char *event_name)
+{
+       int ret, found = 0;
+       struct ltt_ust_event *ustevent;
+       struct object_data *context_data;       /* FIXME: currently a memleak */
+
+       DBG("Add UST context to event %s", event_name);
+
+       ustevent = trace_ust_get_event_by_name(event_name, ustchan);
+       if (ustevent != NULL) {
+               ret = ustctl_add_context(ustsession->sock, ustctx,
+                       ustevent->obj, &context_data);
+               if (ret < 0) {
+                       goto error;
+               }
+               found = 1;
+       }
+
+       ret = found;
+
+error:
+       return ret;
+}
+
+/*
+ * Add UST context to all channel.
+ *
+ * If event_name is specified, add context to event instead.
+ */
+static int add_ustctx_all_channels(struct ltt_ust_session *ustsession,
+               struct lttng_ust_context *ustctx, char *event_name)
+{
+       int ret, no_event = 0, found = 0;
+       struct ltt_ust_channel *ustchan;
+       struct object_data *context_data;       /* FIXME: currently a memleak */
+
+       if (strlen(event_name) == 0) {
+               no_event = 1;
+       }
+
+       DBG("Adding ust context to all channels (event: %s)", event_name);
+
+       /* Go over all channels */
+       cds_list_for_each_entry(ustchan, &ustsession->channels.head, list) {
+               if (no_event) {
+                       ret = ustctl_add_context(ustsession->sock,
+                               ustctx, ustchan->obj, &context_data);
+                       if (ret < 0) {
+                               ret = LTTCOMM_UST_CONTEXT_FAIL;
+                               goto error;
+                       }
+               } else {
+                       ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name);
+                       if (ret < 0) {
+                               ret = LTTCOMM_UST_CONTEXT_FAIL;
+                               goto error;
+                       } else if (ret == 1) {
+                               /* Event found and context added */
+                               found = 1;
+                               break;
+                       }
+               }
+       }
+
+       if (!found && !no_event) {
+               ret = LTTCOMM_NO_EVENT;
+               goto error;
+       }
+
+       ret = LTTCOMM_OK;
+
+error:
+       return ret;
+}
+
+/*
+ * Add UST context to a specific channel.
+ *
+ * If event_name is specified, add context to that event.
+ */
+static int add_ustctx_to_channel(struct ltt_ust_session *ustsession,
+               struct lttng_ust_context *ustctx,
+               struct ltt_ust_channel *ustchan, char *event_name)
+{
+       int ret, no_event = 0, found = 0;
+       struct object_data *context_data;       /* FIXME: currently a memleak */
+
+       if (strlen(event_name) == 0) {
+               no_event = 1;
+       }
+
+       DBG("Add UST context to channel '%s', event '%s'",
+                       ustchan->name, event_name);
+
+       if (no_event) {
+               ret = ustctl_add_context(ustsession->sock, ustctx,
+                       ustchan->obj, &context_data);
+               if (ret < 0) {
+                       ret = LTTCOMM_UST_CONTEXT_FAIL;
+                       goto error;
+               }
+       } else {
+               ret = add_ustctx_to_event(ustsession, ustctx, ustchan, event_name);
+               if (ret < 0) {
+                       ret = LTTCOMM_UST_CONTEXT_FAIL;
+                       goto error;
+               } else if (ret == 1) {
+                       /* Event found and context added */
+                       found = 1;
+               }
+       }
+
+       if (!found && !no_event) {
+               ret = LTTCOMM_NO_EVENT;
+               goto error;
+       }
+
+       ret = LTTCOMM_OK;
+
+error:
+       return ret;
+}
+
+/*
+ * Add UST context to tracer.
+ */
+int context_ust_add(struct ltt_ust_session *ustsession,
+               struct lttng_event_context *ctx, char *event_name,
+               char *channel_name)
+{
+       int ret;
+       struct ltt_ust_channel *ustchan;
+       struct lttng_ust_context ustctx;
+
+       /* Setup UST context structure */
+       ustctx.ctx = ctx->ctx;
+
+       if (strlen(channel_name) == 0) {
+               ret = add_ustctx_all_channels(ustsession, &ustctx, event_name);
+               if (ret != LTTCOMM_OK) {
+                       goto error;
+               }
+       } else {
+               /* Get UST channel */
+               ustchan = trace_ust_get_channel_by_name(channel_name, ustsession);
+               if (ustchan == NULL) {
+                       ret = LTTCOMM_UST_CHAN_NOT_FOUND;
+                       goto error;
+               }
+
+               ret = add_ustctx_to_channel(ustsession, &ustctx, ustchan, event_name);
+               if (ret != LTTCOMM_OK) {
+                       goto error;
+               }
+       }
+
+       ret = LTTCOMM_OK;
+
+error:
+       return ret;
+}
index 38d39d94feaea8a0533d615245fd3c546553707d..872e77e7bbd67c40d631e848cddff0af5d85d74e 100644 (file)
 #define _LTT_CONTEXT_H
 
 #include <lttng/lttng.h>
+#ifdef CONFIG_LTTNG_TOOLS_HAVE_UST
+#include <ust/lttng-ust-abi.h>
+#else
+#include "lttng-ust-abi.h"
+#endif
+
 
 #include "trace-kernel.h"
+#include "trace-ust.h"
 
 int context_kernel_add(struct ltt_kernel_session *ksession,
                struct lttng_event_context *ctx, char *event_name, char *channel_name);
+int context_ust_add(struct ltt_ust_session *ustsession,
+               struct lttng_event_context *ctx, char *event_name, char *channel_name);
 
 #endif /* _LTT_CONTEXT_H */
index c12e385b31015bd41207947d42a807db22d75a92..eef0039d633c30c39d0127378809b3aca1a58bcb 100644 (file)
 
 #include <errno.h>
 #include <urcu/list.h>
+#include <string.h>
 
 #include <lttng/lttng.h>
 #include <lttng-sessiond-comm.h>
 #include <lttngerr.h>
 
+#ifdef CONFIG_LTTNG_TOOLS_HAVE_UST
+#include <ust/lttng-ust-ctl.h>
+#else
+#include "lttng-ust-ctl.h"
+#endif
+
 #include "channel.h"
 #include "event.h"
 #include "kernel-ctl.h"
@@ -229,3 +236,77 @@ int event_kernel_enable_all(struct ltt_kernel_session *ksession,
 end:
        return ret;
 }
+
+/*
+ * Enable UST tracepoint event for a channel from a UST session.
+ */
+int event_ust_enable_tracepoint(struct ltt_ust_session *ustsession,
+               struct ltt_ust_channel *ustchan, struct lttng_event *event)
+{
+       int ret;
+       struct ltt_ust_event *ustevent;
+       struct lttng_ust_event lttngustevent;
+       struct object_data *object_event;
+
+       ustevent = trace_ust_get_event_by_name(event->name, ustchan);
+       if (ustevent == NULL) {
+               ustevent = trace_ust_create_event(event);
+               if (ustevent == NULL) {
+                       ret = -1;
+                       goto end;
+               }
+               strncpy(lttngustevent.name, event->name,
+                       LTTNG_UST_SYM_NAME_LEN);
+               lttngustevent.name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+               /* TODO: adjust to other instrumentation types */
+               lttngustevent.instrumentation = LTTNG_UST_TRACEPOINT;
+               ret = ustctl_create_event(ustsession->sock, &lttngustevent,
+                       ustchan->obj, &object_event);
+               if (ret < 0) {
+                       if (ret == -EEXIST) {
+                               ret = LTTCOMM_KERN_EVENT_EXIST;
+                       } else {
+                               ret = LTTCOMM_KERN_ENABLE_FAIL;
+                       }
+                       goto end;
+               }
+               ustevent->obj = object_event;
+               ustevent->handle = object_event->handle;
+               ustevent->enabled = 1;
+               /* Add event to event list */
+               cds_list_add(&ustevent->list, &ustchan->events.head);
+               ustchan->events.count++;
+       } else if (ustevent->enabled == 0) {
+               ret = ustctl_enable(ustsession->sock, ustevent->obj);
+               if (ret < 0) {
+                       ret = LTTCOMM_KERN_ENABLE_FAIL;
+                       goto end;
+               }
+               ustevent->enabled = 1;
+       }
+       ret = LTTCOMM_OK;
+end:
+       return ret;
+}
+
+int event_ust_disable_tracepoint(struct ltt_ust_session *ustsession,
+               struct ltt_ust_channel *ustchan, char *event_name)
+{
+       int ret;
+       struct ltt_ust_event *ustevent;
+
+       ustevent = trace_ust_get_event_by_name(event_name, ustchan);
+       if (ustevent == NULL) {
+               ret = LTTCOMM_NO_EVENT;
+               goto end;
+       }
+       ret = ustctl_disable(ustsession->sock, ustevent->obj);
+       if (ret < 0) {
+               ret = LTTCOMM_UST_ENABLE_FAIL;
+               goto end;
+       }
+       ustevent->enabled = 0;
+       ret = LTTCOMM_OK;
+end:
+       return ret;
+}
index 38768c51a9a66d242c754b1efc684de80ee6202e..879ae659c2cd34743a1e6e3357e4c4451586d5d1 100644 (file)
@@ -40,4 +40,9 @@ int event_kernel_enable_all_syscalls(struct ltt_kernel_session *ksession,
 int event_kernel_enable_all(struct ltt_kernel_session *ksession,
                struct ltt_kernel_channel *kchan, int kernel_tracer_fd);
 
+int event_ust_enable_tracepoint(struct ltt_ust_session *ustsession,
+               struct ltt_ust_channel *ustchan, struct lttng_event *event);
+int event_ust_disable_tracepoint(struct ltt_ust_session *ustsession,
+               struct ltt_ust_channel *ustchan, char *event_name);
+
 #endif /* _LTT_EVENT_H */
index 303493eeb4e1404ea4241b7054c9f138813ab475..da2bfb942a111844379bad1ff7d6b8b5eed55238 100644 (file)
@@ -111,6 +111,8 @@ struct lttng_ust_context {
 /* Event and Channel FD commands */
 #define LTTNG_UST_CONTEXT                      \
        _UST_CMDW(0x70, struct lttng_ust_context)
+#define LTTNG_UST_FLUSH_BUFFER                 \
+       _UST_CMD(0x71)
 
 /* Event, Channel and Session commands */
 #define LTTNG_UST_ENABLE                       _UST_CMD(0x80)
diff --git a/ltt-sessiond/lttng-ust-ctl.h b/ltt-sessiond/lttng-ust-ctl.h
new file mode 100644 (file)
index 0000000..f3859b8
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
+ *                      Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; only version 2
+ * of the License.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef _LTTNG_UST_CTL_H
+#define _LTTNG_UST_CTL_H
+
+/*
+ * ust-ctl stub API when UST is not present.
+*/
+
+#include "lttng-ust-abi.h"
+#include <errno.h>
+
+/*
+ * Tracer channel attributes.
+ */
+struct lttng_ust_channel_attr {
+       int overwrite;                          /* 1: overwrite, 0: discard */
+       uint64_t subbuf_size;                   /* bytes */
+       uint64_t num_subbuf;                    /* power of 2 */
+       unsigned int switch_timer_interval;     /* usec */
+       unsigned int read_timer_interval;       /* usec */
+       enum lttng_ust_output output;           /* splice, mmap */
+};
+
+struct object_data {
+       int handle;
+       int shm_fd;
+       int wait_fd;
+       uint64_t memory_map_size;
+};
+
+static inline
+int ustctl_register_done(int sock)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_create_session(int sock)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_open_metadata(int sock, int session_handle,
+               struct lttng_ust_channel_attr *chops,
+               struct object_data **metadata_data)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_create_channel(int sock, int session_handle,
+               struct lttng_ust_channel_attr *chops,
+               struct object_data **channel_data)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_create_stream(int sock, struct object_data *channel_data,
+               struct object_data **stream_data)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_create_event(int sock, struct lttng_ust_event *ev,
+               struct object_data *channel_data,
+               struct object_data **event_data)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_add_context(int sock, struct lttng_ust_context *ctx,
+               struct object_data *obj_data,
+               struct object_data **context_data)
+{
+       return -ENOSYS;
+}
+
+static inline
+int ustctl_enable(int sock, struct object_data *object)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_disable(int sock, struct object_data *object)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_start_session(int sock, int handle)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_stop_session(int sock, int handle)
+{
+       return -ENOSYS;
+}
+
+static inline
+int ustctl_tracepoint_list(int sock)   /* not implemented yet */
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_tracer_version(int sock, struct lttng_ust_tracer_version *v)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_wait_quiescent(int sock)
+{
+       return -ENOSYS;
+}
+
+/* Flush each buffers in this channel */
+static inline
+int ustctl_flush_buffer(int sock, struct object_data *channel_data)
+{
+       return -ENOSYS;
+}
+
+/* not implemented yet */
+struct lttng_ust_calibrate;
+static inline
+int ustctl_calibrate(int sock, struct lttng_ust_calibrate *calibrate)
+{
+       return -ENOSYS;
+}
+
+/*
+ * Map channel shm_handle and add streams. Typically performed by the
+ * consumer to map the objects into its memory space.
+ */
+static inline
+struct shm_handle *ustctl_map_channel(struct object_data *chan_data)
+{
+       return NULL;
+}
+static inline
+int ustctl_add_stream(struct shm_handle *shm_handle,
+               struct object_data *stream_data)
+{
+       return -ENOSYS;
+}
+/*
+ * Note: the object_data from which the shm_handle is derived can only
+ * be released after unmapping the handle.
+ */
+static inline
+void ustctl_unmap_channel(struct shm_handle *shm_handle)
+{
+}
+
+/* Buffer operations */
+
+struct shm_handle;
+struct lib_ring_buffer;
+
+/* Open/close stream buffers for read */
+static inline
+struct lib_ring_buffer *ustctl_open_stream_read(struct shm_handle *handle,
+               int cpu)
+{
+       return NULL;
+}
+static inline
+void ustctl_close_stream_read(struct shm_handle *handle,
+                struct lib_ring_buffer *buf)
+{
+}
+
+/* For mmap mode, readable without "get" operation */
+static inline
+int ustctl_get_mmap_len(struct shm_handle *handle,
+               struct lib_ring_buffer *buf,
+               unsigned long *len)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_get_max_subbuf_size(struct shm_handle *handle,
+               struct lib_ring_buffer *buf,
+               unsigned long *len)
+{
+       return -ENOSYS;
+}
+
+/*
+ * For mmap mode, operate on the current packet (between get/put or
+ * get_next/put_next).
+ */
+static inline
+void *ustctl_get_mmap_base(struct shm_handle *handle,
+               struct lib_ring_buffer *buf)
+{
+       return NULL;
+}
+static inline
+int ustctl_get_mmap_read_offset(struct shm_handle *handle,
+               struct lib_ring_buffer *buf, unsigned long *off)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_get_subbuf_size(struct shm_handle *handle,
+               struct lib_ring_buffer *buf, unsigned long *len)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_get_padded_subbuf_size(struct shm_handle *handle,
+               struct lib_ring_buffer *buf, unsigned long *len)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_get_next_subbuf(struct shm_handle *handle,
+               struct lib_ring_buffer *buf)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_put_next_subbuf(struct shm_handle *handle,
+               struct lib_ring_buffer *buf)
+{
+       return -ENOSYS;
+}
+
+/* snapshot */
+
+static inline
+int ustctl_snapshot(struct shm_handle *handle,
+               struct lib_ring_buffer *buf)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_snapshot_get_consumed(struct shm_handle *handle,
+               struct lib_ring_buffer *buf, unsigned long *pos)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_snapshot_get_produced(struct shm_handle *handle,
+               struct lib_ring_buffer *buf, unsigned long *pos)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_get_subbuf(struct shm_handle *handle,
+               struct lib_ring_buffer *buf, unsigned long *pos)
+{
+       return -ENOSYS;
+}
+static inline
+int ustctl_put_subbuf(struct shm_handle *handle,
+               struct lib_ring_buffer *buf)
+{
+       return -ENOSYS;
+}
+
+/* Release object created by members of this API */
+static inline
+void release_object(int sock, struct object_data *data)
+{
+}
+
+#endif /* _LTTNG_UST_CTL_H */
index ddf5acd2f116664b2777421338033a0c64fc0aa4..c288afbb049f4a078f049756fce9c20094f1d705 100644 (file)
 #include <lttng-consumerd.h>
 #include <lttng-sessiond-comm.h>
 #include <lttng/lttng-consumer.h>
+
+#ifdef CONFIG_LTTNG_TOOLS_HAVE_UST
+#include <ust/lttng-ust-ctl.h>
+#else
+#include "lttng-ust-ctl.h"
+#endif
+
+
 #include <lttngerr.h>
 
 #include "channel.h"
@@ -413,7 +421,7 @@ static void clean_command_ctx(struct command_ctx **cmd_ctx)
 /*
  * Send all stream fds of kernel channel to the consumer.
  */
-static int send_consumer_channel_streams(struct consumer_data *consumer_data,
+static int send_kconsumer_channel_streams(struct consumer_data *consumer_data,
                int sock, struct ltt_kernel_channel *channel)
 {
        int ret;
@@ -428,7 +436,7 @@ static int send_consumer_channel_streams(struct consumer_data *consumer_data,
        lkm.u.channel.channel_key = channel->fd;
        lkm.u.channel.max_sb_size = channel->channel->attr.subbuf_size;
        lkm.u.channel.mmap_len = 0;     /* for kernel */
-       DBG("Sending channel %d to consumer", lkm.u.stream.stream_key);
+       DBG("Sending channel %d to consumer", lkm.u.channel.channel_key);
        ret = lttcomm_send_unix_sock(sock, &lkm, sizeof(lkm));
        if (ret < 0) {
                perror("send consumer channel");
@@ -469,10 +477,84 @@ error:
        return ret;
 }
 
+/*
+ * Send all stream fds of UST channel to the consumer.
+ */
+static int send_ustconsumer_channel_streams(struct consumer_data *consumer_data,
+               int sock, struct ltt_ust_channel *channel)
+{
+       int ret, fds[2];
+       struct ltt_ust_stream *stream;
+       struct lttcomm_consumer_msg lum;
+
+       DBG("Sending streams of channel %s to UST consumer",
+                       channel->name);
+
+       /* Send channel */
+       lum.cmd_type = LTTNG_CONSUMER_ADD_CHANNEL;
+       /*
+        * We need to keep shm_fd open to make sure this key stays
+        * unique within the session daemon.
+        */
+       lum.u.channel.channel_key = channel->obj->shm_fd;
+       lum.u.channel.max_sb_size = channel->attr.subbuf_size;
+       lum.u.channel.mmap_len = channel->obj->memory_map_size;
+       DBG("Sending channel %d to consumer", lum.u.channel.channel_key);
+       ret = lttcomm_send_unix_sock(sock, &lum, sizeof(lum));
+       if (ret < 0) {
+               perror("send consumer channel");
+               goto error;
+       }
+       fds[0] = channel->obj->shm_fd;
+       fds[1] = channel->obj->wait_fd;
+       ret = lttcomm_send_fds_unix_sock(sock, fds, 2);
+       if (ret < 0) {
+               perror("send consumer channel ancillary data");
+               goto error;
+       }
+
+       /* Send streams */
+       cds_list_for_each_entry(stream, &channel->stream_list.head, list) {
+               int fds[2];
+
+               if (!stream->obj->shm_fd) {
+                       continue;
+               }
+               lum.cmd_type = LTTNG_CONSUMER_ADD_STREAM;
+               lum.u.stream.channel_key = channel->obj->shm_fd;
+               lum.u.stream.stream_key = stream->obj->shm_fd;
+               lum.u.stream.state = LTTNG_CONSUMER_ACTIVE_STREAM;
+               lum.u.stream.output = channel->attr.output;
+               lum.u.stream.mmap_len = stream->obj->memory_map_size;
+               strncpy(lum.u.stream.path_name, stream->pathname, PATH_MAX - 1);
+               lum.u.stream.path_name[PATH_MAX - 1] = '\0';
+               DBG("Sending stream %d to consumer", lum.u.stream.stream_key);
+               ret = lttcomm_send_unix_sock(sock, &lum, sizeof(lum));
+               if (ret < 0) {
+                       perror("send consumer stream");
+                       goto error;
+               }
+               fds[0] = stream->obj->shm_fd;
+               fds[1] = stream->obj->wait_fd;
+               ret = lttcomm_send_fds_unix_sock(sock, fds, 2);
+               if (ret < 0) {
+                       perror("send consumer stream ancillary data");
+                       goto error;
+               }
+       }
+
+       DBG("consumer channel streams sent");
+
+       return 0;
+
+error:
+       return ret;
+}
+
 /*
  * Send all stream fds of the kernel session to the consumer.
  */
-static int send_consumer_session_streams(struct consumer_data *consumer_data,
+static int send_kconsumer_session_streams(struct consumer_data *consumer_data,
                struct ltt_kernel_session *session)
 {
        int ret;
@@ -482,7 +564,7 @@ static int send_consumer_session_streams(struct consumer_data *consumer_data,
 
        DBG("Sending metadata stream fd");
 
-       /* Extra protection. It's NOT suppose to be set to 0 at this point */
+       /* Extra protection. It's NOT supposed to be set to 0 at this point */
        if (session->consumer_fd == 0) {
                session->consumer_fd = consumer_data->cmd_sock;
        }
@@ -523,7 +605,86 @@ static int send_consumer_session_streams(struct consumer_data *consumer_data,
        }
 
        cds_list_for_each_entry(chan, &session->channel_list.head, list) {
-               ret = send_consumer_channel_streams(consumer_data, sock, chan);
+               ret = send_kconsumer_channel_streams(consumer_data, sock, chan);
+               if (ret < 0) {
+                       goto error;
+               }
+       }
+
+       DBG("consumer fds (metadata and channel streams) sent");
+
+       return 0;
+
+error:
+       return ret;
+}
+
+/*
+ * Send all stream fds of the UST session to the consumer.
+ */
+static int send_ustconsumer_session_streams(struct consumer_data *consumer_data,
+               struct ltt_ust_session *session)
+{
+       int ret;
+       struct ltt_ust_channel *chan;
+       struct lttcomm_consumer_msg lum;
+       int sock = session->consumer_fd;
+
+       DBG("Sending metadata stream fd");
+
+       /* Extra protection. It's NOT supposed to be set to 0 at this point */
+       if (session->consumer_fd == 0) {
+               session->consumer_fd = consumer_data->cmd_sock;
+       }
+
+       if (session->metadata->obj->shm_fd != 0) {
+               int fds[2];
+
+               /* Send metadata channel fd */
+               lum.cmd_type = LTTNG_CONSUMER_ADD_CHANNEL;
+               lum.u.channel.channel_key = session->metadata->obj->shm_fd;
+               lum.u.channel.max_sb_size = session->metadata->attr.subbuf_size;
+               lum.u.channel.mmap_len = 0;     /* for kernel */
+               DBG("Sending metadata channel %d to consumer", lum.u.stream.stream_key);
+               ret = lttcomm_send_unix_sock(sock, &lum, sizeof(lum));
+               if (ret < 0) {
+                       perror("send consumer channel");
+                       goto error;
+               }
+               fds[0] = session->metadata->obj->shm_fd;
+               fds[1] = session->metadata->obj->wait_fd;
+               ret = lttcomm_send_fds_unix_sock(sock, fds, 2);
+               if (ret < 0) {
+                       perror("send consumer metadata channel");
+                       goto error;
+               }
+
+               /* Send metadata stream fd */
+               lum.cmd_type = LTTNG_CONSUMER_ADD_STREAM;
+               lum.u.stream.channel_key = session->metadata->obj->shm_fd;
+               lum.u.stream.stream_key = session->metadata->stream_obj->shm_fd;
+               lum.u.stream.state = LTTNG_CONSUMER_ACTIVE_STREAM;
+               lum.u.stream.output = DEFAULT_UST_CHANNEL_OUTPUT;
+               lum.u.stream.mmap_len = session->metadata->stream_obj->memory_map_size;
+               strncpy(lum.u.stream.path_name, session->metadata->pathname, PATH_MAX - 1);
+               lum.u.stream.path_name[PATH_MAX - 1] = '\0';
+               DBG("Sending metadata stream %d to consumer", lum.u.stream.stream_key);
+               ret = lttcomm_send_unix_sock(sock, &lum, sizeof(lum));
+               if (ret < 0) {
+                       perror("send consumer metadata stream");
+                       goto error;
+               }
+               fds[0] = session->metadata->stream_obj->shm_fd;
+               fds[1] = session->metadata->stream_obj->wait_fd;
+               ret = lttcomm_send_fds_unix_sock(sock, fds, 2);
+               if (ret < 0) {
+                       perror("send consumer stream");
+                       goto error;
+               }
+       }
+
+       cds_list_for_each_entry(chan, &session->channels.head, list) {
+               ret = send_ustconsumer_channel_streams(consumer_data, sock, chan);
                if (ret < 0) {
                        goto error;
                }
@@ -642,7 +803,7 @@ error:
  *
  * Useful for CPU hotplug feature.
  */
-static int update_stream(struct consumer_data *consumer_data, int fd)
+static int update_kernel_stream(struct consumer_data *consumer_data, int fd)
 {
        int ret = 0;
        struct ltt_session *session;
@@ -678,7 +839,7 @@ static int update_stream(struct consumer_data *consumer_data, int fd)
                                 * stream fds.
                                 */
                                if (session->kernel_session->consumer_fds_sent == 1) {
-                                       ret = send_consumer_channel_streams(consumer_data,
+                                       ret = send_kconsumer_channel_streams(consumer_data,
                                                        session->kernel_session->consumer_fd, channel);
                                        if (ret < 0) {
                                                goto error;
@@ -778,7 +939,7 @@ static void *thread_manage_kernel(void *data)
                                 * kernel session and updating the kernel consumer
                                 */
                                if (revents & LPOLLIN) {
-                                       ret = update_stream(&kconsumer_data, pollfd);
+                                       ret = update_kernel_stream(&kconsumer_data, pollfd);
                                        if (ret < 0) {
                                                continue;
                                        }
@@ -1622,7 +1783,7 @@ static int init_kernel_tracing(struct ltt_kernel_session *session)
                        session->consumer_fd = kconsumer_data.cmd_sock;
                }
 
-               ret = send_consumer_session_streams(&kconsumer_data, session);
+               ret = send_kconsumer_session_streams(&kconsumer_data, session);
                if (ret < 0) {
                        ret = LTTCOMM_KERN_CONSUMER_FAIL;
                        goto error;
@@ -1635,6 +1796,36 @@ error:
        return ret;
 }
 
+/*
+ * Init tracing by creating trace directory and sending fds ust consumer.
+ */
+static int init_ust_tracing(struct ltt_ust_session *session)
+{
+       int ret = 0;
+
+       if (session->consumer_fds_sent == 0) {
+               /*
+                * Assign default ust consumer socket if no consumer assigned to the
+                * ust session. At this point, it's NOT suppose to be 0 but this is
+                * an extra security check.
+                */
+               if (session->consumer_fd == 0) {
+                       session->consumer_fd = ustconsumer_data.cmd_sock;
+               }
+
+               ret = send_ustconsumer_session_streams(&ustconsumer_data, session);
+               if (ret < 0) {
+                       ret = LTTCOMM_UST_CONSUMER_FAIL;
+                       goto error;
+               }
+
+               session->consumer_fds_sent = 1;
+       }
+
+error:
+       return ret;
+}
+
 /*
  * Create an UST session and add it to the session ust list.
  */
@@ -1677,11 +1868,13 @@ static int create_ust_session(struct ltt_session *session,
        }
 
        /* Create session on the UST tracer */
-       ret = ustctl_create_session(app->sock, lus);
+       ret = ustctl_create_session(app->sock);
        if (ret < 0) {
                ret = LTTCOMM_UST_SESS_FAIL;
                goto error;
        }
+       lus->handle = ret;
+       lus->sock = app->sock;
 
        cds_list_add(&lus->list, &session->ust_session_list.head);
        session->ust_session_list.count++;
@@ -1980,10 +2173,12 @@ static int cmd_disable_event(struct ltt_session *session, int domain,
                char *channel_name, char *event_name)
 {
        int ret;
-       struct ltt_kernel_channel *kchan;
 
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
+       {
+               struct ltt_kernel_channel *kchan;
+
                kchan = trace_kernel_get_channel_by_name(channel_name,
                                session->kernel_session);
                if (kchan == NULL) {
@@ -1998,8 +2193,34 @@ static int cmd_disable_event(struct ltt_session *session, int domain,
 
                kernel_wait_quiescent(kernel_tracer_fd);
                break;
+       }
+       case LTTNG_DOMAIN_UST:
+       {
+               struct ltt_ust_session *ustsession;
+
+               cds_list_for_each_entry(ustsession, &session->ust_session_list.head, list) {
+                       struct ltt_ust_channel *ustchan;
+
+                       ustchan = trace_ust_get_channel_by_name(channel_name,
+                                       ustsession);
+                       if (ustchan == NULL) {
+                               ret = LTTCOMM_KERN_CHAN_NOT_FOUND;
+                               goto error;
+                       }
+                       ret = event_ust_disable_tracepoint(ustsession, ustchan, event_name);
+                       if (ret != LTTCOMM_OK) {
+                               goto error;
+                       }
+
+                       ustctl_wait_quiescent(ustsession->sock);
+               }
+               break;
+       }
+       case LTTNG_DOMAIN_UST_EXEC_NAME:
+       case LTTNG_DOMAIN_UST_PID:
+       case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
        default:
-               /* TODO: Userspace tracing */
+               /* TODO: Other UST domains */
                ret = LTTCOMM_NOT_IMPLEMENTED;
                goto error;
        }
@@ -2063,10 +2284,23 @@ static int cmd_add_context(struct ltt_session *session, int domain,
                if (ret != LTTCOMM_OK) {
                        goto error;
                }
+               break;
+       case LTTNG_DOMAIN_UST:
+       {
+               struct ltt_ust_session *ustsession;
 
+               cds_list_for_each_entry(ustsession, &session->ust_session_list.head, list) {
+                       /* Add UST context to UST tracer */
+                       ret = context_ust_add(ustsession, ctx,
+                                       event_name, channel_name);
+                       if (ret != LTTCOMM_OK) {
+                               goto error;
+                       }
+               }
                break;
+       }
        default:
-               /* TODO: Userspace tracing */
+               /* TODO: UST other domains */
                ret = LTTCOMM_NOT_IMPLEMENTED;
                goto error;
        }
@@ -2084,11 +2318,13 @@ static int cmd_enable_event(struct ltt_session *session, int domain,
                char *channel_name, struct lttng_event *event)
 {
        int ret;
-       struct ltt_kernel_channel *kchan;
        struct lttng_channel *attr;
 
        switch (domain) {
        case LTTNG_DOMAIN_KERNEL:
+       {
+               struct ltt_kernel_channel *kchan;
+
                kchan = trace_kernel_get_channel_by_name(channel_name,
                                session->kernel_session);
                if (kchan == NULL) {
@@ -2123,8 +2359,54 @@ static int cmd_enable_event(struct ltt_session *session, int domain,
 
                kernel_wait_quiescent(kernel_tracer_fd);
                break;
+       }
+       case LTTNG_DOMAIN_UST:
+       {
+               struct ltt_ust_session *ustsession;
+
+               cds_list_for_each_entry(ustsession, &session->ust_session_list.head, list) {
+                       struct ltt_ust_channel *ustchan;
+
+                       ustchan = trace_ust_get_channel_by_name(channel_name,
+                                       ustsession);
+                       if (ustchan == NULL) {
+                               attr = channel_new_default_attr(domain);
+                               if (attr == NULL) {
+                                       ret = LTTCOMM_FATAL;
+                                       goto error;
+                               }
+                               snprintf(attr->name, NAME_MAX, "%s", channel_name);
+
+                               ret = channel_ust_create(ustsession,
+                                               attr, ustsession->sock);
+                               if (ret != LTTCOMM_OK) {
+                                       goto error;
+                               }
+                       }
+
+                       /* Get the newly created ust channel pointer */
+                       ustchan = trace_ust_get_channel_by_name(channel_name,
+                                       ustsession);
+                       if (ustchan == NULL) {
+                               /* This sould not happen... */
+                               ret = LTTCOMM_FATAL;
+                               goto error;
+                       }
+
+                       ret = event_ust_enable_tracepoint(ustsession, ustchan, event);
+                       if (ret != LTTCOMM_OK) {
+                               goto error;
+                       }
+
+                       ustctl_wait_quiescent(ustsession->sock);
+               }
+               break;
+       }
+       case LTTNG_DOMAIN_UST_EXEC_NAME:
+       case LTTNG_DOMAIN_UST_PID:
+       case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
        default:
-               /* TODO: Userspace tracing */
+               /* TODO: UST other domains */
                ret = LTTCOMM_NOT_IMPLEMENTED;
                goto error;
        }
@@ -2241,14 +2523,16 @@ error:
 static int cmd_start_trace(struct ltt_session *session)
 {
        int ret;
-       struct ltt_kernel_channel *kchan;
        struct ltt_kernel_session *ksession;
+       struct ltt_ust_session *ustsession;
 
        /* Short cut */
        ksession = session->kernel_session;
 
        /* Kernel tracing */
        if (ksession != NULL) {
+               struct ltt_kernel_channel *kchan;
+
                /* Open kernel metadata */
                if (ksession->metadata == NULL) {
                        ret = kernel_open_metadata(ksession, ksession->trace_path);
@@ -2299,7 +2583,101 @@ static int cmd_start_trace(struct ltt_session *session)
                kernel_wait_quiescent(kernel_tracer_fd);
        }
 
-       /* TODO: Start all UST traces */
+       /* Start all UST traces */
+       cds_list_for_each_entry(ustsession, &session->ust_session_list.head, list) {
+               struct ltt_ust_channel *ustchan;
+
+               /* Open kernel metadata */
+               if (ustsession->metadata == NULL) {
+                       struct lttng_ust_channel_attr ustattr;
+
+                       /* Allocate UST metadata */
+                       ustsession->metadata = trace_ust_create_metadata(ustsession->path);
+                       if (ustsession->metadata == NULL) {
+                               ret = LTTCOMM_UST_META_FAIL;
+                               goto error;
+                       }
+
+                       ustattr.overwrite = ustsession->metadata->attr.overwrite;
+                       ustattr.subbuf_size = ustsession->metadata->attr.subbuf_size;
+                       ustattr.num_subbuf = ustsession->metadata->attr.num_subbuf;
+                       ustattr.switch_timer_interval = ustsession->metadata->attr.switch_timer_interval;
+                       ustattr.read_timer_interval = ustsession->metadata->attr.read_timer_interval;
+                       ustattr.output = ustsession->metadata->attr.output;
+                       
+                       /* UST tracer metadata creation */
+                       ret = ustctl_open_metadata(ustsession->sock,
+                               ustsession->handle, &ustattr,
+                               &ustsession->metadata->obj);
+                       if (ret < 0) {
+                               ret = LTTCOMM_UST_META_FAIL;
+                               goto error;
+                       }
+               }
+
+               /* Open UST metadata stream */
+               if (ustsession->metadata->stream_obj == NULL) {
+                       ret = ustctl_create_stream(ustsession->sock,
+                               ustsession->metadata->obj,
+                               &ustsession->metadata->stream_obj);
+                       if (ret < 0) {
+                               ERR("UST create metadata stream failed");
+                               ret = LTTCOMM_UST_STREAM_FAIL;
+                               goto error;
+                       }
+                       ret = asprintf(&ustsession->metadata->pathname, "%s/%s",
+                                       ustsession->path, "metadata");
+                       if (ret < 0) {
+                               perror("asprintf UST create stream");
+                               goto error;
+                       }
+               }
+
+               /* For each channel */
+               cds_list_for_each_entry(ustchan, &ustsession->channels.head, list) {
+                       if (ustchan->stream_count == 0) {
+                               struct ltt_ust_stream *ustream;
+
+                               ustream = zmalloc(sizeof(*ustream));
+                               if (!ustream) {
+                                       ret = LTTCOMM_UST_STREAM_FAIL;
+                                       goto error;
+                               }
+                               ret = ustctl_create_stream(ustsession->sock,
+                                       ustchan->obj, &ustream->obj);
+                               if (ret < 0) {
+                                       ret = LTTCOMM_UST_STREAM_FAIL;
+                                       goto error;
+                               }
+                               ret = asprintf(&ustream->pathname, "%s/%s_%d",
+                                               ustchan->trace_path, ustchan->name,
+                                               ustchan->stream_count);
+                               if (ret < 0) {
+                                       perror("asprintf UST create stream");
+                                       goto error;
+                               }
+                               cds_list_add(&ustream->list, &ustchan->stream_list.head);
+                               ustchan->stream_count++;
+                       }
+               }
+
+               /* Setup UST consumer socket and send fds to it */
+               ret = init_ust_tracing(ustsession);
+               if (ret < 0) {
+                       ret = LTTCOMM_UST_START_FAIL;
+                       goto error;
+               }
+
+               /* This start the UST tracing */
+               ret = ustctl_start_session(ustsession->sock, ustsession->handle);
+               if (ret < 0) {
+                       ret = LTTCOMM_UST_START_FAIL;
+                       goto error;
+               }
+
+               /* Quiescent wait after starting trace */
+               ustctl_wait_quiescent(ustsession->sock);
+       }
 
        ret = LTTCOMM_OK;
 
@@ -2315,6 +2693,8 @@ static int cmd_stop_trace(struct ltt_session *session)
        int ret;
        struct ltt_kernel_channel *kchan;
        struct ltt_kernel_session *ksession;
+       struct ltt_ust_session *ustsession;
+       struct ltt_ust_channel *ustchan;
 
        /* Short cut */
        ksession = session->kernel_session;
@@ -2345,7 +2725,30 @@ static int cmd_stop_trace(struct ltt_session *session)
                kernel_wait_quiescent(kernel_tracer_fd);
        }
 
-       /* TODO : User-space tracer */
+       /* Stop each UST session */
+       DBG("Stop UST tracing");
+       cds_list_for_each_entry(ustsession, &session->ust_session_list.head, list) {
+               /* Flush all buffers before stopping */
+               ret = ustctl_flush_buffer(ustsession->sock, ustsession->metadata->obj);
+               if (ret < 0) {
+                       ERR("UST metadata flush failed");
+               }
+
+               cds_list_for_each_entry(ustchan, &ustsession->channels.head, list) {
+                       ret = ustctl_flush_buffer(ustsession->sock, ustchan->obj);
+                       if (ret < 0) {
+                               ERR("UST flush buffer error");
+                       }
+               }
+
+               ret = ustctl_stop_session(ustsession->sock, ustsession->handle);
+               if (ret < 0) {
+                       ret = LTTCOMM_KERN_STOP_FAIL;
+                       goto error;
+               }
+
+               ustctl_wait_quiescent(ustsession->sock);
+       }
 
        ret = LTTCOMM_OK;
 
@@ -2515,6 +2918,8 @@ static ssize_t cmd_list_channels(struct ltt_session *session,
 
        list_lttng_channels(session, *channels);
 
+       /* TODO UST support */
+
        return nb_chan;
 
 error:
@@ -2659,7 +3064,10 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                        pthread_mutex_unlock(&kconsumer_data.pid_mutex);
                }
                break;
+       case LTTNG_DOMAIN_UST:
+       case LTTNG_DOMAIN_UST_EXEC_NAME:
        case LTTNG_DOMAIN_UST_PID:
+       case LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN:
        {
                struct ltt_ust_session *usess;
 
@@ -2674,11 +3082,22 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
                                        goto error;
                                }
                        }
+                       /* Start the kernel consumer daemon */
+                       pthread_mutex_lock(&ustconsumer_data.pid_mutex);
+                       if (ustconsumer_data.pid == 0 &&
+                                       cmd_ctx->lsm->cmd_type != LTTNG_REGISTER_CONSUMER) {
+                               pthread_mutex_unlock(&ustconsumer_data.pid_mutex);
+                               ret = start_consumerd(&ustconsumer_data);
+                               if (ret < 0) {
+                                       ret = LTTCOMM_KERN_CONSUMER_FAIL;
+                                       goto error;
+                               }
+                       }
+                       pthread_mutex_unlock(&ustconsumer_data.pid_mutex);
                }
                break;
        }
        default:
-               /* TODO Userspace tracer */
                break;
        }
 
@@ -2708,7 +3127,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
        }
        case LTTNG_DISABLE_ALL_EVENT:
        {
-               DBG("Disabling all kernel event");
+               DBG("Disabling all events");
 
                ret = cmd_disable_event_all(cmd_ctx->session, cmd_ctx->lsm->domain.type,
                                cmd_ctx->lsm->u.disable.channel_name);
@@ -2729,7 +3148,7 @@ static int process_client_msg(struct command_ctx *cmd_ctx)
        }
        case LTTNG_ENABLE_ALL_EVENT:
        {
-               DBG("Enabling all kernel event");
+               DBG("Enabling all events");
 
                ret = cmd_enable_event_all(cmd_ctx->session, cmd_ctx->lsm->domain.type,
                                cmd_ctx->lsm->u.enable.channel_name,
index 2bf2f03c9e99c691b8363b3881e89efcc17c60d8..bcea65148be4d5994f0d5eec805e40449555cddb 100644 (file)
@@ -44,6 +44,10 @@ struct ltt_kernel_channel_list {
 struct ltt_kernel_event {
        int fd;
        int enabled;
+       /*
+        * TODO: need internal representation to support more than a
+        * single context.
+        */
        struct lttng_kernel_context *ctx;
        struct lttng_kernel_event *event;
        struct cds_list_head list;
@@ -56,6 +60,10 @@ struct ltt_kernel_channel {
        char *pathname;
        unsigned int stream_count;
        unsigned int event_count;
+       /*
+        * TODO: need internal representation to support more than a
+        * single context.
+        */
        struct lttng_kernel_context *ctx;
        struct lttng_channel *channel;
        struct ltt_kernel_event_list events_list;
index cf1642a6e9163a75f3ce9c4c7c478476304486ec..c2978894ede66ff5ff6b80c764b8ebd54422a7aa 100644 (file)
@@ -189,6 +189,7 @@ struct ltt_ust_channel *trace_ust_create_channel(struct lttng_channel *chan,
                perror("asprintf ust create channel");
                goto error;
        }
+       CDS_INIT_LIST_HEAD(&luc->stream_list.head);
 
        return luc;
 
@@ -270,7 +271,7 @@ struct ltt_ust_metadata *trace_ust_create_metadata(char *path)
 
        lum->handle = -1;
        /* Set metadata trace path */
-       ret = asprintf(&lum->trace_path, "%s/metadata", path);
+       ret = asprintf(&lum->pathname, "%s/metadata", path);
        if (ret < 0) {
                perror("asprintf ust metadata");
                goto error;
@@ -321,8 +322,7 @@ void trace_ust_destroy_metadata(struct ltt_ust_metadata *metadata)
        DBG("[trace] Destroy ust metadata %d", metadata->handle);
 
        /* Free attributes */
-       free(metadata->trace_path);
-
+       free(metadata->pathname);
        free(metadata);
 }
 
index abbf9a9d191a8498f1e714e4435fa4df50acda56..e2901a7fa346262eb72db2c96c854ea32f332b36 100644 (file)
@@ -50,6 +50,12 @@ struct ltt_ust_event_list {
        struct cds_list_head head;
 };
 
+/* UST Stream list */
+struct ltt_ust_stream_list {
+       unsigned int count;
+       struct cds_list_head head;
+};
+
 /* UST Channel list */
 struct ltt_ust_channel_list {
        unsigned int count;
@@ -60,9 +66,21 @@ struct ltt_ust_channel_list {
 struct ltt_ust_event {
        int handle;
        int enabled;
+       /*
+        * TODO: need internal representation to support more than a
+        * single context.
+        */
        struct lttng_ust_context ctx;
        struct lttng_ust_event attr;
        struct cds_list_head list;
+       struct object_data *obj;
+};
+
+/* UST stream */
+struct ltt_ust_stream {
+       struct object_data *obj;
+       struct cds_list_head list;
+       char *pathname;
 };
 
 /* UST channel */
@@ -71,29 +89,41 @@ struct ltt_ust_channel {
        int enabled;
        char name[LTTNG_UST_SYM_NAME_LEN];
        char trace_path[PATH_MAX];    /* Trace file path name */
+       /*
+        * TODO: need internal representation to support more than a
+        * single context.
+        */
        struct lttng_ust_context ctx;
        struct lttng_ust_channel attr;
        struct ltt_ust_event_list events;
        struct cds_list_head list;
+       struct object_data *obj;
+       unsigned int stream_count;
+       struct ltt_ust_stream_list stream_list;
 };
 
 /* UST Metadata */
 struct ltt_ust_metadata {
        int handle;
-       char *trace_path;             /* Trace file path name */
+       struct object_data *obj;
+       char *pathname;              /* Trace file path name */
        struct lttng_ust_channel attr;
+       struct object_data *stream_obj;
 };
 
 /* UST session */
 struct ltt_ust_session {
+       int sock;                     /* socket to send cmds to app */
        int handle;
        int enabled;
        int consumer_fds_sent;
+       int consumer_fd;
        char path[PATH_MAX];
        struct lttng_domain domain;
        struct ltt_ust_metadata *metadata;
        struct ltt_ust_channel_list channels;
        struct cds_list_head list;
+       struct object_data *obj;
 };
 
 #ifdef CONFIG_LTTNG_TOOLS_HAVE_UST
diff --git a/ltt-sessiond/ust-comm.c b/ltt-sessiond/ust-comm.c
deleted file mode 100644 (file)
index 4a54bf7..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C)  2011 - David Goulet <david.goulet@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <config.h>
-#include <stdlib.h>
-#include <lttngerr.h>
-#include <ust/lttng-ust-comm.h>
-#include "ust-comm.h"
-
-/*
- * Send msg containing a command to an UST application via sock and wait for
- * the reply. Caller must free() the reply structure sent back.
- *
- * Return the replied structure or NULL.
- */
-struct lttcomm_ust_reply *ustcomm_send_command(int sock,
-               struct lttcomm_ust_msg *msg)
-{
-       ssize_t len;
-       struct lttcomm_ust_reply *reply;
-
-       /* Extra safety */
-       if (msg == NULL || sock < 0) {
-               goto error;
-       }
-
-       DBG2("Sending UST command %d to sock %d", msg->cmd, sock);
-
-       /* Send UST msg */
-       len = ustcomm_send_unix_sock(sock, msg, sizeof(*msg));
-       if (len < 0) {
-               goto error;
-       }
-
-       reply = malloc(sizeof(struct lttcomm_ust_reply));
-       if (reply == NULL) {
-               perror("malloc ust reply");
-               goto error;
-       }
-
-       DBG2("Receiving UST reply on sock %d", sock);
-
-       /* Get UST reply */
-       len = ustcomm_recv_unix_sock(sock, reply, sizeof(*reply));
-       if (len < 0 || len < sizeof(*reply)) {
-               goto error;
-       }
-
-       return reply;
-
-error:
-       return NULL;
-}
diff --git a/ltt-sessiond/ust-comm.h b/ltt-sessiond/ust-comm.h
deleted file mode 100644 (file)
index f7a3951..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; only version 2 of the License.
- *
- * This program 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 General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#ifndef _LTT_UST_COMM_H
-#define _LTT_UST_COMM_H
-
-#include <lttng-sessiond-comm.h>
-
-struct lttcomm_ust_reply *ustcomm_send_command(int sock,
-               struct lttcomm_ust_msg *msg);
-
-#endif /* _LTT_UST_COMM_H */
diff --git a/ltt-sessiond/ust-ctl.c b/ltt-sessiond/ust-ctl.c
deleted file mode 100644 (file)
index 7f70b89..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; only version 2
- * of the License.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#define _GNU_SOURCE
-#include <config.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <ust/lttng-ust-comm.h>
-#include <lttngerr.h>
-
-#include "ust-comm.h"
-#include "ust-ctl.h"
-
-/*
- * Send registration done packet to the application.
- */
-int ustctl_register_done(int sock)
-{
-       struct lttcomm_ust_msg command;
-       struct lttcomm_ust_reply *reply;
-
-       DBG("Sending register done command to %d", sock);
-
-       command.cmd = LTTNG_UST_REGISTER_DONE;
-       command.handle = LTTNG_UST_ROOT_HANDLE;
-
-       reply = ustcomm_send_command(sock, &command);
-       if (reply == NULL) {
-               goto error;
-       }
-
-       if (reply->ret_code != USTCOMM_OK) {
-               DBG("Return code: %s", ustcomm_get_readable_code(reply->ret_code));
-               goto error;
-       }
-
-       return 0;
-
-error:
-       return -1;
-}
-
-/*
- * Create an UST session on the tracer.
- */
-int ustctl_create_session(int sock, struct ltt_ust_session *session)
-{
-       struct lttcomm_ust_msg command;
-       struct lttcomm_ust_reply *reply = NULL;
-
-       command.cmd = LTTNG_UST_SESSION;
-       command.handle = LTTNG_UST_ROOT_HANDLE;
-
-       reply = ustcomm_send_command(sock, &command);
-       if (reply == NULL) {
-               goto error;
-       }
-
-       if (reply->ret_code != USTCOMM_OK) {
-               DBG("Return code: %s", ustcomm_get_readable_code(reply->ret_code));
-               goto error;
-       }
-
-       /* Save session handle */
-       session->handle = reply->ret_val;
-       free(reply);
-
-       DBG2("ustctl create session command successful");
-       return 0;
-
-error:
-       free(reply);
-       return -1;
-}
-
-/*
- * Create UST channel to the tracer.
- */
-int ustctl_create_channel(int sock, struct ltt_ust_session *session,
-               struct lttng_channel *channel)
-{
-       struct lttcomm_ust_msg command;
-       struct lttcomm_ust_reply *reply = NULL;
-       struct ltt_ust_channel *uchan;
-
-       uchan = trace_ust_create_channel(channel, session->path);
-       if (uchan == NULL) {
-               goto error;
-       }
-
-       memset(&command, 0, sizeof(command));
-
-       command.cmd = LTTNG_UST_CHANNEL;
-       command.handle = session->handle;
-
-       /* Copy channel attributes to command */
-       memcpy(&command.u.channel, &uchan->attr, sizeof(command.u.channel));
-
-       reply = ustcomm_send_command(sock, &command);
-       if (reply == NULL) {
-               goto error;
-       }
-
-       if (reply->ret_code != USTCOMM_OK) {
-               DBG("Return code (%d): %s", reply->ret_code,
-                               ustcomm_get_readable_code(reply->ret_code));
-               goto error;
-       }
-
-       uchan->handle = reply->ret_val;
-
-       /* Add channel to session */
-       cds_list_add(&uchan->list, &session->channels.head);
-       session->channels.count++;
-
-       free(reply);
-
-       return 0;
-
-error:
-       free(reply);
-       return -1;
-}
-
-/*
- * Enable UST channel.
- */
-int ustctl_enable_channel(int sock, struct ltt_ust_session *session,
-               struct ltt_ust_channel *chan)
-{
-       struct lttcomm_ust_msg command;
-       struct lttcomm_ust_reply *reply = NULL;
-
-       memset(&command, 0, sizeof(command));
-
-       command.cmd = LTTNG_UST_ENABLE;
-       command.handle = chan->handle;
-
-       reply = ustcomm_send_command(sock, &command);
-       if (reply == NULL) {
-               goto error;
-       }
-
-       if (reply->ret_code != USTCOMM_OK) {
-               DBG("Return code (%d): %s", reply->ret_code,
-                               ustcomm_get_readable_code(reply->ret_code));
-               goto error;
-       } else if (reply->handle != chan->handle) {
-               ERR("Receive wrong handle from UST reply on enable channel");
-               goto error;
-       }
-
-       chan->enabled = 1;
-       free(reply);
-
-       DBG2("ustctl enable channel successful for sock %d", sock);
-       return 0;
-
-error:
-       free(reply);
-       return -1;
-}
-
-/*
- * Disable UST channel.
- */
-int ustctl_disable_channel(int sock, struct ltt_ust_session *session,
-               struct ltt_ust_channel *chan)
-{
-       struct lttcomm_ust_msg command;
-       struct lttcomm_ust_reply *reply = NULL;
-
-       memset(&command, 0, sizeof(command));
-
-       command.cmd = LTTNG_UST_DISABLE;
-       command.handle = chan->handle;
-
-       reply = ustcomm_send_command(sock, &command);
-       if (reply == NULL) {
-               goto error;
-       }
-
-       if (reply->ret_code != USTCOMM_OK) {
-               DBG("Return code (%d): %s", reply->ret_code,
-                               ustcomm_get_readable_code(reply->ret_code));
-               goto error;
-       } else if (reply->handle != chan->handle) {
-               ERR("Receive wrong handle from UST reply on enable channel");
-               goto error;
-       }
-
-       chan->enabled = 1;
-       free(reply);
-
-       DBG2("ustctl disable channel successful for sock %d", sock);
-       return 0;
-
-error:
-       free(reply);
-       return -1;
-}
index a592abf2276d70cbfc7806a95873dfc53873e0dc..a6d4e773ee14ffb8b60e4065566bc6022df935a5 100644 (file)
 #ifndef _LTT_UST_CTL_H
 #define _LTT_UST_CTL_H
 
+#include <config.h>
 #include <lttng/lttng.h>
 
 #include "trace-ust.h"
 
 #ifdef CONFIG_LTTNG_TOOLS_HAVE_UST
 
-int ustctl_register_done(int sock);
-int ustctl_create_channel(int sock, struct ltt_ust_session *session,
-               struct lttng_channel *channel);
-int ustctl_create_session(int sock, struct ltt_ust_session *session);
-int ustctl_destroy_session(int sock, struct ltt_ust_session *session);
-int ustctl_disable_channel(int sock, struct ltt_ust_session *session,
-               struct ltt_ust_channel *chan);
-int ustctl_enable_channel(int sock, struct ltt_ust_session *session,
-               struct ltt_ust_channel *chan);
 
 #else
 
-static inline
-int ustctl_register_done(int sock)
-{
-       return -ENOSYS;
-}
-static inline
-int ustctl_create_channel(int sock, struct ltt_ust_session *session,
-               struct lttng_channel *channel)
-{
-       return -ENOSYS;
-}
-static inline
-int ustctl_create_session(int sock, struct ltt_ust_session *session)
-{
-       return -ENOSYS;
-}
-static inline
-int ustctl_destroy_session(int sock, struct ltt_ust_session *session)
-{
-       return -ENOSYS;
-}
-static inline
-int ustctl_disable_channel(int sock, struct ltt_ust_session *session,
-               struct ltt_ust_channel *chan)
-{
-       return -ENOSYS;
-}
-static inline
-int ustctl_enable_channel(int sock, struct ltt_ust_session *session,
-               struct ltt_ust_channel *chan)
-{
-       return -ENOSYS;
-}
 
 #endif
 
index fbcd40dafac36d388e79fa2bc6f34d3194bac468..cb53fb0db96094c9736ae181e3bcc3ce27fcd0a9 100644 (file)
@@ -201,10 +201,23 @@ static int enable_events(char *session_name)
                channel_name = opt_channel_name;
        }
 
+       if (opt_kernel && opt_userspace) {
+               MSG("Choose only one of --kernel or --userspace");
+               ret = CMD_FATAL;
+               goto error;
+       }
        /* Create lttng domain */
        if (opt_kernel) {
                dom.type = LTTNG_DOMAIN_KERNEL;
        }
+       if (opt_userspace) {
+               /* TODO
+                * LTTNG_DOMAIN_UST_EXEC_NAME,
+                * LTTNG_DOMAIN_UST_PID,
+                * LTTNG_DOMAIN_UST_PID_FOLLOW_CHILDREN 
+                */
+               dom.type = LTTNG_DOMAIN_UST;
+       }
 
        handle = lttng_create_handle(session_name, &dom);
        if (handle == NULL) {
@@ -224,10 +237,8 @@ static int enable_events(char *session_name)
 
                switch (opt_event_type) {
                case LTTNG_EVENT_TRACEPOINT:
-                       if (opt_kernel) {
-                               MSG("All kernel tracepoints are enabled in channel %s",
-                                               channel_name);
-                       }
+                       MSG("All %s tracepoints are enabled in channel %s",
+                               opt_kernel ? "kernel" : "UST", channel_name);
                        break;
                case LTTNG_EVENT_SYSCALL:
                        if (opt_kernel) {
@@ -236,20 +247,17 @@ static int enable_events(char *session_name)
                        }
                        break;
                case LTTNG_EVENT_ALL:
-                       if (opt_kernel) {
-                               MSG("All kernel events are enabled in channel %s",
-                                               channel_name);
-                       }
+                       MSG("All %s events are enabled in channel %s",
+                               opt_kernel ? "kernel" : "UST", channel_name);
                        break;
                default:
                        /*
-                        * We should not be here since lttng_enable_event should had failed
-                        * on the event type.
+                        * We should not be here since
+                        * lttng_enable_event should have failed on the
+                        * event type.
                         */
                        goto error;
-
                }
-
                goto end;
        }
 
@@ -308,13 +316,41 @@ static int enable_events(char *session_name)
                        }
                } else if (opt_userspace) {             /* User-space tracer action */
                        /*
-                        * TODO: Waiting on lttng UST 2.0
+                        * TODO: only supporting pid_all tracing for
+                        * now. Should have different domain based on
+                        * opt_pid.
                         */
-                       if (opt_pid_all) {
-                       } else if (opt_pid != 0) {
+                       if (!opt_pid_all) {
+                               MSG("Only supporting tracing all UST processes (-u --all) for now.");
+                               ret = CMD_NOT_IMPLEMENTED;
+                               goto error;
+                       }
+                       DBG("Enabling UST event %s for channel %s",
+                                       event_name, channel_name);
+                       /* Copy name and type of the event */
+                       strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN);
+                       ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
+                       ev.type = opt_event_type;
+
+                       switch (opt_event_type) {
+                       case LTTNG_EVENT_ALL:   /* Default behavior is tracepoint */
+                               ev.type = LTTNG_EVENT_TRACEPOINT;
+                               /* Fall-through */
+                       case LTTNG_EVENT_TRACEPOINT:
+                               break;
+                       case LTTNG_EVENT_PROBE:
+                       case LTTNG_EVENT_FUNCTION:
+                       case LTTNG_EVENT_FUNCTION_ENTRY:
+                       case LTTNG_EVENT_SYSCALL:
+                       default:
+                               ret = CMD_NOT_IMPLEMENTED;
+                               goto error;
+                       }
+
+                       ret = lttng_enable_event(handle, &ev, channel_name);
+                       if (ret == 0) {
+                               MSG("UST event %s created in channel %s", event_name, channel_name);
                        }
-                       ret = CMD_NOT_IMPLEMENTED;
-                       goto error;
                } else {
                        ERR("Please specify a tracer (--kernel or --userspace)");
                        goto error;
This page took 0.084126 seconds and 4 git commands to generate.