Move UST registry into sessiond and implement notifiers
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 11 Feb 2013 23:00:34 +0000 (18:00 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 1 Mar 2013 18:06:48 +0000 (13:06 -0500)
Needs to be use in locked-step with lttng-tools

"Move UST registry into sessiond and implement notifiers" commit.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/lttng/ust-abi.h
include/lttng/ust-ctl.h
include/lttng/ust-error.h
include/lttng/ust-events.h
include/ust-comm.h
liblttng-ust-comm/lttng-ust-comm.c
liblttng-ust-ctl/ustctl.c
liblttng-ust/lttng-events.c
liblttng-ust/lttng-tracer-core.h
liblttng-ust/lttng-ust-abi.c
liblttng-ust/lttng-ust-comm.c

index 8c065fca04fd075d4304b3ca2baef6e9d12479fb..3c9f4600e9c0055997d4fbdeaed7173e68079900 100644 (file)
 #include <stdint.h>
 #include <lttng/ust-compiler.h>
 
-#define LTTNG_UST_SYM_NAME_LEN 256
+#ifndef __ust_stringify
+#define __ust_stringify1(x)    #x
+#define __ust_stringify(x)     __ust_stringify1(x)
+#endif /* __ust_stringify */
 
-/* Version for comm protocol between sessiond and ust */
-#define LTTNG_UST_COMM_VERSION_MAJOR           2
-#define LTTNG_UST_COMM_VERSION_MINOR           1
+#define LTTNG_UST_SYM_NAME_LEN                 256
+#define LTTNG_UST_ABI_PROCNAME_LEN             16
+
+/* UST comm magic number, used to validate protocol and endianness. */
+#define LTTNG_UST_COMM_MAGIC                   0xC57C57C5
 
 /* Version for ABI between liblttng-ust, sessiond, consumerd */
-#define LTTNG_UST_INTERNAL_MAJOR_VERSION       3
-#define LTTNG_UST_INTERNAL_MINOR_VERSION       0
-#define LTTNG_UST_INTERNAL_PATCHLEVEL_VERSION  0
+#define LTTNG_UST_ABI_MAJOR_VERSION            4
+#define LTTNG_UST_ABI_MINOR_VERSION            0
 
 enum lttng_ust_instrumentation {
        LTTNG_UST_TRACEPOINT            = 0,
@@ -171,6 +175,8 @@ enum lttng_ust_object_type {
        LTTNG_UST_OBJECT_TYPE_UNKNOWN = -1,
        LTTNG_UST_OBJECT_TYPE_CHANNEL = 0,
        LTTNG_UST_OBJECT_TYPE_STREAM = 1,
+       LTTNG_UST_OBJECT_TYPE_EVENT = 2,
+       LTTNG_UST_OBJECT_TYPE_CONTEXT = 3,
 };
 
 #define LTTNG_UST_OBJECT_DATA_PADDING1 32
index 06b9f92bf6741eeba65eb6a37a8317427143eb8a..ae4f3089bd41f5d1347763266725adc7cfe973ba 100644 (file)
 #define _LTTNG_UST_CTL_H
 
 #include <lttng/ust-abi.h>
-
-#ifndef LTTNG_PACKED
-#define LTTNG_PACKED __attribute__((packed))
-#endif
+#include <sys/types.h>
 
 #ifndef LTTNG_UST_UUID_LEN
 #define LTTNG_UST_UUID_LEN     16
 #endif
 
+/* Default unix socket path */
+#define LTTNG_UST_SOCK_FILENAME                                        \
+       "lttng-ust-sock-"                                       \
+       __ust_stringify(LTTNG_UST_ABI_MAJOR_VERSION)
+
+/*
+ * Shared memory files path are automatically related to shm root, e.g.
+ * /dev/shm under linux.
+ */
+#define LTTNG_UST_WAIT_FILENAME                                        \
+       "lttng-ust-wait-"                                       \
+       __ust_stringify(LTTNG_UST_ABI_MAJOR_VERSION)
+
 struct lttng_ust_shm_handle;
 struct lttng_ust_lib_ring_buffer;
 
@@ -188,4 +198,179 @@ int ustctl_put_subbuf(struct ustctl_consumer_stream *stream);
 void ustctl_flush_buffer(struct ustctl_consumer_stream *stream,
                int producer_active);
 
+/* event registry management */
+
+enum ustctl_socket_type {
+       USTCTL_SOCKET_CMD = 0,
+       USTCTL_SOCKET_NOTIFY = 1,
+};
+
+enum ustctl_notify_cmd {
+       USTCTL_NOTIFY_CMD_EVENT = 0,
+       USTCTL_NOTIFY_CMD_CHANNEL = 1,
+};
+
+enum ustctl_channel_header {
+       USTCTL_CHANNEL_HEADER_UNKNOWN = 0,
+       USTCTL_CHANNEL_HEADER_COMPACT = 1,
+       USTCTL_CHANNEL_HEADER_LARGE = 2,
+};
+
+/* event type structures */
+
+enum ustctl_abstract_types {
+       ustctl_atype_integer,
+       ustctl_atype_enum,
+       ustctl_atype_array,
+       ustctl_atype_sequence,
+       ustctl_atype_string,
+       ustctl_atype_float,
+       NR_USTCTL_ABSTRACT_TYPES,
+};
+
+enum ustctl_string_encodings {
+       ustctl_encode_none = 0,
+       ustctl_encode_UTF8 = 1,
+       ustctl_encode_ASCII = 2,
+       NR_USTCTL_STRING_ENCODINGS,
+};
+
+#define USTCTL_UST_INTEGER_TYPE_PADDING        24
+struct ustctl_integer_type {
+       uint32_t size;          /* in bits */
+       uint32_t signedness;
+       uint32_t reverse_byte_order;
+       uint32_t base;          /* 2, 8, 10, 16, for pretty print */
+       enum ustctl_string_encodings encoding;
+       uint16_t alignment;     /* in bits */
+       char padding[USTCTL_UST_INTEGER_TYPE_PADDING];
+} LTTNG_PACKED;
+
+#define USTCTL_UST_FLOAT_TYPE_PADDING  24
+struct ustctl_float_type {
+       uint32_t exp_dig;               /* exponent digits, in bits */
+       uint32_t mant_dig;              /* mantissa digits, in bits */
+       uint32_t reverse_byte_order;
+       uint16_t alignment;     /* in bits */
+       char padding[USTCTL_UST_FLOAT_TYPE_PADDING];
+} LTTNG_PACKED;
+
+#define USTCTL_UST_BASIC_TYPE_PADDING  296
+union _ustctl_basic_type {
+       struct ustctl_integer_type integer;
+       struct {
+               enum ustctl_string_encodings encoding;
+       } string;
+       struct ustctl_float_type _float;
+       char padding[USTCTL_UST_BASIC_TYPE_PADDING];
+} LTTNG_PACKED;
+
+struct ustctl_basic_type {
+       enum ustctl_abstract_types atype;
+       union {
+               union _ustctl_basic_type basic;
+       } u;
+} LTTNG_PACKED;
+
+#define USTCTL_UST_TYPE_PADDING        128
+struct ustctl_type {
+       enum ustctl_abstract_types atype;
+       union {
+               union _ustctl_basic_type basic;
+               struct {
+                       struct ustctl_basic_type elem_type;
+                       uint32_t length;                /* num. elems. */
+               } array;
+               struct {
+                       struct ustctl_basic_type length_type;
+                       struct ustctl_basic_type elem_type;
+               } sequence;
+               char padding[USTCTL_UST_TYPE_PADDING];
+       } u;
+} LTTNG_PACKED;
+
+#define USTCTL_UST_FIELD_PADDING       28
+struct ustctl_field {
+       char name[LTTNG_UST_SYM_NAME_LEN];
+       struct ustctl_type type;
+       char padding[USTCTL_UST_FIELD_PADDING];
+} LTTNG_PACKED;
+
+/*
+ * Returns 0 on success, negative error value on error.
+ * If an error other than -LTTNG_UST_ERR_UNSUP_MAJOR is returned,
+ * the output fields are not populated.
+ */
+int ustctl_recv_reg_msg(int sock,
+       enum ustctl_socket_type *type,
+       uint32_t *major,
+       uint32_t *minor,
+       uint32_t *pid,
+       uint32_t *ppid,
+       uint32_t *uid,
+       uint32_t *gid,
+       uint32_t *bits_per_long,
+       uint32_t *uint8_t_alignment,
+       uint32_t *uint16_t_alignment,
+       uint32_t *uint32_t_alignment,
+       uint32_t *uint64_t_alignment,
+       uint32_t *long_alignment,
+       int *byte_order,
+       char *name);    /* size LTTNG_UST_ABI_PROCNAME_LEN */
+
+/*
+ * Returns 0 on success, negative UST or system error value on error.
+ * Receive the notification command. The "notify_cmd" can then be used
+ * by the caller to find out which ustctl_recv_* function should be
+ * called to receive the notification, and which ustctl_reply_* is
+ * appropriate.
+ */
+int ustctl_recv_notify(int sock, enum ustctl_notify_cmd *notify_cmd);
+
+/*
+ * Returns 0 on success, negative UST or system error value on error.
+ */
+int ustctl_recv_register_event(int sock,
+       int *session_objd,              /* session descriptor (output) */
+       int *channel_objd,              /* channel descriptor (output) */
+       char *event_name,               /*
+                                        * event name (output,
+                                        * size LTTNG_UST_SYM_NAME_LEN)
+                                        */
+       int *loglevel,
+       char **signature,               /*
+                                        * event signature
+                                        * (output, dynamically
+                                        * allocated, must be free(3)'d
+                                        * by the caller if function
+                                        * returns success.)
+                                        */
+       size_t *nr_fields,
+       struct ustctl_field **fields,
+       char **model_emf_uri);
+
+/*
+ * Returns 0 on success, negative error value on error.
+ */
+int ustctl_reply_register_event(int sock,
+       uint32_t id,                    /* event id (input) */
+       int ret_code);                  /* return code. 0 ok, negative error */
+
+/*
+ * Returns 0 on success, negative UST or system error value on error.
+ */
+int ustctl_recv_register_channel(int sock,
+       int *session_objd,              /* session descriptor (output) */
+       int *channel_objd,              /* channel descriptor (output) */
+       size_t *nr_fields,              /* context fields */
+       struct ustctl_field **fields);
+
+/*
+ * Returns 0 on success, negative error value on error.
+ */
+int ustctl_reply_register_channel(int sock,
+       uint32_t chan_id,
+       enum ustctl_channel_header header_type,
+       int ret_code);                  /* return code. 0 ok, negative error */
+
 #endif /* _LTTNG_UST_CTL_H */
index bf6b7f33f2c3f6ae749cf23dbb16ac72fecf3d89..05cc3bee65e2dd61a87c3907bda010e444c85680 100644 (file)
@@ -43,6 +43,10 @@ enum lttng_ust_error_code {
        LTTNG_UST_ERR_NOSYS = 1029,             /* Not implemented */
        LTTNG_UST_ERR_EXITING = 1030,           /* Process is exiting */
 
+       LTTNG_UST_ERR_INVAL_MAGIC = 1031,       /* Invalid magic number */
+       LTTNG_UST_ERR_INVAL_SOCKET_TYPE = 1032, /* Invalid socket type */
+       LTTNG_UST_ERR_UNSUP_MAJOR = 1033,       /* Unsupported major version */
+
        /* MUST be last element */
        LTTNG_UST_ERR_NR,                       /* Last element */
 };
index c87a82c00a87277ec0b1144c31104ed385c96835..663ffbe353d454ba1ca47417e3ec3194b8068be5 100644 (file)
@@ -420,8 +420,8 @@ struct lttng_channel {
        /* Event ID management */
        struct lttng_session *session;
        int objd;                       /* Object associated to channel */
-       unsigned int free_event_id;     /* Next event ID to allocate */
-       unsigned int used_event_id;     /* Max allocated event IDs */
+       unsigned int _deprecated1;
+       unsigned int _deprecated2;
        struct cds_list_head node;      /* Channel list in session */
        const struct lttng_channel_ops *ops;
        int header_type;                /* 0: unset, 1: compact, 2: large */
@@ -455,13 +455,14 @@ struct lttng_session {
        struct cds_list_head events_head;       /* list of events */
        struct cds_list_head _deprecated1;
        struct cds_list_head node;              /* Session list */
-       unsigned int free_chan_id;              /* Next chan ID to allocate */
+       int _deprecated2;
        unsigned int metadata_dumped:1;
 
        /* New UST 2.1 */
        /* List of enablers */
        struct cds_list_head enablers_head;
        struct lttng_ust_event_ht events_ht;    /* ht of events */
+       void *owner;                            /* object owner */
 };
 
 struct lttng_transport {
index 0eca73a9ecbeecc6fe16247206bb952f43cf87bc..97141160fc32dd6babd9a8614cc6462db1b9a892 100644 (file)
  */
 #define LTTNG_UST_DEFAULT_CONSTRUCTOR_TIMEOUT_MS       3000
 
-#define LTTNG_RUNDIR                        "/var/run/lttng"
-#define LTTNG_HOME_RUNDIR                   "%s/.lttng"
-
-/* Default unix socket path */
-#define DEFAULT_GLOBAL_CLIENT_UNIX_SOCK     LTTNG_RUNDIR "/client-lttng-sessiond"
-#define DEFAULT_GLOBAL_APPS_UNIX_SOCK       LTTNG_RUNDIR "/apps-lttng-sessiond"
-#define DEFAULT_HOME_APPS_UNIX_SOCK         LTTNG_HOME_RUNDIR "/apps-lttng-sessiond"
-#define DEFAULT_HOME_CLIENT_UNIX_SOCK       LTTNG_HOME_RUNDIR "/client-lttng-sessiond"
-
-#define DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH   "/lttng-ust-apps-wait"
-#define DEFAULT_HOME_APPS_WAIT_SHM_PATH     "/lttng-ust-apps-wait-%u"
+#define LTTNG_DEFAULT_RUNDIR                           "/var/run/lttng"
+#define LTTNG_DEFAULT_HOME_RUNDIR                      ".lttng"
 
 /* Queue size of listen(2) */
-#define LTTNG_UST_COMM_MAX_LISTEN 10
+#define LTTNG_UST_COMM_MAX_LISTEN                      10
+#define LTTNG_UST_COMM_REG_MSG_PADDING                 64
+
+struct lttng_event_field;
+
+struct ustctl_reg_msg {
+       uint32_t magic;
+       uint32_t major;
+       uint32_t minor;
+       uint32_t pid;
+       uint32_t ppid;
+       uint32_t uid;
+       uint32_t gid;
+       uint32_t bits_per_long;
+       uint32_t uint8_t_alignment;
+       uint32_t uint16_t_alignment;
+       uint32_t uint32_t_alignment;
+       uint32_t uint64_t_alignment;
+       uint32_t long_alignment;
+       uint32_t socket_type;                   /* enum ustctl_socket_type */
+       char name[LTTNG_UST_ABI_PROCNAME_LEN];  /* process name */
+       char padding[LTTNG_UST_COMM_REG_MSG_PADDING];
+} LTTNG_PACKED;
 
 /*
  * Data structure for the commands sent from sessiond to UST.
  */
+#define USTCOMM_MSG_PADDING1           32
+#define USTCOMM_MSG_PADDING2           32
 struct ustcomm_ust_msg {
        uint32_t handle;
        uint32_t cmd;
+       char padding[USTCOMM_MSG_PADDING1];
        union {
                struct lttng_ust_channel channel;
                struct lttng_ust_stream stream;
@@ -73,6 +89,7 @@ struct ustcomm_ust_msg {
                        uint32_t reloc_offset;
                        uint64_t seqnum;
                } LTTNG_PACKED filter;
+               char padding[USTCOMM_MSG_PADDING2];
        } u;
 } LTTNG_PACKED;
 
@@ -80,11 +97,14 @@ struct ustcomm_ust_msg {
  * Data structure for the response from UST to the session daemon.
  * cmd_type is sent back in the reply for validation.
  */
+#define USTCOMM_REPLY_PADDING1         32
+#define USTCOMM_REPLY_PADDING2         32
 struct ustcomm_ust_reply {
        uint32_t handle;
        uint32_t cmd;
-       uint32_t ret_code;      /* enum enum ustcomm_return_code */
+       uint32_t ret_code;      /* enum ustcomm_return_code */
        uint32_t ret_val;       /* return value */
+       char padding[USTCOMM_REPLY_PADDING1];
        union {
                struct {
                        uint64_t memory_map_size;
@@ -94,9 +114,51 @@ struct ustcomm_ust_reply {
                } LTTNG_PACKED stream;
                struct lttng_ust_tracer_version version;
                struct lttng_ust_tracepoint_iter tracepoint;
+               char padding[USTCOMM_REPLY_PADDING2];
        } u;
 } LTTNG_PACKED;
 
+struct ustcomm_notify_hdr {
+       uint32_t notify_cmd;
+} LTTNG_PACKED;
+
+#define USTCOMM_NOTIFY_EVENT_MSG_PADDING       32
+struct ustcomm_notify_event_msg {
+       uint32_t session_objd;
+       uint32_t channel_objd;
+       char event_name[LTTNG_UST_SYM_NAME_LEN];
+       int32_t loglevel;
+       uint32_t signature_len;
+       uint32_t fields_len;
+       uint32_t model_emf_uri_len;
+       char padding[USTCOMM_NOTIFY_EVENT_MSG_PADDING];
+       /* followed by signature, fields, and model_emf_uri */
+} LTTNG_PACKED;
+
+#define USTCOMM_NOTIFY_EVENT_REPLY_PADDING     32
+struct ustcomm_notify_event_reply {
+       int32_t ret_code;       /* 0: ok, negative: error code */
+       uint32_t event_id;
+       char padding[USTCOMM_NOTIFY_EVENT_REPLY_PADDING];
+} LTTNG_PACKED;
+
+#define USTCOMM_NOTIFY_CHANNEL_MSG_PADDING     32
+struct ustcomm_notify_channel_msg {
+       uint32_t session_objd;
+       uint32_t channel_objd;
+       uint32_t ctx_fields_len;
+       char padding[USTCOMM_NOTIFY_CHANNEL_MSG_PADDING];
+       /* followed by context fields */
+} LTTNG_PACKED;
+
+#define USTCOMM_NOTIFY_CHANNEL_REPLY_PADDING   32
+struct ustcomm_notify_channel_reply {
+       int32_t ret_code;       /* 0: ok, negative: error code */
+       uint32_t chan_id;
+       uint32_t header_type;   /* enum ustctl_channel_header */
+       char padding[USTCOMM_NOTIFY_CHANNEL_REPLY_PADDING];
+} LTTNG_PACKED;
+
 /*
  * LTTNG_UST_TRACEPOINT_FIELD_LIST reply is followed by a
  * struct lttng_ust_field_iter field.
@@ -109,7 +171,7 @@ extern int ustcomm_listen_unix_sock(int sock);
 extern int ustcomm_close_unix_sock(int sock);
 
 extern ssize_t ustcomm_recv_unix_sock(int sock, void *buf, size_t len);
-extern ssize_t ustcomm_send_unix_sock(int sock, void *buf, size_t len);
+extern ssize_t ustcomm_send_unix_sock(int sock, const void *buf, size_t len);
 extern ssize_t ustcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd);
 extern ssize_t ustcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd);
 
@@ -128,4 +190,44 @@ int ustcomm_recv_stream_from_sessiond(int sock,
                uint64_t *memory_map_size,
                int *shm_fd, int *wakeup_fd);
 
+/*
+ * Returns 0 on success, negative error value on error.
+ * Returns -EPIPE or -ECONNRESET if other end has hung up.
+ */
+int ustcomm_send_reg_msg(int sock,
+               enum ustctl_socket_type type,
+               uint32_t bits_per_long,
+               uint32_t uint8_t_alignment,
+               uint32_t uint16_t_alignment,
+               uint32_t uint32_t_alignment,
+               uint32_t uint64_t_alignment,
+               uint32_t long_alignment);
+
+/*
+ * Returns 0 on success, negative error value on error.
+ * Returns -EPIPE or -ECONNRESET if other end has hung up.
+ */
+int ustcomm_register_event(int sock,
+       int session_objd,               /* session descriptor */
+       int channel_objd,               /* channel descriptor */
+       const char *event_name,         /* event name (input) */
+       int loglevel,
+       const char *signature,          /* event signature (input) */
+       size_t nr_fields,               /* fields */
+       const struct lttng_event_field *fields,
+       const char *model_emf_uri,
+       uint32_t *id);                  /* event id (output) */
+
+/*
+ * Returns 0 on success, negative error value on error.
+ * Returns -EPIPE or -ECONNRESET if other end has hung up.
+ */
+int ustcomm_register_channel(int sock,
+       int session_objd,               /* session descriptor */
+       int channel_objd,               /* channel descriptor */
+       size_t nr_ctx_fields,
+       const struct lttng_event_field *ctx_fields,
+       uint32_t *chan_id,              /* channel id (output) */
+       int *header_type);              /* header type (output) */
+
 #endif /* _LTTNG_UST_COMM_H */
index f469567690b3a9a88a2d7f4252417e130a1c6975..1395eee2f22ea6bb19f56e496d30853e1aee6168 100644 (file)
 #include <errno.h>
 #include <fcntl.h>
 
+#include <lttng/ust-ctl.h>
 #include <ust-comm.h>
 #include <helper.h>
 #include <lttng/ust-error.h>
+#include <lttng/ust-events.h>
+#include <usterr-signal-safe.h>
+
+#include "../liblttng-ust/compat.h"
 
 #define USTCOMM_CODE_OFFSET(code)      \
        (code == LTTNG_UST_OK ? 0 : (code - LTTNG_UST_ERR + 1))
@@ -52,6 +57,10 @@ static const char *ustcomm_readable_code[] = {
        [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_PERM) ] = "Permission denied",
        [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_NOSYS) ] = "Not implemented",
        [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_EXITING) ] = "Process is exiting",
+
+       [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL_MAGIC) ] = "Invalid magic number",
+       [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_INVAL_SOCKET_TYPE) ] = "Invalid socket type",
+       [ USTCOMM_CODE_OFFSET(LTTNG_UST_ERR_UNSUP_MAJOR) ] = "Unsupported major version",
 };
 
 /*
@@ -89,13 +98,13 @@ int ustcomm_connect_unix_sock(const char *pathname)
         */
        fd = socket(PF_UNIX, SOCK_STREAM, 0);
        if (fd < 0) {
-               perror("socket");
+               PERROR("socket");
                ret = -errno;
                goto error;
        }
        ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
        if (ret < 0) {
-               perror("fcntl");
+               PERROR("fcntl");
                ret = -errno;
                goto error_fcntl;
        }
@@ -125,7 +134,7 @@ error_fcntl:
 
                closeret = close(fd);
                if (closeret)
-                       perror("close");
+                       PERROR("close");
        }
 error:
        return ret;
