Most parts of code are to deal with passing a varlen payload between
the sessiond, tracer application and lttng command, inspired by how
the filter feature are implemented.

You can also view the patch at:
https://github.com/5kg/lttng-tools/commit/fc2ca02a6915a4da513d47c7386e4a13f6629538
---
 include/lttng/lttng-error.h              |   2 +
 include/lttng/lttng.h                    |  19 ++++-
 src/bin/lttng-sessiond/Makefile.am       |   1 +
 src/bin/lttng-sessiond/cmd.c             |   6 ++
 src/bin/lttng-sessiond/lttng-ust-abi.h   |  30 +++++++-
 src/bin/lttng-sessiond/main.c            |  38 ++++++++++
 src/bin/lttng-sessiond/trace-ust.c       |  19 ++++-
 src/bin/lttng-sessiond/ust-app.c         | 126 +++++++++++++++++++++++++++++++
 src/bin/lttng-sessiond/ust-instrument.h  |  47 ++++++++++++
 src/bin/lttng/commands/enable_events.c   |  84 +++++++++++++++++++--
 src/bin/lttng/commands/list.c            |   2 +
 src/common/error.c                       |   2 +
 src/common/sessiond-comm/sessiond-comm.h |   2 +
 src/lib/lttng-ctl/lttng-ctl.c            |   7 ++
 14 files changed, 374 insertions(+), 11 deletions(-)
 create mode 100644 src/bin/lttng-sessiond/ust-instrument.h

