X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fsessiond-comm%2Finet.c;h=2c959c5fe81ee08d21cca8f0ac42a62d0dfecb6c;hp=6d729238a575e8ae149d85a8f25693f7a2554400;hb=f14256d650ba78aa23c87a1f35c0c66656cb9e06;hpb=a655f4cf59f557aef3f0a975988d87bdd3b199fd diff --git a/src/common/sessiond-comm/inet.c b/src/common/sessiond-comm/inet.c index 6d729238a..2c959c5fe 100644 --- a/src/common/sessiond-comm/inet.c +++ b/src/common/sessiond-comm/inet.c @@ -50,6 +50,8 @@ static const struct lttcomm_proto_ops inet_ops = { .sendmsg = lttcomm_sendmsg_inet_sock, }; +unsigned long lttcomm_inet_tcp_timeout; + /* * Creates an PF_INET socket. */ @@ -57,6 +59,7 @@ LTTNG_HIDDEN int lttcomm_create_inet_sock(struct lttcomm_sock *sock, int type, int proto) { int val = 1, ret; + unsigned long timeout; /* Create server socket */ if ((sock->fd = socket(PF_INET, type, proto)) < 0) { @@ -74,6 +77,17 @@ int lttcomm_create_inet_sock(struct lttcomm_sock *sock, int type, int proto) PERROR("setsockopt inet"); goto error; } + timeout = lttcomm_get_network_timeout(); + if (timeout) { + ret = lttcomm_setsockopt_rcv_timeout(sock->fd, timeout); + if (ret) { + goto error; + } + ret = lttcomm_setsockopt_snd_timeout(sock->fd, timeout); + if (ret) { + goto error; + } + } return 0; @@ -436,3 +450,81 @@ int lttcomm_close_inet_sock(struct lttcomm_sock *sock) return ret; } + +/* + * Return value read from /proc or else 0 if value is not found. + */ +static unsigned long read_proc_value(const char *path) +{ + int ret, fd; + ssize_t size_ret; + long r_val; + unsigned long val = 0; + char buf[64]; + + fd = open(path, O_RDONLY); + if (fd < 0) { + goto error; + } + + size_ret = lttng_read(fd, buf, sizeof(buf)); + /* + * Allow reading a file smaller than buf, but keep space for + * final \0. + */ + if (size_ret < 0 || size_ret >= sizeof(buf)) { + PERROR("read proc failed"); + goto error_close; + } + buf[size_ret] = '\0'; + + errno = 0; + r_val = strtol(buf, NULL, 10); + if (errno != 0 || r_val < -1L) { + val = 0; + goto error_close; + } else { + if (r_val > 0) { + val = r_val; + } + } + +error_close: + ret = close(fd); + if (ret) { + PERROR("close /proc value"); + } +error: + return val; +} + +LTTNG_HIDDEN +void lttcomm_inet_init(void) +{ + unsigned long syn_retries, fin_timeout, syn_timeout, env; + + env = lttcomm_get_network_timeout(); + if (env) { + lttcomm_inet_tcp_timeout = env; + goto end; + } + + /* Assign default value and see if we can change it. */ + lttcomm_inet_tcp_timeout = DEFAULT_INET_TCP_TIMEOUT; + + syn_retries = read_proc_value(LTTCOMM_INET_PROC_SYN_RETRIES_PATH); + fin_timeout = read_proc_value(LTTCOMM_INET_PROC_FIN_TIMEOUT_PATH); + + syn_timeout = syn_retries * LTTCOMM_INET_SYN_TIMEOUT_FACTOR; + + /* + * Get the maximum between the two possible timeout value and use that to + * get the maximum with the default timeout. + */ + lttcomm_inet_tcp_timeout = max_t(unsigned long, + max_t(unsigned long, syn_timeout, fin_timeout), + lttcomm_inet_tcp_timeout); + +end: + DBG("TCP inet operation timeout set to %lu sec", lttcomm_inet_tcp_timeout); +}