12 static struct mutex server_lock = {
13 .name = "server_addr_lock",
14 .lock = PTHREAD_MUTEX_INITIALIZER,
17 static int parse_opts(const char *str, char *ow_path, size_t pathlen, double *offset)
20 const char *start_str = str;
21 const char offset_str[] = "offset=";
27 * Skip the onewire path entry. Options begin after the first
34 /* Copy the onewire path without options */
35 strncpy(ow_path, start_str, pathlen);
36 ow_path[str - start_str] = '\0';
38 /* Get the next non-space, which is where the argument begins */
43 if (strncmp(str, offset_str, sizeof(offset_str) - 1))
45 str += sizeof(offset_str) - 1;
47 *offset = strtod(str, &endptr);
55 static int make_uncached(char *path, size_t len)
57 char p1[32], p2[32], *p = path;
59 if (strstr(path, "/uncached/"))
63 * Naively assume the "uncached" string can be put after the
66 while (*p && *p != '/')
75 strncpy(p1, path, sizeof(p1));
76 strncpy(p2, p, sizeof(p2));
77 snprintf(path, len, "%s/uncached/%s", p1, p2);
82 static int onewire_parser(char *rrd_data, const char **parser_data)
84 static OWNET_HANDLE handle;
85 static char *server_addr;
88 int max_str = RRD_DATA_MAX_LEN;
91 pr_err("No parser data available\n");
95 if (!parser_data[0]) {
96 pr_err("Server address not specified\n");
101 * No point trying to connect to the server more than
102 * once. Also we don't know how thread safe libownet is. One
103 * lock to protect it all.
105 mutex_lock(&server_lock);
107 * Keep one server connection alive at all times. This
108 * prevents file descriptor leak with older libownet.
110 if (!server_addr || handle < 0) {
113 server_addr = strdup(parser_data[0]);
114 handle = OWNET_init(server_addr);
115 } else if (strcmp(server_addr, parser_data[0])) {
118 server_addr = strdup(parser_data[0]);
119 handle = OWNET_init(server_addr);
123 pr_err("Failed to connect to server %s\n", server_addr);
124 mutex_unlock(&server_lock);
128 while (parser_data[i]) {
129 double offset = 0, data;
134 if (!strcmp("U", parser_data[i])) {
136 ret = snprintf(rrd_data, max_str, "U");
142 parse_opts(parser_data[i], ow_path, sizeof(ow_path), &offset);
148 pr_info("Reading data for entry %s with offset of %.2f\n",
150 ret = OWNET_read(handle, ow_path, &tmp);
153 /* Skip leading white space */
155 for (j = 0; j < ret && *tmp2 == ' '; j++)
158 fail = !strncmp(tmp2, "85", 2);
161 * In case of failure, retry with uncached
162 * data. This is likely to help as it forces a
163 * retry even if the sensor is missing from
164 * the cache. We thread "85" also as a failure
165 * above, as temp sensors some times report 85
166 * under faulty conditions.
168 if (ret > 0 && !fail)
171 ret = make_uncached(ow_path, sizeof(ow_path));
173 if (retries >= 10 || ret < 0) {
174 pr_err("Failed to read entry %s: %m\n",
181 /* The data from OWNET_read appears to not be NULL terminated */
182 memcpy(buf, tmp, MIN(ret, sizeof(buf) -1));
186 data = strtod(buf, &endptr);
189 pr_err("Failed to parse data %s\n", buf);
195 ret = snprintf(rrd_data, max_str, "%f", data);
204 ret = snprintf(rrd_data, max_str, ":");
210 mutex_unlock(&server_lock);
214 static struct parser_info onewire_parser_info = {
216 .parse = onewire_parser,
219 static int init_onewire_parser(void)
221 return register_parser(&onewire_parser_info);
224 struct plugin_info plugin_info = {
225 .name = "onewire_parser",
226 .init = init_onewire_parser,
227 .version = RRDD_VERSION,