@@ -146,7 +155,7 @@ int ustcomm_accept_unix_sock(int sock)
        /* Blocking call */
        new_fd = accept(sock, (struct sockaddr *) &sun, &len);
        if (new_fd < 0) {
-               perror("accept");
+               PERROR("accept");
                return -errno;
        }
        return new_fd;
@@ -165,7 +174,7 @@ int ustcomm_create_unix_sock(const char *pathname)
 
        /* Create server socket */
        if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
-               perror("socket");
+               PERROR("socket");
                ret = -errno;
                goto error;
        }
@@ -179,7 +188,7 @@ int ustcomm_create_unix_sock(const char *pathname)
        (void) unlink(pathname);
        ret = bind(fd, (struct sockaddr *) &sun, sizeof(sun));
        if (ret < 0) {
-               perror("bind");
+               PERROR("bind");
                ret = -errno;
                goto error_close;
        }
@@ -192,7 +201,7 @@ error_close:
 
                closeret = close(fd);
                if (closeret) {
-                       perror("close");
+                       PERROR("close");
                }
        }
 error:
@@ -211,7 +220,7 @@ int ustcomm_listen_unix_sock(int sock)
        ret = listen(sock, LTTNG_UST_COMM_MAX_LISTEN);
        if (ret < 0) {
                ret = -errno;
-               perror("listen");
+               PERROR("listen");
        }
 
        return ret;
