From: David Goulet Date: Tue, 10 Jul 2012 21:30:37 +0000 (-0400) Subject: Add and change lttcomm socket API X-Git-Tag: v2.1.0-rc1~99 X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=commitdiff_plain;h=de5e90863d3824dd3a5bc52d4cba1cd9b0329200 Add and change lttcomm socket API Add lttcomm_alloc_sock_from_uri(), lttcomm_destroy_sock(), lttcomm_alloc_copy_sock() and lttcomm_copy_sock(). Also add the relayd command and lttcomm error message. Change the create and alloc sock call API arguments. Fix the fd leak in accept() function. Signed-off-by: David Goulet --- diff --git a/src/common/sessiond-comm/inet.c b/src/common/sessiond-comm/inet.c index 3cf8f5d3f..e049d021b 100644 --- a/src/common/sessiond-comm/inet.c +++ b/src/common/sessiond-comm/inet.c @@ -49,7 +49,7 @@ static const struct lttcomm_proto_ops inet_ops = { */ 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) { @@ -136,7 +136,7 @@ struct lttcomm_sock *lttcomm_accept_inet_sock(struct lttcomm_sock *sock) goto end; } - new_sock = lttcomm_alloc_sock(LTTCOMM_INET, sock->proto); + new_sock = lttcomm_alloc_sock(sock->proto); if (new_sock == NULL) { goto error; } @@ -150,6 +150,7 @@ struct lttcomm_sock *lttcomm_accept_inet_sock(struct lttcomm_sock *sock) } new_sock->fd = new_fd; + new_sock->ops = &inet_ops; end: return new_sock; @@ -274,7 +275,7 @@ int lttcomm_close_inet_sock(struct lttcomm_sock *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; } diff --git a/src/common/sessiond-comm/inet6.c b/src/common/sessiond-comm/inet6.c index ac6d0988a..0d96c31c2 100644 --- a/src/common/sessiond-comm/inet6.c +++ b/src/common/sessiond-comm/inet6.c @@ -49,7 +49,7 @@ static const struct lttcomm_proto_ops inet6_ops = { */ 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) { @@ -136,7 +136,7 @@ struct lttcomm_sock *lttcomm_accept_inet6_sock(struct lttcomm_sock *sock) goto end; } - new_sock = lttcomm_alloc_sock(LTTCOMM_INET, sock->proto); + new_sock = lttcomm_alloc_sock(sock->proto); if (new_sock == NULL) { goto error; } @@ -150,6 +150,7 @@ struct lttcomm_sock *lttcomm_accept_inet6_sock(struct lttcomm_sock *sock) } new_sock->fd = new_fd; + new_sock->ops = &inet6_ops; end: return new_sock; @@ -274,7 +275,7 @@ int lttcomm_close_inet6_sock(struct lttcomm_sock *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; } diff --git a/src/common/sessiond-comm/sessiond-comm.c b/src/common/sessiond-comm/sessiond-comm.c index eaa14a549..6cbd014b8 100644 --- a/src/common/sessiond-comm/sessiond-comm.c +++ b/src/common/sessiond-comm/sessiond-comm.c @@ -138,6 +138,11 @@ static const char *lttcomm_readable_code[] = { [ 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", }; /* @@ -158,84 +163,107 @@ const char *lttcomm_get_readable_code(enum lttcomm_return_code code) } /* - * 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)); } /* @@ -259,6 +287,7 @@ int lttcomm_init_inet_sockaddr(struct lttcomm_sockaddr *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)); @@ -294,3 +323,65 @@ int lttcomm_init_inet6_sockaddr(struct lttcomm_sockaddr *sockaddr, 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); + } +} diff --git a/src/common/sessiond-comm/sessiond-comm.h b/src/common/sessiond-comm/sessiond-comm.h index 52369dc62..580beec32 100644 --- a/src/common/sessiond-comm/sessiond-comm.h +++ b/src/common/sessiond-comm/sessiond-comm.h @@ -61,6 +61,7 @@ enum lttcomm_sessiond_command { LTTNG_ENABLE_ALL_EVENT, /* Session daemon command */ LTTNG_CREATE_SESSION, + LTTNG_CREATE_SESSION_URI, LTTNG_DESTROY_SESSION, LTTNG_LIST_CHANNELS, LTTNG_LIST_DOMAINS, @@ -71,6 +72,17 @@ enum lttcomm_sessiond_command { 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, }; /* @@ -169,11 +181,62 @@ enum lttcomm_return_code { 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. */ @@ -210,6 +273,13 @@ struct lttcomm_session_msg { 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; }; @@ -238,6 +308,7 @@ struct lttcomm_consumer_msg { 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; @@ -249,7 +320,16 @@ struct lttcomm_consumer_msg { 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; }; @@ -294,52 +374,6 @@ struct lttcomm_ust_reply { #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, @@ -347,9 +381,12 @@ 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 */