#include <stdio.h>
#include <ownetapi.h>
+#include "process.h"
#include "parser.h"
#include "debug.h"
#include "string.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 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;
return -1;
}
- server_addr = parser_data[0];
-
- if (!server_addr) {
+ if (!parser_data[0]) {
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);
+ mutex_unlock(&server_lock);
return -1;
}
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++)
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]);
}
rrd_data = 0;
- OWNET_finish();
+ mutex_unlock(&server_lock);
return 0;
}