#include <fcntl.h>
#include <unistd.h>
#include <math.h>
+#include <time.h>
#include "parser.h"
#include "debug.h"
{
int i;
- /* Count how many sensor entries we need */
+ /*
+ * Count how many sensor entries we need. First entry belongs
+ * to server address or mount point and last one is NULL. So
+ * the index final is the count of actual valid sensor
+ * entries.
+ */
for (i = 0; datastr[i]; i++)
;
- /* The first entry belongs to server address or mount point */
- i--;
-
return calloc(sizeof(struct owparser_state), i);
}
{
double max_delta, delta;
+ /* The known bad data value from the sensor */
+ if (data == 85)
+ return 1;
+
max_delta = max_glitch_delta(s);
/* Probably no enough data yet, so no glitch detection */
break;
/* Copy the onewire path without options */
- strncpy(ow_path, start_str, pathlen);
+ strncpy(ow_path, start_str, pathlen - 1);
ow_path[str - start_str] = '\0';
/* Get the next non-space, which is where the argument begins */
static int make_uncached(char *path, size_t len)
{
- char p1[1024], p2[1024], *p = path;
+ int ret;
+ char p1[1028], p2[1028], *p = path;
if (strstr(path, "/uncached/"))
return 0;
strncpy(p1, path, sizeof(p1) - 1);
strncpy(p2, p, sizeof(p2) - 1);
- snprintf(path, len, "%s/uncached/%s", p1, p2);
+ ret = snprintf(path, len, "%s/uncached/%s", p1, p2);
+
+ /* No actual data overflow, snprintf just couldn't fit all data in the buffer */
+ if (ret >= RRD_DATA_MAX_LEN)
+ pr_err("Buffer overlfow\n");
return 0;
}
return ret;
}
+static void enable_simultaneous_reading(const char *mountpoint)
+{
+ static time_t last_simultaneous;
+ static struct mutex lock = {
+ .lock = PTHREAD_MUTEX_INITIALIZER,
+ };
+
+ time_t now = time(0);
+ int fd;
+ int ret;
+ char path[4096];
+ char one = '1';
+
+ mutex_lock(&lock);
+ /* Arbitrary 10 second limit between simultaneous reads */
+ if (now < last_simultaneous + 10) {
+ mutex_unlock(&lock);
+ return;
+ }
+
+ last_simultaneous = now;
+ mutex_unlock(&lock);
+
+ /*
+ * We only protect setting the variable. From now on we have
+ * 10 seconds time until we could race writing multiple times
+ * to this file. If that happens, well, can't help it..
+ */
+
+ strncpy(path, mountpoint, sizeof(path) - 1);
+ strncat(path, "/simultaneous/temperature", sizeof(path) - 1);
+ path[sizeof(path) - 1 ] = '\0';
+
+ fd = open(path, O_WRONLY);
+ if (path < 0) {
+ pr_err("Failed to open %s for writing: %m\n", path);
+ return;
+ }
+
+ ret = write(fd, &one, 1);
+ if (ret < 0)
+ pr_warn("Failed to write to %s: %m\n", path);
+
+ close(fd);
+}
+
static int is_mount_point(const char *str)
{
/*
parse_opts(parser_data[i], ow_path, sizeof(ow_path), &offset);
+ if (is_mountpoint)
+ enable_simultaneous_reading(mount_point);
+
while (1) {
- int fail, j;
+ int j;
char *tmp2;
tmp = NULL;
for (j = 0; j < ret && *tmp2 == ' '; j++)
tmp2++;
- if (ret > 0)
- fail = !strncmp(tmp2, "85", 2);
- else
- fail = 1;
-
- if (ret <= 0 || fail)
+ if (ret <= 0)
goto retry;
-
/*
* Older versions of OWNET_read did not NULL
* terminate data.
}
if (might_be_glitch(data, &state[i]) &&
- glitches < 2 && retries < 7) {
+ glitches < 4 && retries < 7) {
glitches++;
prev_data = data;
pr_info("Retrying due to a glitch: %f\n", data);