*/
int lttcomm_create_inet_sock(struct lttcomm_sock *sock, int type, int proto)
{
- int val, ret;
+ int val = 1, ret;
/* Create server socket */
if ((sock->fd = socket(PF_INET, type, proto)) < 0) {
goto end;
}
- new_sock = lttcomm_alloc_sock(LTTCOMM_INET, sock->proto);
+ new_sock = lttcomm_alloc_sock(sock->proto);
if (new_sock == NULL) {
goto error;
}
}
new_sock->fd = new_fd;
+ new_sock->ops = &inet_ops;
end:
return new_sock;
{
int ret;
- /* Don't try to close an invalid mark socket */
+ /* Don't try to close an invalid marked socket */
if (sock->fd == -1) {
return 0;
}
*/
int lttcomm_create_inet6_sock(struct lttcomm_sock *sock, int type, int proto)
{
- int val, ret;
+ int val = 1, ret;
/* Create server socket */
if ((sock->fd = socket(PF_INET, type, proto)) < 0) {
goto end;
}
- new_sock = lttcomm_alloc_sock(LTTCOMM_INET, sock->proto);
+ new_sock = lttcomm_alloc_sock(sock->proto);
if (new_sock == NULL) {
goto error;
}
}
new_sock->fd = new_fd;
+ new_sock->ops = &inet6_ops;
end:
return new_sock;
{
int ret;
- /* Don't try to close an invalid mark socket */
+ /* Don't try to close an invalid marked socket */
if (sock->fd == -1) {
return 0;
}
[ LTTCOMM_ERR_INDEX(LTTCOMM_NO_USTCONSUMERD) ] = "No UST consumer detected",
[ LTTCOMM_ERR_INDEX(LTTCOMM_NO_KERNCONSUMERD) ] = "No kernel consumer detected",
[ LTTCOMM_ERR_INDEX(LTTCOMM_EVENT_EXIST_LOGLEVEL) ] = "Event already enabled with different loglevel",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_URI_DATA_MISS) ] = "Missing data path URI",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_URI_CTRL_MISS) ] = "Missing control data path URI",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_ENABLE_CONSUMER_FAIL) ] = "Enabling consumer failed",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_RELAYD_SESSION_FAIL) ] = "Unable to create session on lttng-relayd",
+ [ LTTCOMM_ERR_INDEX(LTTCOMM_RELAYD_VERSION_FAIL) ] = "Relay daemon not compatible",
};
/*
}
/*
- * Alloc lttcomm socket and set protocol.
+ * Create socket from an already allocated lttcomm socket structure and init
+ * sockaddr in the lttcomm sock.
*/
-static struct lttcomm_sock *alloc_sock(enum lttcomm_sock_proto proto)
+int lttcomm_create_sock(struct lttcomm_sock *sock)
{
- struct lttcomm_sock *sock;
+ int ret, _sock_type, _sock_proto, domain;
- sock = zmalloc(sizeof(struct lttcomm_sock));
- if (sock == NULL) {
- PERROR("zmalloc create sock");
- goto end;
+ assert(sock);
+
+ domain = sock->sockaddr.type;
+ if (domain != LTTCOMM_INET && domain != LTTCOMM_INET6) {
+ ERR("Create socket of unknown domain %d", domain);
+ ret = -1;
+ goto error;
}
- sock->proto = proto;
+ switch (sock->proto) {
+ case LTTCOMM_SOCK_UDP:
+ _sock_type = SOCK_DGRAM;
+ _sock_proto = IPPROTO_UDP;
+ break;
+ case LTTCOMM_SOCK_TCP:
+ _sock_type = SOCK_STREAM;
+ _sock_proto = IPPROTO_TCP;
+ break;
+ default:
+ ret = -1;
+ goto error;
+ }
-end:
- return sock;
+ ret = net_families[domain].create(sock, _sock_type, _sock_proto);
+ if (ret < 0) {
+ goto error;
+ }
+
+error:
+ return ret;
}
/*
- * Create socket from an already allocated lttcomm socket structure.
+ * Return allocated lttcomm socket structure.
*/
-int lttcomm_create_sock(struct lttcomm_sock *sock,
- enum lttcomm_sock_domain domain, enum lttcomm_sock_proto proto)
+struct lttcomm_sock *lttcomm_alloc_sock(enum lttcomm_sock_proto proto)
{
- int ret, _sock_type, _sock_proto;
-
- assert(sock);
-
- switch (proto) {
- case LTTCOMM_SOCK_UDP:
- _sock_type = SOCK_DGRAM;
- _sock_proto = IPPROTO_UDP;
- break;
- case LTTCOMM_SOCK_TCP:
- _sock_type = SOCK_STREAM;
- _sock_proto = IPPROTO_TCP;
- break;
- default:
- ret = -1;
- goto error;
- }
+ struct lttcomm_sock *sock;
- ret = net_families[domain].create(sock, _sock_type, _sock_proto);
- if (ret < 0) {
- goto error;
+ sock = zmalloc(sizeof(struct lttcomm_sock));
+ if (sock == NULL) {
+ PERROR("zmalloc create sock");
+ goto end;
}
sock->proto = proto;
+ sock->fd = -1;
-error:
- return ret;
+end:
+ return sock;
}
/*
- * Return allocated lttcomm socket structure.
+ * Return an allocated lttcomm socket structure and copy src content into
+ * the newly created socket.
+ *
+ * This is mostly useful when lttcomm_sock are passed between process where the
+ * fd and ops have to be changed within the correct address space.
*/
-struct lttcomm_sock *lttcomm_alloc_sock(enum lttcomm_sock_domain domain,
- enum lttcomm_sock_proto proto)
+struct lttcomm_sock *lttcomm_alloc_copy_sock(struct lttcomm_sock *src)
{
- int ret;
struct lttcomm_sock *sock;
- sock = alloc_sock(proto);
+ /* Safety net */
+ assert(src);
+
+ sock = lttcomm_alloc_sock(src->proto);
if (sock == NULL) {
goto alloc_error;
}
- ret = lttcomm_create_sock(sock, domain, proto);
- if (ret < 0) {
- goto error;
- }
+ lttcomm_copy_sock(sock, src);
+alloc_error:
return sock;
+}
-error:
- free(sock);
-alloc_error:
- return NULL;
+/*
+ * Create and copy socket from an allocated lttcomm socket structure.
+ *
+ * This is mostly useful when lttcomm_sock are passed between process where the
+ * fd and ops have to be changed within the correct address space.
+ */
+void lttcomm_copy_sock(struct lttcomm_sock *dst, struct lttcomm_sock *src)
+{
+ /* Safety net */
+ assert(dst);
+ assert(src);
+
+ dst->proto = src->proto;
+ dst->fd = src->fd;
+ dst->ops = src->ops;
+ /* Copy sockaddr information from original socket */
+ memcpy(&dst->sockaddr, &src->sockaddr, sizeof(dst->sockaddr));
}
/*
&sockaddr->addr.sin.sin_addr);
if (ret < 1) {
ret = -1;
+ ERR("%s with port %d: unrecognized IPv4 address", ip, port);
goto error;
}
memset(sockaddr->addr.sin.sin_zero, 0, sizeof(sockaddr->addr.sin.sin_zero));
error:
return ret;
}
+
+/*
+ * Return allocated lttcomm socket structure from lttng URI.
+ */
+struct lttcomm_sock *lttcomm_alloc_sock_from_uri(struct lttng_uri *uri)
+{
+ int ret;
+ int _sock_proto;
+ struct lttcomm_sock *sock = NULL;
+
+ /* Safety net */
+ assert(uri);
+
+ /* Check URI protocol */
+ if (uri->proto == LTTNG_TCP) {
+ _sock_proto = LTTCOMM_SOCK_TCP;
+ } else {
+ ERR("Relayd invalid URI proto: %d", uri->proto);
+ goto alloc_error;
+ }
+
+ sock = lttcomm_alloc_sock(_sock_proto);
+ if (sock == NULL) {
+ goto alloc_error;
+ }
+
+ /* Check destination type */
+ if (uri->dtype == LTTNG_DST_IPV4) {
+ ret = lttcomm_init_inet_sockaddr(&sock->sockaddr, uri->dst.ipv4,
+ uri->port);
+ if (ret < 0) {
+ goto error;
+ }
+ } else if (uri->dtype == LTTNG_DST_IPV6) {
+ ret = lttcomm_init_inet6_sockaddr(&sock->sockaddr, uri->dst.ipv6,
+ uri->port);
+ if (ret < 0) {
+ goto error;
+ }
+ } else {
+ /* Command URI is invalid */
+ ERR("Relayd invalid URI dst type: %d", uri->dtype);
+ goto error;
+ }
+
+ return sock;
+
+error:
+ lttcomm_destroy_sock(sock);
+alloc_error:
+ return NULL;
+}
+
+/*
+ * Destroy and free lttcomm socket.
+ */
+void lttcomm_destroy_sock(struct lttcomm_sock *sock)
+{
+ if (sock != NULL) {
+ free(sock);
+ }
+}
LTTNG_ENABLE_ALL_EVENT,
/* Session daemon command */
LTTNG_CREATE_SESSION,
+ LTTNG_CREATE_SESSION_URI,
LTTNG_DESTROY_SESSION,
LTTNG_LIST_CHANNELS,
LTTNG_LIST_DOMAINS,
LTTNG_START_TRACE,
LTTNG_STOP_TRACE,
LTTNG_LIST_TRACEPOINT_FIELDS,
+ /* Consumer */
+ LTTNG_DISABLE_CONSUMER,
+ LTTNG_ENABLE_CONSUMER,
+ LTTNG_SET_CONSUMER_URI,
+ /* Relay daemon */
+ RELAYD_ADD_STREAM,
+ RELAYD_CREATE_SESSION,
+ RELAYD_START_DATA,
+ RELAYD_UPDATE_SYNC_INFO,
+ RELAYD_VERSION,
+ RELAYD_SEND_METADATA,
};
/*
LTTCOMM_NO_USTCONSUMERD, /* No UST consumer detected */
LTTCOMM_NO_KERNCONSUMERD, /* No Kernel consumer detected */
LTTCOMM_EVENT_EXIST_LOGLEVEL, /* Event already enabled with different loglevel */
+ LTTCOMM_URI_DATA_MISS, /* Missing network data URI */
+ LTTCOMM_URI_CTRL_MISS, /* Missing network control URI */
+ LTTCOMM_ENABLE_CONSUMER_FAIL, /* Enabling consumer failed */
+ LTTCOMM_RELAYD_SESSION_FAIL, /* lttng-relayd create session failed */
+ LTTCOMM_RELAYD_VERSION_FAIL, /* lttng-relayd not compatible */
/* MUST be last element */
LTTCOMM_NR, /* Last element */
};
+/* lttng socket protocol. */
+enum lttcomm_sock_proto {
+ LTTCOMM_SOCK_UDP,
+ LTTCOMM_SOCK_TCP,
+};
+
+/*
+ * Index in the net_families array below. Please keep in sync!
+ */
+enum lttcomm_sock_domain {
+ LTTCOMM_INET = 1,
+ LTTCOMM_INET6 = 2,
+};
+
+struct lttcomm_sockaddr {
+ enum lttcomm_sock_domain type;
+ union {
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ } addr;
+};
+
+struct lttcomm_sock {
+ int fd;
+ enum lttcomm_sock_proto proto;
+ struct lttcomm_sockaddr sockaddr;
+ const struct lttcomm_proto_ops *ops;
+};
+
+struct lttcomm_net_family {
+ int family;
+ int (*create) (struct lttcomm_sock *sock, int type, int proto);
+};
+
+struct lttcomm_proto_ops {
+ int (*bind) (struct lttcomm_sock *sock);
+ int (*close) (struct lttcomm_sock *sock);
+ int (*connect) (struct lttcomm_sock *sock);
+ struct lttcomm_sock *(*accept) (struct lttcomm_sock *sock);
+ int (*listen) (struct lttcomm_sock *sock, int backlog);
+ ssize_t (*recvmsg) (struct lttcomm_sock *sock, void *buf, size_t len,
+ int flags);
+ ssize_t (*sendmsg) (struct lttcomm_sock *sock, void *buf, size_t len,
+ int flags);
+};
+
/*
* Data structure received from lttng client to session daemon.
*/
char channel_name[NAME_MAX];
} list;
struct lttng_calibrate calibrate;
+ /* Used by the set_consumer_uri call */
+ struct lttng_uri uri;
+ struct {
+ uint32_t enable_consumer;
+ struct lttng_uri ctrl_uri;
+ struct lttng_uri data_uri;
+ } create_uri;
} u;
};
uint64_t max_sb_size; /* the subbuffer size for this channel */
/* shm_fd and wait_fd are sent as ancillary data */
uint64_t mmap_len;
+ char name[LTTNG_SYMBOL_NAME_LEN];
} channel;
struct {
int channel_key;
uid_t uid; /* User ID owning the session */
gid_t gid; /* Group ID owning the session */
char path_name[PATH_MAX];
+ int net_index;
+ unsigned int metadata_flag;
+ char name[LTTNG_SYMBOL_NAME_LEN]; /* Name string of the stream */
} stream;
+ struct {
+ int net_index;
+ enum lttng_stream_type type;
+ /* Open socket to the relayd */
+ struct lttcomm_sock sock;
+ } relayd_sock;
} u;
};
#endif /* HAVE_LIBLTTNG_UST_CTL */
-/* lttng socket protocol. */
-enum lttcomm_sock_proto {
- LTTCOMM_SOCK_UDP,
- LTTCOMM_SOCK_TCP,
-};
-
-/*
- * Index in the net_families array below. Please keep in sync!
- */
-enum lttcomm_sock_domain {
- LTTCOMM_INET,
- LTTCOMM_INET6,
-};
-
-struct lttcomm_sockaddr {
- enum lttcomm_sock_domain type;
- union {
- struct sockaddr_in sin;
- struct sockaddr_in6 sin6;
- } addr;
-};
-
-struct lttcomm_sock {
- int fd;
- enum lttcomm_sock_proto proto;
- struct lttcomm_sockaddr sockaddr;
- const struct lttcomm_proto_ops *ops;
-};
-
-struct lttcomm_net_family {
- int family;
- int (*create) (struct lttcomm_sock *sock, int type, int proto);
-};
-
-struct lttcomm_proto_ops {
- int (*bind) (struct lttcomm_sock *sock);
- int (*close) (struct lttcomm_sock *sock);
- int (*connect) (struct lttcomm_sock *sock);
- struct lttcomm_sock *(*accept) (struct lttcomm_sock *sock);
- int (*listen) (struct lttcomm_sock *sock, int backlog);
- ssize_t (*recvmsg) (struct lttcomm_sock *sock, void *buf, size_t len,
- int flags);
- ssize_t (*sendmsg) (struct lttcomm_sock *sock, void *buf, size_t len,
- int flags);
-};
-
extern const char *lttcomm_get_readable_code(enum lttcomm_return_code code);
extern int lttcomm_init_inet_sockaddr(struct lttcomm_sockaddr *sockaddr,
extern int lttcomm_init_inet6_sockaddr(struct lttcomm_sockaddr *sockaddr,
const char *ip, unsigned int port);
-extern struct lttcomm_sock *lttcomm_alloc_sock(enum lttcomm_sock_domain domain,
- enum lttcomm_sock_proto proto);
-extern int lttcomm_create_sock(struct lttcomm_sock *sock,
- enum lttcomm_sock_domain domain, enum lttcomm_sock_proto proto);
+extern struct lttcomm_sock *lttcomm_alloc_sock(enum lttcomm_sock_proto proto);
+extern int lttcomm_create_sock(struct lttcomm_sock *sock);
+extern struct lttcomm_sock *lttcomm_alloc_sock_from_uri(struct lttng_uri *uri);
+extern void lttcomm_destroy_sock(struct lttcomm_sock *sock);
+extern struct lttcomm_sock *lttcomm_alloc_copy_sock(struct lttcomm_sock *src);
+extern void lttcomm_copy_sock(struct lttcomm_sock *dst,
+ struct lttcomm_sock *src);
#endif /* _LTTNG_SESSIOND_COMM_H */