]> git.itanic.dy.fi Git - rrdd/commitdiff
onewire_parser: Keep server handle open at all time
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Mon, 11 Jul 2016 11:56:48 +0000 (14:56 +0300)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Mon, 11 Jul 2016 11:56:48 +0000 (14:56 +0300)
On libowfs 2.7 there appear to be a problem when releasing the client
resources. At least sockets are left open every now and then. There is
no such problem with 3.1 version.

To resolve the issue with older client library, keep the serve handle
open at all time. Release it only when there is a change with the
server address, which normally does not happen ever.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
onewire_parser.c

index eb2ccd212b490ecead3ac58587087d1cac41d1e1..9f4b404c480bdcc87ef2c88c37f3b6c9eb5441e9 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <ownetapi.h>
 
 #include <stdio.h>
 #include <ownetapi.h>
 
+#include "process.h"
 #include "parser.h"
 #include "debug.h"
 #include "string.h"
 #include "parser.h"
 #include "debug.h"
 #include "string.h"
@@ -8,6 +9,11 @@
 #include "plugin.h"
 #include "version.h"
 
 #include "plugin.h"
 #include "version.h"
 
+static struct mutex server_lock = {
+       .name = "server_addr_lock",
+       .lock = PTHREAD_MUTEX_INITIALIZER,
+};
+
 static int parse_opts(const char *str, char *ow_path, size_t pathlen, double *offset)
 {
        char *endptr;
 static int parse_opts(const char *str, char *ow_path, size_t pathlen, double *offset)
 {
        char *endptr;
@@ -75,8 +81,8 @@ static int make_uncached(char *path, size_t len)
 
 static int onewire_parser(char *rrd_data, const char **parser_data)
 {
 
 static int onewire_parser(char *rrd_data, const char **parser_data)
 {
-       OWNET_HANDLE h;
-       const char *server_addr;
+       static OWNET_HANDLE handle;
+       static char *server_addr;
        char buf[24], *tmp;
        int i = 1, ret;
        int max_str = RRD_DATA_MAX_LEN;
        char buf[24], *tmp;
        int i = 1, ret;
        int max_str = RRD_DATA_MAX_LEN;
@@ -86,16 +92,36 @@ static int onewire_parser(char *rrd_data, const char **parser_data)
                return -1;
        }
 
                return -1;
        }
 
-       server_addr = parser_data[0];
-
-       if (!server_addr) {
+       if (!parser_data[0]) {
                pr_err("Server address not specified\n");
                return -1;
        }
 
                pr_err("Server address not specified\n");
                return -1;
        }
 
-       h = OWNET_init(server_addr);
-       if (h < 0) {
+       /*
+        * No point trying to connect to the server more than
+        * once. Also we don't know how thread safe libownet is. One
+        * lock to protect it all.
+        */
+       mutex_lock(&server_lock);
+       /*
+        * Keep one server connection alive at all times. This
+        * prevents file descriptor leak with older libownet.
+        */
+       if (!server_addr || handle < 0) {
+               if (server_addr)
+                       free(server_addr);
+               server_addr = strdup(parser_data[0]);
+               handle = OWNET_init(server_addr);
+       } else if (strcmp(server_addr, parser_data[0])) {
+               OWNET_close(handle);
+               free(server_addr);
+               server_addr = strdup(parser_data[0]);
+               handle = OWNET_init(server_addr);
+       }
+
+       if (handle < 0) {
                pr_err("Failed to connect to server %s\n", server_addr);
                pr_err("Failed to connect to server %s\n", server_addr);
+               mutex_unlock(&server_lock);
                return -1;
        }
 
                return -1;
        }
 
@@ -121,8 +147,9 @@ undefined:
 
                        pr_info("Reading data for entry %s with offset of %.2f\n",
                                ow_path, offset);
 
                        pr_info("Reading data for entry %s with offset of %.2f\n",
                                ow_path, offset);
-                       ret = OWNET_read(h, ow_path, &tmp);
-
+                       ret = OWNET_read(handle, ow_path, &tmp);
+                       if (ret < 0)
+                               goto err;
                        /* Skip leading white space */
                        tmp2 = tmp;
                        for (j = 0; j < ret && *tmp2 == ' '; j++)
                        /* Skip leading white space */
                        tmp2 = tmp;
                        for (j = 0; j < ret && *tmp2 == ' '; j++)
@@ -142,6 +169,7 @@ undefined:
                                break;
 
                        ret = make_uncached(ow_path, sizeof(ow_path));
                                break;
 
                        ret = make_uncached(ow_path, sizeof(ow_path));
+err:
                        if (retries >= 10 || ret < 0) {
                                pr_err("Failed to read entry %s: %m\n",
                                        parser_data[i]);
                        if (retries >= 10 || ret < 0) {
                                pr_err("Failed to read entry %s: %m\n",
                                        parser_data[i]);
@@ -179,7 +207,7 @@ next:
        }
        rrd_data = 0;
 
        }
        rrd_data = 0;
 
-       OWNET_finish();
+       mutex_unlock(&server_lock);
        return 0;
 }
 
        return 0;
 }