Add heartbeat support (stop all cores in case of TCP socket issues) 40/68440/1
authorXavier Simonart <xavier.simonart@intel.com>
Wed, 4 Sep 2019 11:54:31 +0000 (13:54 +0200)
committerXavier Simonart <xavier.simonart@intel.com>
Wed, 4 Sep 2019 11:54:31 +0000 (13:54 +0200)
"heartbeat timeout" (in second) can be specified as a global parameter
in PROX config file. If set, a timer is started when the first
command is received from the TCP socket. This timer is reset at each
commands received through the TCP socket. If the timer expires, then
- all cores are stopped
- the TCP socket is closed, causing an error at client side.

This feature helps in case a script starts PROX and the traffic generated
through PROX causes issues to the control plane.

Change-Id: I900f22fa091786a564f6b7d846f5abc2c5cbcc58
Signed-off-by: Xavier Simonart <xavier.simonart@intel.com>
VNFs/DPPD-PROX/input_conn.c
VNFs/DPPD-PROX/input_conn.h
VNFs/DPPD-PROX/prox_args.c
VNFs/DPPD-PROX/prox_cfg.h
VNFs/DPPD-PROX/run.c

index 63e6511..13d6110 100644 (file)
 #include <sys/un.h>
 #include <unistd.h>
 
+#include <rte_cycles.h>
 #include "input_conn.h"
 #include "input.h"
+#include "log.h"
 #include "run.h"
 #include "cmd_parser.h"
+#include "prox_cfg.h"
 
 static struct input tcp_server;
 int tcp_server_started;
@@ -132,6 +135,8 @@ static void handle_client(struct input* client_input)
                return ;
        }
 
+       prox_cfg.heartbeat_tsc = rte_rdtsc() + prox_cfg.heartbeat_timeout * rte_get_tsc_hz();
+
        /* Scan in data until \n (\r skipped if followed by \n) */
        for (int i = 0; i < ret; ++i) {
                if (cur[i] == '\r' && i + 1 < ret && cur[i + 1] == '\n')
@@ -150,6 +155,18 @@ static void handle_client(struct input* client_input)
        }
 }
 
+void stop_handling_client(void)
+{
+       size_t i;
+       for (i = 0; i < sizeof(clients)/sizeof(clients[0]); ++i) {
+               if (clients[i].enabled) {
+                       close(clients[i].input.fd);
+                       clients[i].enabled = 0;
+                       unreg_input(&clients[i].input);
+               }
+       }
+}
+
 static void handle_new_client(struct input* server)
 {
        size_t i;
index 98e9af4..9e39c80 100644 (file)
@@ -23,5 +23,6 @@ int reg_input_uds(void);
 
 void unreg_input_tcp(void);
 void unreg_input_uds(void);
+void stop_handling_client(void);
 
 #endif /* _INPUT_CONN_H_ */
index ca5b93b..e1ed10e 100644 (file)
@@ -338,6 +338,9 @@ static int get_global_cfg(__attribute__((unused))unsigned sindex, char *str, voi
        if (STR_EQ(str, "enable bypass")) {
                return parse_flag(&pset->flags, DSF_ENABLE_BYPASS, pkey);
        }
+       if (STR_EQ(str, "heartbeat timeout")) {
+               return parse_int(&pset->heartbeat_timeout, pkey);
+       }
 
        if (STR_EQ(str, "cpe table map")) {
                /* The config defined ports through 0, 1, 2 ... which
index ed54ecc..9d5f25f 100644 (file)
@@ -66,6 +66,8 @@ struct prox_cfg {
        uint32_t        logbuf_size;
        uint32_t        logbuf_pos;
        char            *logbuf;
+       uint32_t        heartbeat_timeout;
+       uint64_t        heartbeat_tsc;
 };
 
 extern struct prox_cfg prox_cfg;
index bed0c75..c05f0a9 100644 (file)
@@ -237,6 +237,13 @@ void __attribute__((noreturn)) run(uint32_t flags)
                        if (stop_tsc && rte_rdtsc() >= stop_tsc) {
                                stop_prox = 1;
                        }
+                       if ((prox_cfg.heartbeat_tsc) && (prox_cfg.heartbeat_timeout) && (rte_rdtsc() >= prox_cfg.heartbeat_tsc)) {
+                               plog_info("Stopping to handle client as heartbeat timed out\n");
+                               stop_core_all(-1);
+                               stop_handling_client();
+                               req_refresh();
+                               prox_cfg.heartbeat_tsc = 0;
+                       }
                }
        } else {
                while (stop_prox == 0) {
@@ -254,6 +261,13 @@ void __attribute__((noreturn)) run(uint32_t flags)
                        if (stop_tsc && rte_rdtsc() >= stop_tsc) {
                                stop_prox = 1;
                        }
+                       if ((prox_cfg.heartbeat_tsc) && (prox_cfg.heartbeat_timeout) && (rte_rdtsc() >= prox_cfg.heartbeat_tsc)) {
+                               plog_info("Stopping to handle client as heartbeat timed out\n");
+                               stop_core_all(-1);
+                               stop_handling_client();
+                               req_refresh();
+                               prox_cfg.heartbeat_tsc = 0;
+                       }
                }
        }