@@ -228,7 +237,7 @@ int ustcomm_close_unix_sock(int sock)
 
        ret = close(sock);
        if (ret < 0) {
-               perror("close");
+               PERROR("close");
                ret = -errno;
        }
 
@@ -264,12 +273,12 @@ ssize_t ustcomm_recv_unix_sock(int sock, void *buf, size_t len)
                int shutret;
 
                if (errno != EPIPE && errno != ECONNRESET)
-                       perror("recvmsg");
+                       PERROR("recvmsg");
                ret = -errno;
 
                shutret = shutdown(sock, SHUT_RDWR);
                if (shutret)
-                       fprintf(stderr, "Socket shutdown error");
+                       ERR("Socket shutdown error");
        }
 
        return ret;
@@ -281,7 +290,7 @@ ssize_t ustcomm_recv_unix_sock(int sock, void *buf, size_t len)
  * Send buf data of size len. Using sendmsg API.
  * Return the size of sent data.
  */
-ssize_t ustcomm_send_unix_sock(int sock, void *buf, size_t len)
+ssize_t ustcomm_send_unix_sock(int sock, const void *buf, size_t len)
 {
        struct msghdr msg;
        struct iovec iov[1];
@@ -289,7 +298,7 @@ ssize_t ustcomm_send_unix_sock(int sock, void *buf, size_t len)
 
        memset(&msg, 0, sizeof(msg));
 
-       iov[0].iov_base = buf;
+       iov[0].iov_base = (void *) buf;
        iov[0].iov_len = len;
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;
@@ -309,12 +318,12 @@ ssize_t ustcomm_send_unix_sock(int sock, void *buf, size_t len)
                int shutret;
 
                if (errno != EPIPE && errno != ECONNRESET)
-                       perror("sendmsg");
+                       PERROR("sendmsg");
                ret = -errno;
 
                shutret = shutdown(sock, SHUT_RDWR);
                if (shutret)
-                       fprintf(stderr, "Socket shutdown error");
+                       ERR("Socket shutdown error");
        }
 
        return ret;
@@ -365,7 +374,7 @@ ssize_t ustcomm_send_fds_unix_sock(int sock, int *fds, size_t nb_fd)
                 * We consider EPIPE and ECONNRESET as expected.
                 */
                if (errno != EPIPE && errno != ECONNRESET) {
-                       perror("sendmsg");
+                       PERROR("sendmsg");
                }
        }
        return ret;
