Get the maximum TCP timeout in sessiond
authorDavid Goulet <dgoulet@efficios.com>
Tue, 27 Aug 2013 19:11:40 +0000 (15:11 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Tue, 27 Aug 2013 19:31:57 +0000 (15:31 -0400)
This actually just open some /proc files when calling
lttcomm_init_inet() and computes the maximum value a TCP timeout for
every possible operations (send/recv/connect).

This is the first patch to fix the health check issue of having a
smaller delta than the TCP maximum possible timeout.

Signed-off-by: David Goulet <dgoulet@efficios.com>
src/bin/lttng-sessiond/main.c
src/common/defaults.h
src/common/sessiond-comm/inet.c
src/common/sessiond-comm/inet.h

index 9d2ad08b07e5ec4069a5cde4ceeec2fa2a148ebf..7032191bd4dbc40eef7631263a74dbb907155dc2 100644 (file)
@@ -4518,6 +4518,9 @@ int main(int argc, char **argv)
 
        write_pidfile();
 
+       /* This is to get the TCP timeout value. */
+       lttcomm_inet_init();
+
        /* Create thread to manage the client socket */
        ret = pthread_create(&ht_cleanup_thread, NULL,
                        thread_ht_cleanup, (void *) NULL);
index c040634880516231af7be0463e9ba650ff3b82db..f67acf18c205dd54343c4a8dc3921b6db4ef7a01 100644 (file)
  */
 #define DEFAULT_METADATA_AVAILABILITY_WAIT_TIME 200000  /* usec */
 
+/*
+ * The usual value for the maximum TCP SYN retries time and TCP FIN timeout is
+ * 180 and 60 seconds on most Linux system and the default value since kernel
+ * 2.2 thus using the highest value. See tcp(7) for more details.
+ */
+#define DEFAULT_INET_TCP_TIMEOUT                       180     /* sec */
+
 /*
  * Default receiving and sending timeout for an application socket.
  */
index b2bd65d9029672efb47a4469ef3632b30a649740..2e5c470899c76b5bb09856bf2e7158cc7a054d10 100644 (file)
@@ -25,6 +25,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <errno.h>
+#include <fcntl.h>
 
 #include <common/common.h>
 
@@ -43,6 +44,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.
  */
@@ -302,3 +305,68 @@ 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;
+       long r_val;
+       unsigned long val = 0;
+       char buf[64];
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               goto error;
+       }
+
+       ret = read(fd, buf, sizeof(buf));
+       if (ret < 0) {
+               PERROR("read proc failed");
+               goto error_close;
+       }
+
+       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;
+
+       /* 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);
+
+       DBG("TCP inet operation timeout set to %lu sec", lttcomm_inet_tcp_timeout);
+}
index 89716b8bafdb0b19cfaa1cca503e34af140711dc..83209bb719fff759e4719ed48f34cf69bb8fd7a2 100644 (file)
 
 #include "sessiond-comm.h"
 
+/* See man tcp(7) for more detail about this value. */
+#define LTTCOMM_INET_PROC_SYN_RETRIES_PATH "/proc/sys/net/ipv4/tcp_syn_retries"
+#define LTTCOMM_INET_PROC_FIN_TIMEOUT_PATH "/proc/sys/net/ipv4/tcp_fin_timeout"
+
+/*
+ * The timeout value of a connect() is computed with an algorithm inside the
+ * kernel using the defined TCP SYN retries so the end value in time is
+ * approximative. According to tcp(7) man page, a value of 5 is roughly 180
+ * seconds of timeout. With that information, we've computed a factor of 36
+ * (180/5) by considering that it grows linearly. This is of course uncertain
+ * but this is the best approximation we can do at runtime.
+ */
+#define LTTCOMM_INET_SYN_TIMEOUT_FACTOR                36
+
+/*
+ * Maximum timeout value in seconds of a TCP connection for both send/recv and
+ * connect operations.
+ */
+extern unsigned long lttcomm_inet_tcp_timeout;
+
 /* Stub */
 struct lttcomm_sock;
 
@@ -41,4 +61,7 @@ extern ssize_t lttcomm_recvmsg_inet_sock(struct lttcomm_sock *sock, void *buf,
 extern ssize_t lttcomm_sendmsg_inet_sock(struct lttcomm_sock *sock, void *buf,
                size_t len, int flags);
 
+/* Initialize inet communication layer. */
+extern void lttcomm_inet_init(void);
+
 #endif /* _LTTCOMM_INET_H */
This page took 0.030985 seconds and 4 git commands to generate.