diff --git a/include/lttng/lttng-error.h b/include/lttng/lttng-error.h
index 51ef9ca..73e40b4 100644
--- a/include/lttng/lttng-error.h
+++ b/include/lttng/lttng-error.h
@@ -140,6 +140,8 @@ enum lttng_error_code {
        LTTNG_ERR_FILTER_NOMEM           = 107, /* Lack of memory for filter 
bytecode */
        LTTNG_ERR_FILTER_EXIST           = 108, /* Filter already exist */
        LTTNG_ERR_NO_CONSUMER            = 109, /* No consumer exist for the 
session */
+       LTTNG_ERR_TARGET_INVAL           = 110, /* Invalid instrument target */
+       LTTNG_ERR_TARGET_NOMEM           = 111, /* Lack of memory for 
instrument target */
 
        /* MUST be last element */
        LTTNG_ERR_NR,                           /* Last element */
diff --git a/include/lttng/lttng.h b/include/lttng/lttng.h
index 4ffffd8..a6e018d 100644
--- a/include/lttng/lttng.h
+++ b/include/lttng/lttng.h
@@ -231,11 +231,27 @@ struct lttng_event_function_attr {
 };
 
 /*
+ * Instrument target
+ *
+ * The structures should be initialized to zero before use.
+ */
+#define LTTNG_EVENT_TARGET_PADDING        32
+struct lttng_event_target_attr {
+       int path_len;
+
+       char padding[LTTNG_EVENT_TARGET_PADDING];
+
+       /* This varlen field should always be the last element */
+       char path[0];
+};
+
+/*
  * Generic lttng event
  *
  * The structures should be initialized to zero before use.
  */
-#define LTTNG_EVENT_PADDING1               15
+#define LTTNG_EVENT_PADDING1               \
+       (15 - sizeof(struct lttng_event_target_attr *))
 #define LTTNG_EVENT_PADDING2               LTTNG_SYMBOL_NAME_LEN + 32
 struct lttng_event {
        enum lttng_event_type type;
@@ -247,6 +263,7 @@ struct lttng_event {
        int32_t enabled;        /* Does not apply: -1 */
        pid_t pid;
        unsigned char filter;   /* filter enabled ? */
+       struct lttng_event_target_attr *target;
 
        char padding[LTTNG_EVENT_PADDING1];
 
diff --git a/src/bin/lttng-sessiond/Makefile.am 
b/src/bin/lttng-sessiond/Makefile.am
index 77cc1d2..dce17cb 100644
--- a/src/bin/lttng-sessiond/Makefile.am
+++ b/src/bin/lttng-sessiond/Makefile.am
@@ -11,6 +11,7 @@ lttng_sessiond_SOURCES = utils.c utils.h \
                        kernel.c kernel.h \
                        ust-ctl.h ust-app.h trace-ust.h ust-thread.h \
                        ust-registry.h \
+                       ust-instrument.h \
                        context.c context.h \
                        channel.c channel.h \
                        event.c event.h \
diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c
index e9fa3b4..c154927 100644
--- a/src/bin/lttng-sessiond/cmd.c
+++ b/src/bin/lttng-sessiond/cmd.c
@@ -235,9 +235,15 @@ static int list_lttng_ust_global_events(char *channel_name,
                        break;
                case LTTNG_UST_PROBE:
                        tmp[i].type = LTTNG_EVENT_PROBE;
+                       memcpy(&tmp[i].attr.probe, &uevent->attr.u.probe,
+                                       sizeof(struct lttng_ust_probe));
+                       /* TODO: List instrument target information */
                        break;
                case LTTNG_UST_FUNCTION:
                        tmp[i].type = LTTNG_EVENT_FUNCTION;
+                       memcpy(&tmp[i].attr.probe, &uevent->attr.u.probe,
+                                       sizeof(struct lttng_ust_probe));
+                       /* TODO: List instrument target information */
                        break;
                }
 
diff --git a/src/bin/lttng-sessiond/lttng-ust-abi.h 
b/src/bin/lttng-sessiond/lttng-ust-abi.h
index 98470e4..29fc879 100644
--- a/src/bin/lttng-sessiond/lttng-ust-abi.h
+++ b/src/bin/lttng-sessiond/lttng-ust-abi.h
@@ -100,7 +100,32 @@ struct lttng_ust_stream {
         */
 } LTTNG_PACKED;
 
-#define LTTNG_UST_EVENT_PADDING1       16
+/*
+ * Either addr is used, or symbol_name and offset.
+ */
+#define LTTNG_UST_PROBE_PADDING        16
+struct lttng_ust_probe {
+       uint64_t addr;
+
+       uint64_t offset;
+       char symbol_name[LTTNG_UST_SYM_NAME_LEN];
+
+       char padding[LTTNG_UST_PROBE_PADDING];
+} LTTNG_PACKED;
+
+/*
+ * Instrument target
+ */
+#define LTTNG_UST_TARGET_PADDING       32
+struct lttng_ust_target {
+       uint32_t path_len;
+
+       char padding[LTTNG_UST_TARGET_PADDING];
+
+       char path[0];
+} LTTNG_PACKED;
+
+#define LTTNG_UST_EVENT_PADDING1       (16 - sizeof(struct lttng_ust_target *))
 #define LTTNG_UST_EVENT_PADDING2       (LTTNG_UST_SYM_NAME_LEN + 32)
 struct lttng_ust_event {
        enum lttng_ust_instrumentation instrumentation;
@@ -108,10 +133,12 @@ struct lttng_ust_event {
 
        enum lttng_ust_loglevel_type loglevel_type;
        int loglevel;   /* value, -1: all */
+       struct lttng_ust_target *target;
        char padding[LTTNG_UST_EVENT_PADDING1];
 
        /* Per instrumentation type configuration */
        union {
+               struct lttng_ust_probe probe;
                char padding[LTTNG_UST_EVENT_PADDING2];
        } u;
 } LTTNG_PACKED;
@@ -275,6 +302,7 @@ struct lttng_ust_filter_bytecode {
 
 /* Event FD commands */
 #define LTTNG_UST_FILTER                       _UST_CMD(0xA0)
+#define LTTNG_UST_TARGET                       _UST_CMD(0xA1)
 
 #define LTTNG_UST_ROOT_HANDLE  0
 
diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c
index d22e2a6..6c6b60b 100644
--- a/src/bin/lttng-sessiond/main.c
+++ b/src/bin/lttng-sessiond/main.c
@@ -2876,6 +2876,44 @@ skip_domain:
        }
        case LTTNG_ENABLE_EVENT:
        {
+               /* TODO: Handle dynamic instrumentation with filter */
+               struct lttng_event_target_attr *target;
+
+               if (cmd_ctx->lsm->u.enable.event.target) {
+                       if (cmd_ctx->lsm->u.enable.target_len
+                                       < sizeof(struct 
lttng_event_target_attr)) {
+                               ret = LTTNG_ERR_TARGET_INVAL;
+                               goto error;
+                       }
+
+                       target = zmalloc(cmd_ctx->lsm->u.enable.target_len);
+                       if (!target) {
+                               ret = LTTNG_ERR_TARGET_NOMEM;
+                               goto error;
+                       }
+
+                       /* Receive var. len. data */
+                       DBG("Receiving var len data target from client ...");
+                       ret = lttcomm_recv_unix_sock(sock, target,
+                                       cmd_ctx->lsm->u.enable.target_len);
+                       if (ret <= 0) {
+                               DBG("Nothing recv() from client var len data... 
continuing");
+                               *sock_error = 1;
+                               free(target);
+                               ret = LTTNG_ERR_TARGET_INVAL;
+                               goto error;
+                       }
+
+                       if ((sizeof(struct lttng_event_target_attr) + 
target->path_len)
+                                               != 
cmd_ctx->lsm->u.enable.target_len) {
+                               free(target);
+                               ret = LTTNG_ERR_TARGET_INVAL;
+                               goto error;
+                       }
+
+                       cmd_ctx->lsm->u.enable.event.target = target;
+               }
+
                ret = cmd_enable_event(cmd_ctx->session, &cmd_ctx->lsm->domain,
                                cmd_ctx->lsm->u.enable.channel_name,
                                &cmd_ctx->lsm->u.enable.event, NULL, 
kernel_poll_pipe[1]);
diff --git a/src/bin/lttng-sessiond/trace-ust.c 
b/src/bin/lttng-sessiond/trace-ust.c
index c80d5e7..f5f4122 100644
--- a/src/bin/lttng-sessiond/trace-ust.c
+++ b/src/bin/lttng-sessiond/trace-ust.c
@@ -324,12 +324,23 @@ struct ltt_ust_event *trace_ust_create_event(struct 
lttng_event *ev,
        switch (ev->type) {
        case LTTNG_EVENT_PROBE:
                lue->attr.instrumentation = LTTNG_UST_PROBE;
+               lue->attr.u.probe.addr = ev->attr.probe.addr;
+               lue->attr.u.probe.offset = ev->attr.probe.offset;
+               strncpy(lue->attr.u.probe.symbol_name,
+                               ev->attr.probe.symbol_name, 
LTTNG_UST_SYM_NAME_LEN);
+               lue->attr.u.probe.symbol_name[LTTNG_UST_SYM_NAME_LEN - 1] = 
'\0';
+               /* Same layout. */
+               lue->attr.target = (struct lttng_ust_target *) ev->target;
                break;
        case LTTNG_EVENT_FUNCTION:
                lue->attr.instrumentation = LTTNG_UST_FUNCTION;
-               break;
-       case LTTNG_EVENT_FUNCTION_ENTRY:
-               lue->attr.instrumentation = LTTNG_UST_FUNCTION;
+               lue->attr.u.probe.addr = ev->attr.probe.addr;
+               lue->attr.u.probe.offset = ev->attr.probe.offset;
+               strncpy(lue->attr.u.probe.symbol_name,
+                               ev->attr.probe.symbol_name, 
LTTNG_UST_SYM_NAME_LEN);
+               lue->attr.u.probe.symbol_name[LTTNG_UST_SYM_NAME_LEN - 1] = 
'\0';
+               /* Same layout. */
+               lue->attr.target = (struct lttng_ust_target *) ev->target;
                break;
        case LTTNG_EVENT_TRACEPOINT:
                lue->attr.instrumentation = LTTNG_UST_TRACEPOINT;
@@ -514,6 +525,8 @@ void trace_ust_destroy_event(struct ltt_ust_event *event)
        assert(event);
 
        DBG2("Trace destroy UST event %s", event->attr.name);
+
+       free(event->attr.target);
        free(event->filter);
        free(event);
 }
diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c
index 9fe5483..c8333bf 100644
--- a/src/bin/lttng-sessiond/ust-app.c
+++ b/src/bin/lttng-sessiond/ust-app.c
@@ -38,6 +38,7 @@
 #include "ust-app.h"
 #include "ust-consumer.h"
 #include "ust-ctl.h"
+#include "ust-instrument.h"
 #include "utils.h"
 
 /* Next available channel key. Access under next_channel_key_lock. */
@@ -270,6 +271,7 @@ void delete_ust_app_event(int sock, struct ust_app_event 
*ua_event)
 
        assert(ua_event);
 
+       free(ua_event->attr.target);
        free(ua_event->filter);
 
        if (ua_event->obj != NULL) {
@@ -927,6 +929,28 @@ error:
 }
 
 /*
+ * Allocate a instrument target and copy the given original one.
+ *
+ * Return allocated instrument target or NULL on error.
+ */
+static struct lttng_ust_target *alloc_copy_ust_app_target(
+               struct lttng_ust_target *orig_t)
+{
+       struct lttng_ust_target *target = NULL;
+
+       target = zmalloc(sizeof(*target) + orig_t->path_len);
+       if (!target) {
+               PERROR("zmalloc alloc ust app instrument target");
+               goto error;
+       }
+
+       memcpy(target, orig_t, sizeof(*target) + orig_t->path_len);
+
+error:
+       return target;
+}
+
+/*
  * Allocate a filter and copy the given original filter.
  *
  * Return allocated filter or NULL on error.
@@ -1067,6 +1091,41 @@ error:
 }
 
 /*
+ * Set the target on the tracer.
+ */
+static
+int set_ust_event_target(struct ust_app_event *ua_event,
+               struct ust_app *app)
+{
+       int ret;
+
+       health_code_update();
+
+       if (!ua_event->attr.target) {
+               ret = 0;
+               goto error;
+       }
+
+       ret = ustctl_set_target(app->sock, ua_event->attr.target,
+                       ua_event->obj);
+       if (ret < 0) {
+               if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
+                       ERR("UST app event %s set instrument target failed for 
app (pid: %d) "
+                                       "with ret %d", ua_event->attr.name, 
app->pid, ret);
+               } else {
+                       DBG3("UST app set instrument target failed. Application 
is dead.");
+               }
+               goto error;
+       }
+
+       DBG2("UST instrument target set successfully for event %s", 
ua_event->name);
+
+error:
+       health_code_update();
+       return ret;
+}
+
+/*
  * Set the filter on the tracer.
  */
 static
@@ -1302,6 +1361,14 @@ int create_ust_event(struct ust_app *app, struct 
ust_app_session *ua_sess,
 
        health_code_update();
 
+       /* Set instrument target if one is present. */
+       if (ua_event->attr.target) {
+               ret = set_ust_event_target(ua_event, app);
+               if (ret < 0) {
+                       goto error;
+               }
+       }
+
        /* Set filter if one is present. */
        if (ua_event->filter) {
                ret = set_ust_event_filter(ua_event, app);
@@ -1353,6 +1420,13 @@ static void shadow_copy_event(struct ust_app_event 
*ua_event,
        /* Copy event attributes */
        memcpy(&ua_event->attr, &uevent->attr, sizeof(ua_event->attr));
 
+       /* Copy instrument target */
+       if (uevent->attr.target) {
+               ua_event->attr.target =
+                       alloc_copy_ust_app_target(uevent->attr.target);
+               /* Target might be NULL here in case of ENONEM. */
+       }
+
        /* Copy filter bytecode */
        if (uevent->filter) {
                ua_event->filter = alloc_copy_ust_app_filter(uevent->filter);
@@ -4775,6 +4849,58 @@ int ust_app_recv_notify(int sock)
 
                break;
        }
+       case USTCTL_NOTIFY_CMD_INSTRUMENT:
+       {
+               enum lttng_ust_instrumentation instrumentation;
+               char name[LTTNG_UST_SYM_NAME_LEN], 
symbol[LTTNG_UST_SYM_NAME_LEN];
+               char object_path[PATH_MAX];
+               uint64_t addr, offset;
+               struct ust_app *app;
+
+               DBG2("UST app ustctl instrument probe received");
+
+               ret = ustctl_recv_instrument_probe(sock, object_path, name,
+                               &instrumentation, &addr, symbol, &offset);
+               if (ret < 0) {
+                       if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
+                               ERR("UST app recv instrument failed with ret 
%d", ret);
+                       } else {
+                               DBG3("UST app recv instrument failed. 
Application died");
+                       }
+                       goto error;
+               }
+
+               rcu_read_lock();
+
+               app = find_app_by_notify_sock(sock);
+               if (app == NULL) {
+                       DBG3("UST app instrument failed to find app sock %d", 
sock);
+                       goto error;
+               }
+
+               if (!app->compatible) {
+                       goto error;
+               }
+
+               rcu_read_unlock();
+
+               ret = ust_instrument_probe(app, object_path, name, 
instrumentation,
+                               addr, symbol, offset);
+
+               DBG3("UST app replying to instrument probe with pid %u, ret: 
%d",
+                               app->pid, ret);
+
+               ret = ustctl_reply_instrument_probe(sock, ret);
+               if (ret < 0) {
+                       if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
+                               ERR("UST app reply instrument failed with ret 
%d", ret);
+                       } else {
+                               DBG3("UST app reply instrument failed. 
Application died");
+                       }
+                       goto error;
+               }
+               break;
+       }
        default:
                /* Should NEVER happen. */
                assert(0);
diff --git a/src/bin/lttng-sessiond/ust-instrument.h 
b/src/bin/lttng-sessiond/ust-instrument.h
new file mode 100644
index 0000000..4332253
--- /dev/null
+++ b/src/bin/lttng-sessiond/ust-instrument.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 - Zifei Tong <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _LTT_UST_INSTRUMENT_H
+#define _LTT_UST_INSTRUMENT_H
+
+#include <stdint.h>
+
+#include "trace-ust.h"
+
+#if defined(HAVE_UST_INSTRUMENT_PROBE) && defined(HAVE_LIBLTTNG_UST_CTL)
+
+int ust_instrument_probe(struct ust_app* app,
+               const char *object_path,
+               const char *name,
+               enum lttng_ust_instrumentation instrumentation,
+               uint64_t addr,
+               const char *symbol,
+               uint64_t offset);
+
+#else /* HAVE_UST_INSTRUMENT_PROBE && HAVE_LIBLTTNG_UST_CTL */
+
+static inline
+int ust_instrument_probe(struct ust_app *app, const char* object_path,
+               const char* name, enum lttng_ust_instrumentation 
instrumentation,
+               uint64_t addr, const char *symbol, uint64_t offset)
+{
+       return -ENOSYS;
+}
+
+#endif /* HAVE_UST_INSTRUMENT_PROBE && HAVE_LIBLTTNG_UST_CTL */
+
+#endif /* _LTT_UST_INSTRUEMENT_H */
diff --git a/src/bin/lttng/commands/enable_events.c 
b/src/bin/lttng/commands/enable_events.c
index 26195af..cd8e1a1 100644
--- a/src/bin/lttng/commands/enable_events.c
+++ b/src/bin/lttng/commands/enable_events.c
@@ -113,14 +113,16 @@ static void usage(FILE *ofp)
        fprintf(ofp, "                             e.g.:\n");
        fprintf(ofp, "                               \"*\"\n");
        fprintf(ofp, "                               \"app_component:na*\"\n");
-       fprintf(ofp, "    --probe (addr | symbol | symbol+offset)\n");
+       fprintf(ofp, "    --probe [object@](addr | symbol | symbol+offset)\n");
        fprintf(ofp, "                           Dynamic probe.\n");
-       fprintf(ofp, "                           Addr and offset can be octal 
(0NNN...),\n");
-       fprintf(ofp, "                           decimal (NNN...) or 
hexadecimal (0xNNN...)\n");
-       fprintf(ofp, "    --function (addr | symbol | symbol+offset)\n");
+       fprintf(ofp, "                           - userspace tracer requires 
specifying an object to instrument.\n");
+       fprintf(ofp, "                           - Addr and offset can be octal 
(0NNN...),\n");
+       fprintf(ofp, "                             decimal (NNN...) or 
hexadecimal (0xNNN...)\n");
+       fprintf(ofp, "    --function [object@](addr | symbol | 
symbol+offset)\n");
        fprintf(ofp, "                           Dynamic function entry/return 
probe.\n");
-       fprintf(ofp, "                           Addr and offset can be octal 
(0NNN...),\n");
-       fprintf(ofp, "                           decimal (NNN...) or 
hexadecimal (0xNNN...)\n");
+       fprintf(ofp, "                           - userspace tracer requires 
specifying an object to instrument.\n");
+       fprintf(ofp, "                           - Addr and offset can be octal 
(0NNN...),\n");
+       fprintf(ofp, "                             decimal (NNN...) or 
hexadecimal (0xNNN...)\n");
 #if 0
        fprintf(ofp, "    --function:entry symbol\n");
        fprintf(ofp, "                           Function tracer event\n");
@@ -260,6 +262,58 @@ end:
 }
 
 /*
+ * Parse user-space probe options.
+ */
+static int parse_ust_probe_opts(struct lttng_event *ev, char *opt)
+{
+       char *pos;
+       int ret;
+
+       if (opt == NULL) {
+               ret = -1;
+               goto end;
+       }
+
+       /* Check for pathname */
+       /* TODO: support wildcard matching */
+       if ((pos = strrchr(opt, '@')) != NULL) {
+               struct lttng_event_target_attr *target;
+               char fullpath[PATH_MAX];
+               int path_len;
+
+               /* Process relative path */
+               if (opt[0] != '/') {
+                       if (getcwd(fullpath, PATH_MAX) == NULL) {
+                               goto error;
+                       }
+                       strncat(fullpath, "/", 1);
+                       strncat(fullpath, opt, pos - opt);
+               } else {
+                       strncpy(fullpath, opt, pos - opt);
+               }
+
+               path_len = strnlen(fullpath, PATH_MAX);
+               /* Include the tailing '\0' */
+               target = zmalloc(sizeof(struct lttng_event_target_attr) + 
path_len + 1);
+               target->path_len = path_len + 1;
+
+               strncpy(target->path, fullpath, path_len);
+               target->path[path_len] = '\0';
+               ev->target = target;
+               DBG("probe object %s", ev->target->path);
+               ret = parse_probe_opts(ev, pos+1);
+               goto end;
+       }
+
+error:
+       /* No match */
+       ret = -1;
+
+end:
+       return ret;
+}
+
+/*
  * Maps loglevel from string to value
  */
 static
@@ -556,7 +610,21 @@ static int enable_events(char *session_name)
                                ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
                                break;
                        case LTTNG_EVENT_PROBE:
+                               ret = parse_ust_probe_opts(&ev, opt_probe);
+                               if (ret < 0) {
+                                       ERR("Unable to parse probe options");
+                                       ret = 0;
+                                       goto error;
+                               }
+                               break;
                        case LTTNG_EVENT_FUNCTION:
+                               ret = parse_ust_probe_opts(&ev, opt_function);
+                               if (ret < 0) {
+                                       ERR("Unable to parse function probe 
options");
+                                       ret = 0;
+                                       goto error;
+                               }
+                               break;
                        case LTTNG_EVENT_FUNCTION_ENTRY:
                        case LTTNG_EVENT_SYSCALL:
                        default:
@@ -646,6 +714,10 @@ error:
        }
        lttng_destroy_handle(handle);
 
+       if (ev.target) {
+               free(ev.target);
+       }
+
        return ret;
 }
 
diff --git a/src/bin/lttng/commands/list.c b/src/bin/lttng/commands/list.c
index 1c7085d..52fb84d 100644
--- a/src/bin/lttng/commands/list.c
+++ b/src/bin/lttng/commands/list.c
@@ -240,6 +240,7 @@ static void print_events(struct lttng_event *event)
                        MSG("%soffset: 0x%" PRIx64, indent8, 
event->attr.probe.offset);
                        MSG("%ssymbol: %s", indent8, 
event->attr.probe.symbol_name);
                }
+               /* TODO: add support to print instrument object path */
                break;
        case LTTNG_EVENT_PROBE:
                MSG("%s%s (type: probe)%s%s", indent6,
@@ -251,6 +252,7 @@ static void print_events(struct lttng_event *event)
                        MSG("%soffset: 0x%" PRIx64, indent8, 
event->attr.probe.offset);
                        MSG("%ssymbol: %s", indent8, 
event->attr.probe.symbol_name);
                }
+               /* TODO: add support to print instrument object path */
                break;
        case LTTNG_EVENT_FUNCTION_ENTRY:
                MSG("%s%s (type: function)%s%s", indent6,
diff --git a/src/common/error.c b/src/common/error.c
index 42ed06f..d48e53a 100644
--- a/src/common/error.c
+++ b/src/common/error.c
@@ -112,6 +112,8 @@ static const char *error_string_array[] = {
        [ ERROR_INDEX(LTTNG_ERR_SNAPSHOT_OUTPUT_EXIST) ] = "Snapshot output 
already exists",
        [ ERROR_INDEX(LTTNG_ERR_START_SESSION_ONCE) ] = "Session needs to be 
started once",
        [ ERROR_INDEX(LTTNG_ERR_SNAPSHOT_FAIL) ] = "Snapshot record failed",
+       [ ERROR_INDEX(LTTNG_ERR_TARGET_INVAL) ] = "Invalid instrument target",
+       [ ERROR_INDEX(LTTNG_ERR_TARGET_NOMEM) ] = "Not enough memory for 
instrument target",
 
        /* Last element */
        [ ERROR_INDEX(LTTNG_ERR_NR) ] = "Unknown error code"
diff --git a/src/common/sessiond-comm/sessiond-comm.h 
b/src/common/sessiond-comm/sessiond-comm.h
index c52a6ca..294e185 100644
--- a/src/common/sessiond-comm/sessiond-comm.h
+++ b/src/common/sessiond-comm/sessiond-comm.h
@@ -224,6 +224,8 @@ struct lttcomm_session_msg {
                        struct lttng_event event;
                        /* Length of following bytecode for filter. */
                        uint32_t bytecode_len;
+                       /* Length of following instrument target. */
+                       uint32_t target_len;
                } LTTNG_PACKED enable;
                /* Create channel */
                struct {
diff --git a/src/lib/lttng-ctl/lttng-ctl.c b/src/lib/lttng-ctl/lttng-ctl.c
index daa4a73..695e9ee 100644
--- a/src/lib/lttng-ctl/lttng-ctl.c
+++ b/src/lib/lttng-ctl/lttng-ctl.c
@@ -699,6 +699,13 @@ int lttng_enable_event(struct lttng_handle *handle,
        lttng_ctl_copy_string(lsm.session.name, handle->session_name,
                        sizeof(lsm.session.name));
 
+       if (ev->target) {
+               lsm.u.enable.target_len = ev->target->path_len
+                       + sizeof(struct lttng_event_target_attr);
+               return lttng_ctl_ask_sessiond_varlen(&lsm, ev->target,
+                                       lsm.u.enable.target_len, NULL);
+       }
+
        return lttng_ctl_ask_sessiond(&lsm, NULL);
 }
 
-- 
1.8.4


_______________________________________________
lttng-dev mailing list
[email protected]
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

Reply via email to