@@ -405,7 +414,7 @@ ssize_t ustcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
        } while (ret < 0 && errno == EINTR);
        if (ret < 0) {
                if (errno != EPIPE && errno != ECONNRESET) {
-                       perror("recvmsg fds");
+                       PERROR("recvmsg fds");
                }
                if (errno == EPIPE || errno == ECONNRESET)
                        ret = -errno;
@@ -417,28 +426,28 @@ ssize_t ustcomm_recv_fds_unix_sock(int sock, int *fds, size_t nb_fd)
                goto end;
        }
        if (ret != 1) {
-               fprintf(stderr, "Error: Received %zd bytes, expected %d\n",
+               ERR("Error: Received %zd bytes, expected %d\n",
                                ret, 1);
                goto end;
        }
        if (msg.msg_flags & MSG_CTRUNC) {
-               fprintf(stderr, "Error: Control message truncated.\n");
+               ERR("Error: Control message truncated.\n");
                ret = -1;
                goto end;
        }
        cmsg = CMSG_FIRSTHDR(&msg);
        if (!cmsg) {
-               fprintf(stderr, "Error: Invalid control message header\n");
+               ERR("Error: Invalid control message header\n");
                ret = -1;
                goto end;
        }
        if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {
-               fprintf(stderr, "Didn't received any fd\n");
+               ERR("Didn't received any fd\n");
                ret = -1;
                goto end;
        }
        if (cmsg->cmsg_len != CMSG_LEN(sizeof_fds)) {
-               fprintf(stderr, "Error: Received %zu bytes of ancillary data, expected %zu\n",
+               ERR("Error: Received %zu bytes of ancillary data, expected %zu\n",
                                (size_t) cmsg->cmsg_len, (size_t) CMSG_LEN(sizeof_fds));
                ret = -1;
                goto end;
@@ -461,7 +470,7 @@ int ustcomm_send_app_msg(int sock, struct ustcomm_ust_msg *lum)
                if (len < 0) {
                        return len;
                } else {
-                       fprintf(stderr, "incorrect message size: %zd\n", len);
+                       ERR("incorrect message size: %zd\n", len);
                        return -EINVAL;
                }
        }
@@ -480,13 +489,13 @@ int ustcomm_recv_app_reply(int sock, struct ustcomm_ust_reply *lur,
                return -EPIPE;
        case sizeof(*lur):
                if (lur->handle != expected_handle) {
-                       fprintf(stderr, "Unexpected result message handle: "
+                       ERR("Unexpected result message handle: "
                                "expected: %u vs received: %u\n",
                                expected_handle, lur->handle);
                        return -EINVAL;
                }
                if (lur->cmd != expected_cmd) {
-                       fprintf(stderr, "Unexpected result message command "
+                       ERR("Unexpected result message command "
                                "expected: %u vs received: %u\n",
                                expected_cmd, lur->cmd);
                        return -EINVAL;
@@ -499,7 +508,7 @@ int ustcomm_recv_app_reply(int sock, struct ustcomm_ust_reply *lur,
                                len = -errno;
                        return len;
                } else {
-                       fprintf(stderr, "incorrect message size: %zd\n", len);
+                       ERR("incorrect message size: %zd\n", len);
                        return len;
                }
        }
@@ -580,3 +589,424 @@ int ustcomm_recv_stream_from_sessiond(int sock,
 error:
        return ret;
 }
+
+/*
+ * Returns 0 on success, negative error value on error.
+ */
+int ustcomm_send_reg_msg(int sock,
+               enum ustctl_socket_type type,
+               uint32_t bits_per_long,
+               uint32_t uint8_t_alignment,
+               uint32_t uint16_t_alignment,
+               uint32_t uint32_t_alignment,
+               uint32_t uint64_t_alignment,
+               uint32_t long_alignment)
+{
+       ssize_t len;
+       struct ustctl_reg_msg reg_msg;
+
+       reg_msg.magic = LTTNG_UST_COMM_MAGIC;
+       reg_msg.major = LTTNG_UST_ABI_MAJOR_VERSION;
+       reg_msg.minor = LTTNG_UST_ABI_MINOR_VERSION;
+       reg_msg.pid = getpid();
+       reg_msg.ppid = getppid();
+       reg_msg.uid = getuid();
+       reg_msg.gid = getgid();
+       reg_msg.bits_per_long = bits_per_long;
+       reg_msg.uint8_t_alignment = uint8_t_alignment;
+       reg_msg.uint16_t_alignment = uint16_t_alignment;
+       reg_msg.uint32_t_alignment = uint32_t_alignment;
+       reg_msg.uint64_t_alignment = uint64_t_alignment;
+       reg_msg.long_alignment = long_alignment;
+       reg_msg.socket_type = type;
+       lttng_ust_getprocname(reg_msg.name);
+       memset(reg_msg.padding, 0, sizeof(reg_msg.padding));
+
+       len = ustcomm_send_unix_sock(sock, &reg_msg, sizeof(reg_msg));
+       if (len > 0 && len != sizeof(reg_msg))
+               return -EIO;
+       if (len < 0)
+               return len;
+       return 0;
+}
+
+static
+int serialize_basic_type(enum lttng_abstract_types atype,
+               union _ustctl_basic_type *ubt,
+               const union _lttng_basic_type *lbt)
+{
+       switch (atype) {
+       case atype_integer:
+       {
+               struct ustctl_integer_type *uit;
+               const struct lttng_integer_type *lit;
+
+               uit = &ubt->integer;
+               lit = &lbt->integer;
+               uit->size = lit->size;
+               uit->signedness = lit->signedness;
+               uit->reverse_byte_order = lit->reverse_byte_order;
+               uit->base = lit->base;
+               uit->encoding = lit->encoding;
+               uit->alignment = lit->alignment;
+               break;
+       }
+       case atype_string:
+       {
+               ubt->string.encoding = lbt->string.encoding;
+               break;
+       }
+       case atype_float:
+       {
+               struct ustctl_float_type *uft;
+               const struct lttng_float_type *lft;
+
+               uft = &ubt->_float;
+               lft = &lbt->_float;
+               uft->exp_dig = lft->exp_dig;
+               uft->mant_dig = lft->mant_dig;
+               uft->alignment = lft->alignment;
+               uft->reverse_byte_order = lft->reverse_byte_order;
+               break;
+       }
+       case atype_enum:
+       case atype_array:
+       case atype_sequence:
+       default:
+               return -EINVAL;
+       }
+       return 0;
+
+}
+
+static
+int serialize_one_type(struct ustctl_type *ut, const struct lttng_type *lt)
+{
+       int ret;
+
+       switch (lt->atype) {
+       case atype_integer:
+       case atype_float:
+       case atype_string:
+               ret = serialize_basic_type(lt->atype,
+                       &ut->u.basic, &lt->u.basic);
+               if (ret)
+                       return ret;
+               break;
+       case atype_array:
+       {
+               struct ustctl_basic_type *ubt;
+               const struct lttng_basic_type *lbt;
+               int ret;
+
+               ubt = &ut->u.array.elem_type;
+               lbt = &lt->u.array.elem_type;
+               ut->u.array.length = lt->u.array.length;
+               ret = serialize_basic_type(lbt->atype,
+                       &ubt->u.basic, &lbt->u.basic);
+               if (ret)
+                       return -EINVAL;
+               break;
+       }
+       case atype_sequence:
+       {
+               struct ustctl_basic_type *ubt;
+               const struct lttng_basic_type *lbt;
+               int ret;
+
+               ubt = &ut->u.sequence.length_type;
+               lbt = &lt->u.sequence.length_type;
+               ret = serialize_basic_type(lbt->atype,
+                       &ubt->u.basic, &lbt->u.basic);
+               if (ret)
+                       return -EINVAL;
+               ubt = &ut->u.sequence.elem_type;
+               lbt = &lt->u.sequence.elem_type;
+               ret = serialize_basic_type(lbt->atype,
+                       &ubt->u.basic, &lbt->u.basic);
+               if (ret)
+                       return -EINVAL;
+               break;
+       }
+       case atype_enum:
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static
+int serialize_fields(size_t *_nr_write_fields,
+               struct ustctl_field **ustctl_fields,
+               size_t nr_fields,
+               const struct lttng_event_field *lttng_fields)
+{
+       struct ustctl_field *fields;
+       int i, ret;
+       size_t nr_write_fields = 0;
+
+       fields = zmalloc(nr_fields * sizeof(*fields));
+       if (!fields)
+               return -ENOMEM;
+
+       for (i = 0; i < nr_fields; i++) {
+               struct ustctl_field *f;
+               const struct lttng_event_field *lf;
+
+               f = &fields[nr_write_fields];
+               lf = &lttng_fields[i];
+
+               /* skip 'nowrite' fields */
+               if (lf->nowrite)
+                       continue;
+               strncpy(f->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
+               f->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+               ret = serialize_one_type(&f->type, &lf->type);
+               if (ret)
+                       goto error_type;
+               nr_write_fields++;
+       }
+
+       *_nr_write_fields = nr_write_fields;
+       *ustctl_fields = fields;
+       return 0;
+
+error_type:
+       free(fields);
+       return ret;
+}
+
+/*
+ * Returns 0 on success, negative error value on error.
+ */
+int ustcomm_register_event(int sock,
+       int session_objd,               /* session descriptor */
+       int channel_objd,               /* channel descriptor */
+       const char *event_name,         /* event name (input) */
+       int loglevel,
+       const char *signature,          /* event signature (input) */
+       size_t nr_fields,               /* fields */
+       const struct lttng_event_field *lttng_fields,
+       const char *model_emf_uri,
+       uint32_t *id)                   /* event id (output) */
+{
+       ssize_t len;
+       struct {
+               struct ustcomm_notify_hdr header;
+               struct ustcomm_notify_event_msg m;
+       } msg;
+       struct {
+               struct ustcomm_notify_hdr header;
+               struct ustcomm_notify_event_reply r;
+       } reply;
+       size_t signature_len, fields_len, model_emf_uri_len;
+       struct ustctl_field *fields;
+       size_t nr_write_fields = 0;
+       int ret;
+
+       memset(&msg, 0, sizeof(msg));
+       msg.header.notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
+       msg.m.session_objd = session_objd;
+       msg.m.channel_objd = channel_objd;
+       strncpy(msg.m.event_name, event_name, LTTNG_UST_SYM_NAME_LEN);
+       msg.m.event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+       msg.m.loglevel = loglevel;
+       signature_len = strlen(signature) + 1;
+       msg.m.signature_len = signature_len;
+
+       /* Calculate fields len, serialize fields. */
+       if (nr_fields > 0) {
+               ret = serialize_fields(&nr_write_fields, &fields,
+                               nr_fields, lttng_fields);
+               if (ret)
+                       return ret;
+       }
+
+       fields_len = sizeof(*fields) * nr_write_fields;
+       msg.m.fields_len = fields_len;
+       if (model_emf_uri) {
+               model_emf_uri_len = strlen(model_emf_uri) + 1;
+       } else {
+               model_emf_uri_len = 0;
+       }
+       msg.m.model_emf_uri_len = model_emf_uri_len;
+       len = ustcomm_send_unix_sock(sock, &msg, sizeof(msg));
+       if (len > 0 && len != sizeof(msg)) {
+               free(fields);
+               return -EIO;
+       }
+       if (len < 0) {
+               free(fields);
+               return len;
+       }
+
+       /* send signature */
+       len = ustcomm_send_unix_sock(sock, signature, signature_len);
+       if (len > 0 && len != signature_len) {
+               free(fields);
+               return -EIO;
+       }
+       if (len < 0) {
+               free(fields);
+               return len;
+       }
+
+       /* send fields */
+       if (fields_len > 0) {
+               len = ustcomm_send_unix_sock(sock, fields, fields_len);
+               free(fields);
+               if (len > 0 && len != fields_len) {
+                       return -EIO;
+               }
+               if (len < 0) {
+                       return len;
+               }
+       }
+
+       if (model_emf_uri_len) {
+               /* send model_emf_uri */
+               len = ustcomm_send_unix_sock(sock, model_emf_uri,
+                               model_emf_uri_len);
+               if (len > 0 && len != model_emf_uri_len)
+                       return -EIO;
+               if (len < 0)
+                       return len;
+       }
+
+       /* receive reply */
+       len = ustcomm_recv_unix_sock(sock, &reply, sizeof(reply));
+       switch (len) {
+       case 0: /* orderly shutdown */
+               return -EPIPE;
+       case sizeof(reply):
+               if (reply.header.notify_cmd != msg.header.notify_cmd) {
+                       ERR("Unexpected result message command "
+                               "expected: %u vs received: %u\n",
+                               msg.header.notify_cmd, reply.header.notify_cmd);
+                       return -EINVAL;
+               }
+               if (reply.r.ret_code > 0)
+                       return -EINVAL;
+               if (reply.r.ret_code < 0)
+                       return reply.r.ret_code;
+               *id = reply.r.event_id;
+               DBG("Sent register event notification for name \"%s\": ret_code %d, event_id %u\n",
+                       event_name, reply.r.ret_code, reply.r.event_id);
+               return 0;
+       default:
+               if (len < 0) {
+                       /* Transport level error */
+                       if (errno == EPIPE || errno == ECONNRESET)
+                               len = -errno;
+                       return len;
+               } else {
+                       ERR("incorrect message size: %zd\n", len);
+                       return len;
+               }
+       }
+}
+
+/*
+ * Returns 0 on success, negative error value on error.
+ * Returns -EPIPE or -ECONNRESET if other end has hung up.
+ */
+int ustcomm_register_channel(int sock,
+       int session_objd,               /* session descriptor */
+       int channel_objd,               /* channel descriptor */
+       size_t nr_ctx_fields,
+       const struct lttng_event_field *ctx_fields,
+       uint32_t *chan_id,              /* channel id (output) */
+       int *header_type)               /* header type (output) */
+{
+       ssize_t len;
+       struct {
+               struct ustcomm_notify_hdr header;
+               struct ustcomm_notify_channel_msg m;
+       } msg;
+       struct {
+               struct ustcomm_notify_hdr header;
+               struct ustcomm_notify_channel_reply r;
+       } reply;
+       size_t fields_len;
+       struct ustctl_field *fields;
+       int ret;
+       size_t nr_write_fields = 0;
+
+       memset(&msg, 0, sizeof(msg));
+       msg.header.notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
+       msg.m.session_objd = session_objd;
+       msg.m.channel_objd = channel_objd;
+
+       /* Calculate fields len, serialize fields. */
+       if (nr_ctx_fields > 0) {
+               ret = serialize_fields(&nr_write_fields, &fields,
+                               nr_ctx_fields, ctx_fields);
+               if (ret)
+                       return ret;
+       }
+
+       fields_len = sizeof(*fields) * nr_write_fields;
+       msg.m.ctx_fields_len = fields_len;
+       len = ustcomm_send_unix_sock(sock, &msg, sizeof(msg));
+       if (len > 0 && len != sizeof(msg)) {
+               free(fields);
+               return -EIO;
+       }
+       if (len < 0) {
+               free(fields);
+               return len;
+       }
+
+       /* send fields */
+       if (fields_len > 0) {
+               len = ustcomm_send_unix_sock(sock, fields, fields_len);
+               free(fields);
+               if (len > 0 && len != fields_len) {
+                       return -EIO;
+               }
+               if (len < 0) {
+                       return len;
+               }
+       }
+
+       len = ustcomm_recv_unix_sock(sock, &reply, sizeof(reply));
+       switch (len) {
+       case 0: /* orderly shutdown */
+               return -EPIPE;
+       case sizeof(reply):
+               if (reply.header.notify_cmd != msg.header.notify_cmd) {
+                       ERR("Unexpected result message command "
+                               "expected: %u vs received: %u\n",
+                               msg.header.notify_cmd, reply.header.notify_cmd);
+                       return -EINVAL;
+               }
+               if (reply.r.ret_code > 0)
+                       return -EINVAL;
+               if (reply.r.ret_code < 0)
+                       return reply.r.ret_code;
+               *chan_id = reply.r.chan_id;
+               switch (reply.r.header_type) {
+               case 1:
+               case 2:
+                       *header_type = reply.r.header_type;
+                       break;
+               default:
+                       ERR("Unexpected channel header type %u\n",
+                               reply.r.header_type);
+                       return -EINVAL;
+               }
+               DBG("Sent register channel notification: chan_id %d, header_type %d\n",
+                       reply.r.chan_id, reply.r.header_type);
+               return 0;
+       default:
+               if (len < 0) {
+                       /* Transport level error */
+                       if (errno == EPIPE || errno == ECONNRESET)
+                               len = -errno;
+                       return len;
+               } else {
+                       ERR("incorrect message size: %zd\n", len);
+                       return len;
+               }
+       }
+}
index aed40f26382ac94f4ad38ec26cea3a350774e9be..d47a5b5055facc83c9ae01f7dbfb711cfcbc3040 100644 (file)
@@ -22,6 +22,7 @@
 #include <lttng/ust-abi.h>
 #include <lttng/ust-events.h>
 #include <sys/mman.h>
+#include <byteswap.h>
 
 #include <usterr-signal-safe.h>
 #include <ust-comm.h>
@@ -105,6 +106,9 @@ int ustctl_release_object(int sock, struct lttng_ust_object_data *data)
                        }
                }
                break;
+       case LTTNG_UST_OBJECT_TYPE_EVENT:
+       case LTTNG_UST_OBJECT_TYPE_CONTEXT:
+               break;
        default:
                assert(0);
        }
@@ -166,6 +170,7 @@ int ustctl_create_event(int sock, struct lttng_ust_event *ev,
        event_data = zmalloc(sizeof(*event_data));
        if (!event_data)
                return -ENOMEM;
+       event_data->type = LTTNG_UST_OBJECT_TYPE_EVENT;
        memset(&lum, 0, sizeof(lum));
        lum.handle = channel_data->handle;
        lum.cmd = LTTNG_UST_EVENT;
@@ -200,6 +205,7 @@ int ustctl_add_context(int sock, struct lttng_ust_context *ctx,
        context_data = zmalloc(sizeof(*context_data));
        if (!context_data)
                return -ENOMEM;
+       context_data->type = LTTNG_UST_OBJECT_TYPE_CONTEXT;
        memset(&lum, 0, sizeof(lum));
        lum.handle = obj_data->handle;
        lum.cmd = LTTNG_UST_CONTEXT;
@@ -209,8 +215,8 @@ int ustctl_add_context(int sock, struct lttng_ust_context *ctx,
                free(context_data);
                return ret;
        }
-       context_data->handle = lur.ret_val;
-       DBG("received context handle %u", context_data->handle);
+       context_data->handle = -1;
+       DBG("Context created successfully");
        *_context_data = context_data;
        return ret;
 }
@@ -779,7 +785,7 @@ struct ustctl_consumer_channel *
        transport = lttng_transport_find(transport_name);
        if (!transport) {
                DBG("LTTng transport %s not found\n",
-                      transport_name);
+                       transport_name);
                return NULL;
        }
 
@@ -788,9 +794,9 @@ struct ustctl_consumer_channel *
                return NULL;
 
        chan->chan = transport->ops.channel_create(transport_name, NULL,
-                        attr->subbuf_size, attr->num_subbuf,
+                       attr->subbuf_size, attr->num_subbuf,
                        attr->switch_timer_interval,
-                        attr->read_timer_interval,
+                       attr->read_timer_interval,
                        attr->uuid);
        if (!chan->chan) {
                goto chan_error;
@@ -1011,7 +1017,7 @@ int ustctl_get_mmap_read_offset(struct ustctl_consumer_stream *stream,
        if (chan->backend.config.output != RING_BUFFER_MMAP)
                return -EINVAL;
        sb_bindex = subbuffer_id_get_index(&chan->backend.config,
-                                          buf->backend.buf_rsb.id);
+                                       buf->backend.buf_rsb.id);
        *off = shmp(consumer_chan->chan->handle,
                shmp_index(consumer_chan->chan->handle, buf->backend.array, sb_bindex)->shmp)->mmap_offset;
        return 0;
@@ -1169,6 +1175,344 @@ void ustctl_flush_buffer(struct ustctl_consumer_stream *stream,
                consumer_chan->chan->handle);
 }
 
+/*
+ * Returns 0 on success, negative error value on error.
+ */
+int ustctl_recv_reg_msg(int sock,
+       enum ustctl_socket_type *type,
+       uint32_t *major,
+       uint32_t *minor,
+       uint32_t *pid,
+       uint32_t *ppid,
+       uint32_t *uid,
+       uint32_t *gid,
+       uint32_t *bits_per_long,
+       uint32_t *uint8_t_alignment,
+       uint32_t *uint16_t_alignment,
+       uint32_t *uint32_t_alignment,
+       uint32_t *uint64_t_alignment,
+       uint32_t *long_alignment,
+       int *byte_order,
+       char *name)
+{
+       ssize_t len;
+       struct ustctl_reg_msg reg_msg;
+
+       len = ustcomm_recv_unix_sock(sock, &reg_msg, sizeof(reg_msg));
+       if (len > 0 && len != sizeof(reg_msg))
+               return -EIO;
+       if (len == 0)
+               return -EPIPE;
+       if (len < 0)
+               return len;
+
+       if (reg_msg.magic == LTTNG_UST_COMM_MAGIC) {
+               *byte_order = BYTE_ORDER == BIG_ENDIAN ?
+                               BIG_ENDIAN : LITTLE_ENDIAN;
+       } else if (reg_msg.magic == bswap_32(LTTNG_UST_COMM_MAGIC)) {
+               *byte_order = BYTE_ORDER == BIG_ENDIAN ?
+                               LITTLE_ENDIAN : BIG_ENDIAN;
+       } else {
+               return -LTTNG_UST_ERR_INVAL_MAGIC;
+       }
+       switch (reg_msg.socket_type) {
+       case 0: *type = USTCTL_SOCKET_CMD;
+               break;
+       case 1: *type = USTCTL_SOCKET_NOTIFY;
+               break;
+       default:
+               return -LTTNG_UST_ERR_INVAL_SOCKET_TYPE;
+       }
+       *major = reg_msg.major;
+       *minor = reg_msg.minor;
+       *pid = reg_msg.pid;
+       *ppid = reg_msg.ppid;
+       *uid = reg_msg.uid;
+       *gid = reg_msg.gid;
+       *bits_per_long = reg_msg.bits_per_long;
+       *uint8_t_alignment = reg_msg.uint8_t_alignment;
+       *uint16_t_alignment = reg_msg.uint16_t_alignment;
+       *uint32_t_alignment = reg_msg.uint32_t_alignment;
+       *uint64_t_alignment = reg_msg.uint64_t_alignment;
+       *long_alignment = reg_msg.long_alignment;
+       memcpy(name, reg_msg.name, LTTNG_UST_ABI_PROCNAME_LEN);
+       if (reg_msg.major != LTTNG_UST_ABI_MAJOR_VERSION) {
+               return -LTTNG_UST_ERR_UNSUP_MAJOR;
+       }
+
+       return 0;
+}
+
+int ustctl_recv_notify(int sock, enum ustctl_notify_cmd *notify_cmd)
+{
+       struct ustcomm_notify_hdr header;
+       ssize_t len;
+
+       len = ustcomm_recv_unix_sock(sock, &header, sizeof(header));
+       if (len > 0 && len != sizeof(header))
+               return -EIO;
+       if (len == 0)
+               return -EPIPE;
+       if (len < 0)
+               return len;
+       switch (header.notify_cmd) {
+       case 0:
+               *notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
+               break;
+       case 1:
+               *notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+/*
+ * Returns 0 on success, negative error value on error.
+ */
+int ustctl_recv_register_event(int sock,
+       int *session_objd,
+       int *channel_objd,
+       char *event_name,
+       int *loglevel,
+       char **signature,
+       size_t *nr_fields,
+       struct ustctl_field **fields,
+       char **model_emf_uri)
+{
+       ssize_t len;
+       struct ustcomm_notify_event_msg msg;
+       size_t signature_len, fields_len, model_emf_uri_len;
+       char *a_sign = NULL, *a_model_emf_uri = NULL;
+       struct ustctl_field *a_fields = NULL;
+
+       len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
+       if (len > 0 && len != sizeof(msg))
+               return -EIO;
+       if (len == 0)
+               return -EPIPE;
+       if (len < 0)
+               return len;
+
+       *session_objd = msg.session_objd;
+       *channel_objd = msg.channel_objd;
+       strncpy(event_name, msg.event_name, LTTNG_UST_SYM_NAME_LEN);
+       event_name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+       *loglevel = msg.loglevel;
+       signature_len = msg.signature_len;
+       fields_len = msg.fields_len;
+
+       if (fields_len % sizeof(*a_fields) != 0) {
+               return -EINVAL;
+       }
+
+       model_emf_uri_len = msg.model_emf_uri_len;
+
+       /* recv signature. contains at least \0. */
+       a_sign = zmalloc(signature_len);
+       if (!a_sign)
+               return -ENOMEM;
+       len = ustcomm_recv_unix_sock(sock, a_sign, signature_len);
+       if (len > 0 && len != signature_len) {
+               len = -EIO;
+               goto signature_error;
+       }
+       if (len == 0) {
+               len = -EPIPE;
+               goto signature_error;
+       }
+       if (len < 0) {
+               goto signature_error;
+       }
+       /* Enforce end of string */
+       signature[signature_len - 1] = '\0';
+
+       /* recv fields */
+       if (fields_len) {
+               a_fields = zmalloc(fields_len);
+               if (!a_fields) {
+                       len = -ENOMEM;
+                       goto signature_error;
+               }
+               len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
+               if (len > 0 && len != fields_len) {
+                       len = -EIO;
+                       goto fields_error;
+               }
+               if (len == 0) {
+                       len = -EPIPE;
+                       goto fields_error;
+               }
+               if (len < 0) {
+                       goto fields_error;
+               }
+       }
+
+       if (model_emf_uri_len) {
+               /* recv model_emf_uri_len */
+               a_model_emf_uri = zmalloc(model_emf_uri_len);
+               if (!a_model_emf_uri) {
+                       len = -ENOMEM;
+                       goto fields_error;
+               }
+               len = ustcomm_recv_unix_sock(sock, a_model_emf_uri,
+                               model_emf_uri_len);
+               if (len > 0 && len != model_emf_uri_len) {
+                       len = -EIO;
+                       goto model_error;
+               }
+               if (len == 0) {
+                       len = -EPIPE;
+                       goto model_error;
+               }
+               if (len < 0) {
+                       goto model_error;
+               }
+               /* Enforce end of string */
+               a_model_emf_uri[model_emf_uri_len - 1] = '\0';
+       }
+
+       *signature = a_sign;
+       *nr_fields = fields_len / sizeof(*a_fields);
+       *fields = a_fields;
+       *model_emf_uri = a_model_emf_uri;
+
+       return 0;
+
+model_error:
+       free(a_model_emf_uri);
+fields_error:
+       free(a_fields);
+signature_error:
+       free(a_sign);
+       return len;
+}
+
+/*
+ * Returns 0 on success, negative error value on error.
+ */
+int ustctl_reply_register_event(int sock,
+       uint32_t id,
+       int ret_code)
+{
+       ssize_t len;
+       struct {
+               struct ustcomm_notify_hdr header;
+               struct ustcomm_notify_event_reply r;
+       } reply;
+
+       memset(&reply, 0, sizeof(reply));
+       reply.header.notify_cmd = USTCTL_NOTIFY_CMD_EVENT;
+       reply.r.ret_code = ret_code;
+       reply.r.event_id = id;
+       len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
+       if (len > 0 && len != sizeof(reply))
+               return -EIO;
+       if (len < 0)
+               return len;
+       return 0;
+}
+
+/*
+ * Returns 0 on success, negative UST or system error value on error.
+ */
+int ustctl_recv_register_channel(int sock,
+       int *session_objd,              /* session descriptor (output) */
+       int *channel_objd,              /* channel descriptor (output) */
+       size_t *nr_fields,
+       struct ustctl_field **fields)
+{
+       ssize_t len;
+       struct ustcomm_notify_channel_msg msg;
+       size_t fields_len;
+       struct ustctl_field *a_fields;
+
+       len = ustcomm_recv_unix_sock(sock, &msg, sizeof(msg));
+       if (len > 0 && len != sizeof(msg))
+               return -EIO;
+       if (len == 0)
+               return -EPIPE;
+       if (len < 0)
+               return len;
+
+       *session_objd = msg.session_objd;
+       *channel_objd = msg.channel_objd;
+       fields_len = msg.ctx_fields_len;
+
+       if (fields_len % sizeof(*a_fields) != 0) {
+               return -EINVAL;
+       }
+
+       /* recv fields */
+       if (fields_len) {
+               a_fields = zmalloc(fields_len);
+               if (!a_fields) {
+                       len = -ENOMEM;
+                       goto alloc_error;
+               }
+               len = ustcomm_recv_unix_sock(sock, a_fields, fields_len);
+               if (len > 0 && len != fields_len) {
+                       len = -EIO;
+                       goto fields_error;
+               }
+               if (len == 0) {
+                       len = -EPIPE;
+                       goto fields_error;
+               }
+               if (len < 0) {
+                       goto fields_error;
+               }
+               *fields = a_fields;
+       } else {
+               *fields = NULL;
+       }
+       *nr_fields = fields_len / sizeof(*a_fields);
+       return 0;
+
+fields_error:
+       free(a_fields);
+alloc_error:
+       return len;
+}
+
+/*
+ * Returns 0 on success, negative error value on error.
+ */
+int ustctl_reply_register_channel(int sock,
+       uint32_t chan_id,
+       enum ustctl_channel_header header_type,
+       int ret_code)
+{
+       ssize_t len;
+       struct {
+               struct ustcomm_notify_hdr header;
+               struct ustcomm_notify_channel_reply r;
+       } reply;
+
+       memset(&reply, 0, sizeof(reply));
+       reply.header.notify_cmd = USTCTL_NOTIFY_CMD_CHANNEL;
+       reply.r.ret_code = ret_code;
+       reply.r.chan_id = chan_id;
+       switch (header_type) {
+       case USTCTL_CHANNEL_HEADER_COMPACT:
+               reply.r.header_type = 1;
+               break;
+       case USTCTL_CHANNEL_HEADER_LARGE:
+               reply.r.header_type = 2;
+               break;
+       default:
+               reply.r.header_type = 0;
+               break;
+       }
+       len = ustcomm_send_unix_sock(sock, &reply, sizeof(reply));
+       if (len > 0 && len != sizeof(reply))
+               return -EIO;
+       if (len < 0)
+               return len;
+       return 0;
+}
+
 static __attribute__((constructor))
 void ustctl_init(void)
 {
index 3bf1ede3a6a30836d50e35f48fd837da79815c89..f77db60c512f7d3d1f7a5d6bdef970d307368a4e 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <usterr-signal-safe.h>
 #include <helper.h>
+#include <ust-ctl.h>
+#include <ust-comm.h>
 #include "error.h"
 #include "compat.h"
 #include "lttng-ust-uuid.h"
@@ -203,12 +205,17 @@ int lttng_session_enable(struct lttng_session *session)
 {
        int ret = 0;
        struct lttng_channel *chan;
+       int notify_socket;
 
        if (session->active) {
                ret = -EBUSY;
                goto end;
        }
 
+       notify_socket = lttng_get_notify_socket(session->owner);
+       if (notify_socket < 0)
+               return notify_socket;
+
        /* We need to sync enablers with session before activation. */
        lttng_session_sync_enablers(session);
 
@@ -217,12 +224,27 @@ int lttng_session_enable(struct lttng_session *session)
         * we need to use.
         */
        cds_list_for_each_entry(chan, &session->chan_head, node) {
+               const struct lttng_ctx *ctx;
+               const struct lttng_event_field *fields = NULL;
+               size_t nr_fields = 0;
+
+               /* don't change it if session stop/restart */
                if (chan->header_type)
-                       continue;               /* don't change it if session stop/restart */
-               if (chan->free_event_id < 31)
-                       chan->header_type = 1;  /* compact */
-               else
-                       chan->header_type = 2;  /* large */
+                       continue;
+               ctx = chan->ctx;
+               if (ctx) {
+                       nr_fields = ctx->nr_fields;
+                       fields = &ctx->fields->event_field;
+               }
+               ret = ustcomm_register_channel(notify_socket,
+                       session->objd,
+                       chan->objd,
+                       nr_fields,
+                       fields,
+                       &chan->id,
+                       &chan->header_type);
+               if (ret)
+                       return ret;
        }
 
        CMM_ACCESS_ONCE(session->active) = 1;
@@ -304,16 +326,15 @@ int lttng_event_create(const struct lttng_event_desc *desc,
 {
        const char *event_name = desc->name;
        struct lttng_event *event;
+       struct lttng_session *session = chan->session;
        struct cds_hlist_head *head;
        struct cds_hlist_node *node;
        int ret = 0;
        size_t name_len = strlen(event_name);
        uint32_t hash;
+       int notify_socket, loglevel;
+       const char *uri;
 
-       if (chan->used_event_id == -1U) {
-               ret = -ENOMEM;
-               goto full;
-       }
        hash = jhash(event_name, name_len, 0);
        head = &chan->session->events_ht.table[hash & (LTTNG_UST_EVENT_HT_SIZE - 1)];
        cds_hlist_for_each_entry(event, node, head, hlist) {
@@ -326,6 +347,12 @@ int lttng_event_create(const struct lttng_event_desc *desc,
                }
        }
 
+       notify_socket = lttng_get_notify_socket(session->owner);
+       if (notify_socket < 0) {
+               ret = notify_socket;
+               goto socket_error;
+       }
+
        /*
         * Check if loglevel match. Refuse to connect event if not.
         */
@@ -336,23 +363,42 @@ int lttng_event_create(const struct lttng_event_desc *desc,
        }
        event->chan = chan;
 
-       /*
-        * used_event_id counts the maximum number of event IDs that can
-        * register if all probes register.
-        */
-       chan->used_event_id++;
        event->enabled = 1;
        CDS_INIT_LIST_HEAD(&event->bytecode_runtime_head);
        CDS_INIT_LIST_HEAD(&event->enablers_ref_head);
        event->desc = desc;
+
+       if (desc->loglevel)
+               loglevel = *(*event->desc->loglevel);
+       else
+               loglevel = TRACE_DEFAULT;
+       if (desc->u.ext.model_emf_uri)
+               uri = *(desc->u.ext.model_emf_uri);
+       else
+               uri = NULL;
+
+       /* Fetch event ID from sessiond */
+       ret = ustcomm_register_event(notify_socket,
+               session->objd,
+               chan->objd,
+               event_name,
+               loglevel,
+               desc->signature,
+               desc->nr_fields,
+               desc->fields,
+               uri,
+               &event->id);
+       if (ret < 0) {
+               goto sessiond_register_error;
+       }
        /* Populate lttng_event structure before tracepoint registration. */
        cmm_smp_wmb();
        ret = __tracepoint_probe_register(event_name,
                        desc->probe_callback,
                        event, desc->signature);
        if (ret)
-               goto register_error;
-       event->id = chan->free_event_id++;
+               goto tracepoint_register_error;
+
        ret = _lttng_event_metadata_statedump(chan->session, chan, event);
        if (ret)
                goto statedump_error;
@@ -364,11 +410,12 @@ statedump_error:
        WARN_ON_ONCE(__tracepoint_probe_unregister(event_name,
                                desc->probe_callback,
                                event));
-register_error:
+tracepoint_register_error:
+sessiond_register_error:
        free(event);
 cache_error:
+socket_error:
 exist:
-full:
        return ret;
 }
 
@@ -507,8 +554,8 @@ void lttng_create_event_if_missing(struct lttng_enabler *enabler)
                        ret = lttng_event_create(probe_desc->event_desc[i],
                                        enabler->chan);
                        if (ret) {
-                               DBG("Unable to create event %s\n",
-                                       probe_desc->event_desc[i]->name);
+                               DBG("Unable to create event %s, error %d\n",
+                                       probe_desc->event_desc[i]->name, ret);
                        }
                }
        }
index f2e95674b2373b2dd8ed7bb194c64e9ad37c57f8..f643a7e5023f85fcb8091b56930d7cfaa8d0f95a 100644 (file)
@@ -43,4 +43,6 @@ void lttng_fixup_procname_tls(void);
 
 const char *lttng_ust_obj_get_name(int id);
 
+int lttng_get_notify_socket(void *owner);
+
 #endif /* _LTTNG_TRACER_CORE_H */
index 006e996264f8964e38f67038dec09d1d508be19f..1e146e6196512cc545485c17da935240edb7ae31 100644 (file)
@@ -294,6 +294,7 @@ int lttng_abi_create_session(void *owner)
                goto objd_error;
        }
        session->objd = session_objd;
+       session->owner = owner;
        return session_objd;
 
 objd_error:
@@ -305,9 +306,9 @@ static
 long lttng_abi_tracer_version(int objd,
        struct lttng_ust_tracer_version *v)
 {
-       v->major = LTTNG_UST_INTERNAL_MAJOR_VERSION;
-       v->minor = LTTNG_UST_INTERNAL_MINOR_VERSION;
-       v->patchlevel = LTTNG_UST_INTERNAL_PATCHLEVEL_VERSION;
+       v->major = LTTNG_UST_MAJOR_VERSION;
+       v->minor = LTTNG_UST_MINOR_VERSION;
+       v->patchlevel = LTTNG_UST_PATCHLEVEL_VERSION;
        return 0;
 }
 
@@ -498,8 +499,6 @@ int lttng_abi_map_channel(int session_objd,
        lttng_chan->enabled = 1;
        lttng_chan->ctx = NULL;
        lttng_chan->session = session;
-       lttng_chan->free_event_id = 0;
-       lttng_chan->used_event_id = 0;
        lttng_chan->ops = &transport->ops;
        memcpy(&lttng_chan->chan->backend.config,
                transport->client_config,
@@ -508,7 +507,6 @@ int lttng_abi_map_channel(int session_objd,
        lttng_chan->header_type = 0;
        lttng_chan->handle = channel_handle;
        lttng_chan->metadata_dumped = 0;
-       lttng_chan->id = session->free_chan_id++;
        lttng_chan->type = type;
 
        /*
index a1ebcbe6fc83564a5fc4d9c0c0642403938da35f..5a4b6bd8693ed5b427f8baf693a903949d025547 100644 (file)
@@ -102,6 +102,7 @@ struct sock_info {
 
        char sock_path[PATH_MAX];
        int socket;
+       int notify_socket;
 
        char wait_shm_path[PATH_MAX];
        char *wait_shm_mmap;
@@ -116,10 +117,11 @@ struct sock_info global_apps = {
        .allowed = 1,
        .thread_active = 0,
 
-       .sock_path = DEFAULT_GLOBAL_APPS_UNIX_SOCK,
+       .sock_path = LTTNG_DEFAULT_RUNDIR "/" LTTNG_UST_SOCK_FILENAME,
        .socket = -1,
+       .notify_socket = -1,
 
-       .wait_shm_path = DEFAULT_GLOBAL_APPS_WAIT_SHM_PATH,
+       .wait_shm_path = "/" LTTNG_UST_WAIT_FILENAME,
 };
 
 /* TODO: allow global_apps_sock_path override */
@@ -132,6 +134,7 @@ struct sock_info local_apps = {
        .thread_active = 0,
 
        .socket = -1,
+       .notify_socket = -1,
 };
 
 static int wait_poll_fallback;
@@ -187,6 +190,13 @@ void lttng_fixup_nest_count_tls(void)
        asm volatile ("" : : "m" (URCU_TLS(lttng_ust_nest_count)));
 }
 
+int lttng_get_notify_socket(void *owner)
+{
+       struct sock_info *info = owner;
+
+       return info->notify_socket;
+}
+
 static
 void print_cmd(int cmd, int handle)
 {
@@ -220,41 +230,27 @@ int setup_local_apps(void)
                return -ENOENT;
        }
        local_apps.allowed = 1;
-       snprintf(local_apps.sock_path, PATH_MAX,
-                DEFAULT_HOME_APPS_UNIX_SOCK, home_dir);
-       snprintf(local_apps.wait_shm_path, PATH_MAX,
-                DEFAULT_HOME_APPS_WAIT_SHM_PATH, uid);
+       snprintf(local_apps.sock_path, PATH_MAX, "%s/%s/%s",
+               home_dir,
+               LTTNG_DEFAULT_HOME_RUNDIR,
+               LTTNG_UST_SOCK_FILENAME);
+       snprintf(local_apps.wait_shm_path, PATH_MAX, "/%s-%u",
+               LTTNG_UST_WAIT_FILENAME,
+               uid);
        return 0;
 }
 
 static
-int register_app_to_sessiond(int socket)
+int register_to_sessiond(int socket, enum ustctl_socket_type type)
 {
-       ssize_t ret;
-       struct {
-               uint32_t major;
-               uint32_t minor;
-               pid_t pid;
-               pid_t ppid;
-               uid_t uid;
-               gid_t gid;
-               uint32_t bits_per_long;
-               char name[16];  /* process name */
-       } reg_msg;
-
-       reg_msg.major = LTTNG_UST_COMM_VERSION_MAJOR;
-       reg_msg.minor = LTTNG_UST_COMM_VERSION_MINOR;
-       reg_msg.pid = getpid();
-       reg_msg.ppid = getppid();
-       reg_msg.uid = getuid();
-       reg_msg.gid = getgid();
-       reg_msg.bits_per_long = CAA_BITS_PER_LONG;
-       lttng_ust_getprocname(reg_msg.name);
-
-       ret = ustcomm_send_unix_sock(socket, &reg_msg, sizeof(reg_msg));
-       if (ret >= 0 && ret != sizeof(reg_msg))
-               return -EIO;
-       return ret;
+       return ustcomm_send_reg_msg(socket,
+               type,
+               CAA_BITS_PER_LONG,
+               lttng_alignof(uint8_t) * CHAR_BIT,
+               lttng_alignof(uint16_t) * CHAR_BIT,
+               lttng_alignof(uint32_t) * CHAR_BIT,
+               lttng_alignof(uint64_t) * CHAR_BIT,
+               lttng_alignof(unsigned long) * CHAR_BIT);
 }
 
 static
@@ -561,10 +557,17 @@ void cleanup_sock_info(struct sock_info *sock_info, int exiting)
        if (sock_info->socket != -1) {
                ret = ustcomm_close_unix_sock(sock_info->socket);
                if (ret) {
-                       ERR("Error closing apps socket");
+                       ERR("Error closing ust cmd socket");
                }
                sock_info->socket = -1;
        }
+       if (sock_info->notify_socket != -1) {
+               ret = ustcomm_close_unix_sock(sock_info->notify_socket);
+               if (ret) {
+                       ERR("Error closing ust notify socket");
+               }
+               sock_info->notify_socket = -1;
+       }
        if (sock_info->root_handle != -1) {
                ret = lttng_ust_objd_unref(sock_info->root_handle);
                if (ret) {
@@ -815,6 +818,8 @@ void *ust_listener_thread(void *arg)
 {
        struct sock_info *sock_info = arg;
        int sock, ret, prev_connect_failed = 0, has_waited = 0;
+       int open_sock[2];
+       int i;
 
        /* Restart trying to connect to the session daemon */
 restart:
@@ -842,27 +847,40 @@ restart:
        if (sock_info->socket != -1) {
                ret = ustcomm_close_unix_sock(sock_info->socket);
                if (ret) {
-                       ERR("Error closing %s apps socket", sock_info->name);
+                       ERR("Error closing %s ust cmd socket",
+                               sock_info->name);
                }
                sock_info->socket = -1;
        }
+       if (sock_info->notify_socket != -1) {
+               ret = ustcomm_close_unix_sock(sock_info->notify_socket);
+               if (ret) {
+                       ERR("Error closing %s ust notify socket",
+                               sock_info->name);
+               }
+               sock_info->notify_socket = -1;
+       }
 
        /* Register */
-       ret = ustcomm_connect_unix_sock(sock_info->sock_path);
-       if (ret < 0) {
-               DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name);
-               prev_connect_failed = 1;
-               /*
-                * If we cannot find the sessiond daemon, don't delay
-                * constructor execution.
-                */
-               ret = handle_register_done(sock_info);
-               assert(!ret);
-               ust_unlock();
-               goto restart;
+       for (i = 0; i < 2; i++) {
+               ret = ustcomm_connect_unix_sock(sock_info->sock_path);
+               if (ret < 0) {
+                       DBG("Info: sessiond not accepting connections to %s apps socket", sock_info->name);
+                       prev_connect_failed = 1;
+                       /*
+                        * If we cannot find the sessiond daemon, don't delay
+                        * constructor execution.
+                        */
+                       ret = handle_register_done(sock_info);
+                       assert(!ret);
+                       ust_unlock();
+                       goto restart;
+               }
+               open_sock[i] = ret;
        }
 
-       sock_info->socket = sock = ret;
+       sock_info->socket = open_sock[0];
+       sock_info->notify_socket = open_sock[1];
 
        /*
         * Create only one root handle per listener thread for the whole
@@ -878,9 +896,10 @@ restart:
                sock_info->root_handle = ret;
        }
 
-       ret = register_app_to_sessiond(sock);
+       ret = register_to_sessiond(sock_info->socket, USTCTL_SOCKET_CMD);
        if (ret < 0) {
-               ERR("Error registering to %s apps socket", sock_info->name);
+               ERR("Error registering to %s ust cmd socket",
+                       sock_info->name);
                prev_connect_failed = 1;
                /*
                 * If we cannot register to the sessiond daemon, don't
@@ -891,6 +910,23 @@ restart:
                ust_unlock();
                goto restart;
        }
+       ret = register_to_sessiond(sock_info->notify_socket,
+                       USTCTL_SOCKET_NOTIFY);
+       if (ret < 0) {
+               ERR("Error registering to %s ust notify socket",
+                       sock_info->name);
+               prev_connect_failed = 1;
+               /*
+                * If we cannot register to the sessiond daemon, don't
+                * delay constructor execution.
+                */
+               ret = handle_register_done(sock_info);
+               assert(!ret);
+               ust_unlock();
+               goto restart;
+       }
+       sock = sock_info->socket;
+
        ust_unlock();
 
        for (;;) {
This page took 0.050481 seconds and 4 git commands to generate.