Lines 29-34
Link Here
|
29 |
#define DEVICE_DIR "/proc/sys/dev/sensors" |
29 |
#define DEVICE_DIR "/proc/sys/dev/sensors" |
30 |
#else |
30 |
#else |
31 |
#define DEVICE_DIR "/sys/class/hwmon" |
31 |
#define DEVICE_DIR "/sys/class/hwmon" |
|
|
32 |
static char *locations[] = {"", "/device", NULL}; |
32 |
#endif |
33 |
#endif |
33 |
|
34 |
|
34 |
#define ATTR_MAX 128 |
35 |
#define ATTR_MAX 128 |
Lines 84-129
Link Here
|
84 |
* * |
85 |
* * |
85 |
* Function: sysfs_read_attr * |
86 |
* Function: sysfs_read_attr * |
86 |
* * |
87 |
* * |
87 |
* Purpose: read the name attribute of a sensor from sysf * |
88 |
* Purpose: locate and read the name attribute of a sensor from sysfs * |
88 |
* * |
89 |
* * |
89 |
* Parameters: device - [IN] the path to sensor data in sysf * |
90 |
* Parameters: device - [IN] the path to sensor data in sysfs * |
|
|
91 |
* attribute - [OUT] the sensor name * |
90 |
* * |
92 |
* * |
91 |
* Return value: The seonsor name or NULL pointer * |
93 |
* Return value: Subfolder where the sensor name file was found or NULL * |
92 |
* * |
94 |
* * |
93 |
* Comments: The returned string must be freed by caller after it's been used. * |
95 |
* Comments: attribute string must be freed by caller after it's been used. * |
94 |
* * |
96 |
* * |
95 |
*********************************************************************************/ |
97 |
*********************************************************************************/ |
96 |
static char *sysfs_read_attr(const char *device) |
98 |
static const char *sysfs_read_attr(const char *device, char **attribute) |
97 |
{ |
99 |
{ |
98 |
char path[MAX_STRING_LEN], buf[ATTR_MAX], *p; |
100 |
char path[MAX_STRING_LEN], buf[ATTR_MAX], *p, **location; |
99 |
FILE *f; |
101 |
FILE *f; |
100 |
|
102 |
|
101 |
zbx_snprintf(path, MAX_STRING_LEN, "%s/%s", device, "name"); |
103 |
for (location = locations; NULL != *location; location++) |
|
|
104 |
{ |
105 |
zbx_snprintf(path, MAX_STRING_LEN, "%s%s/name", device, *location); |
102 |
|
106 |
|
103 |
if (NULL == (f = fopen(path, "r"))) |
107 |
if (NULL != (f = fopen(path, "r"))) |
104 |
return NULL; |
108 |
{ |
|
|
109 |
p = fgets(buf, ATTR_MAX, f); |
110 |
zbx_fclose(f); |
105 |
|
111 |
|
106 |
p = fgets(buf, ATTR_MAX, f); |
112 |
if (NULL == p) |
107 |
zbx_fclose(f); |
113 |
break; |
108 |
|
114 |
|
109 |
if (NULL == p) |
115 |
/* Last byte is a '\n'; chop that off */ |
110 |
return NULL; |
116 |
buf[strlen(buf) - 1] = '\0'; |
111 |
|
117 |
|
112 |
/* Last byte is a '\n'; chop that off */ |
118 |
*attribute = zbx_strdup(*attribute, buf); |
113 |
buf[strlen(buf) - 1] = '\0'; |
119 |
return *location; |
|
|
120 |
} |
121 |
} |
114 |
|
122 |
|
115 |
return zbx_strdup(NULL, buf); |
123 |
return NULL; |
116 |
} |
124 |
} |
117 |
|
125 |
|
118 |
int get_device_info(const char *dev_path, const char *dev_name, char *device_info) |
126 |
int get_device_info(const char *dev_path, const char *dev_name, char *device_info, const char **name_subfolder) |
119 |
{ |
127 |
{ |
120 |
char bus_path[MAX_STRING_LEN], linkpath[MAX_STRING_LEN], subsys_path[MAX_STRING_LEN]; |
128 |
char bus_path[MAX_STRING_LEN], linkpath[MAX_STRING_LEN], subsys_path[MAX_STRING_LEN]; |
121 |
char *subsys, *prefix, *bus_attr = NULL; |
129 |
char *subsys, *prefix = NULL, *bus_attr = NULL; |
|
|
130 |
const char *bus_subfolder; |
122 |
int domain, bus, slot, fn, addr, vendor, product, sub_len, ret = FAIL; |
131 |
int domain, bus, slot, fn, addr, vendor, product, sub_len, ret = FAIL; |
123 |
short int bus_spi, bus_i2c; |
132 |
short int bus_spi, bus_i2c; |
124 |
|
133 |
|
125 |
/* ignore any device without name attribute */ |
134 |
/* ignore any device without name attribute */ |
126 |
if (NULL == (prefix = sysfs_read_attr(dev_path))) |
135 |
if (NULL == (*name_subfolder = sysfs_read_attr(dev_path, &prefix))) |
127 |
goto out; |
136 |
goto out; |
128 |
|
137 |
|
129 |
if (NULL == dev_name) |
138 |
if (NULL == dev_name) |
Lines 138-144
Link Here
|
138 |
} |
147 |
} |
139 |
|
148 |
|
140 |
/* Find bus type */ |
149 |
/* Find bus type */ |
141 |
zbx_snprintf(linkpath, MAX_STRING_LEN, "%s/subsystem", dev_path); |
150 |
zbx_snprintf(linkpath, MAX_STRING_LEN, "%s/device/subsystem", dev_path); |
142 |
|
151 |
|
143 |
sub_len = readlink(linkpath, subsys_path, MAX_STRING_LEN - 1); |
152 |
sub_len = readlink(linkpath, subsys_path, MAX_STRING_LEN - 1); |
144 |
|
153 |
|
Lines 145-151
Link Here
|
145 |
if (0 > sub_len && ENOENT == errno) |
154 |
if (0 > sub_len && ENOENT == errno) |
146 |
{ |
155 |
{ |
147 |
/* Fallback to "bus" link for kernels <= 2.6.17 */ |
156 |
/* Fallback to "bus" link for kernels <= 2.6.17 */ |
148 |
zbx_snprintf(linkpath, MAX_STRING_LEN, "%s/bus", dev_path); |
157 |
zbx_snprintf(linkpath, MAX_STRING_LEN, "%s/device/bus", dev_path); |
149 |
sub_len = readlink(linkpath, subsys_path, MAX_STRING_LEN - 1); |
158 |
sub_len = readlink(linkpath, subsys_path, MAX_STRING_LEN - 1); |
150 |
} |
159 |
} |
151 |
|
160 |
|
Lines 175-183
Link Here
|
175 |
} |
184 |
} |
176 |
else |
185 |
else |
177 |
{ |
186 |
{ |
178 |
zbx_snprintf(bus_path, sizeof(bus_path), "/sys/class/i2c-adapter/i2c-%d/device", bus_i2c); |
187 |
zbx_snprintf(bus_path, sizeof(bus_path), "/sys/class/i2c-adapter/i2c-%d", bus_i2c); |
|
|
188 |
bus_subfolder = sysfs_read_attr(bus_path, &bus_attr); |
179 |
|
189 |
|
180 |
if (NULL != (bus_attr = sysfs_read_attr(bus_path))) |
190 |
if (NULL != bus_subfolder && '\0' != *bus_subfolder) |
181 |
{ |
191 |
{ |
182 |
if (0 != strncmp(bus_attr, "ISA ", 4)) |
192 |
if (0 != strncmp(bus_attr, "ISA ", 4)) |
183 |
goto out; |
193 |
goto out; |
Lines 298-303
Link Here
|
298 |
struct dirent *sensorent, *deviceent; |
308 |
struct dirent *sensorent, *deviceent; |
299 |
char hwmon_dir[MAX_STRING_LEN], devicepath[MAX_STRING_LEN], deviced[MAX_STRING_LEN], |
309 |
char hwmon_dir[MAX_STRING_LEN], devicepath[MAX_STRING_LEN], deviced[MAX_STRING_LEN], |
300 |
device_info[MAX_STRING_LEN], regex[MAX_STRING_LEN], *device_p; |
310 |
device_info[MAX_STRING_LEN], regex[MAX_STRING_LEN], *device_p; |
|
|
311 |
const char *subfolder; |
301 |
int err, dev_len; |
312 |
int err, dev_len; |
302 |
|
313 |
|
303 |
zbx_snprintf(hwmon_dir, sizeof(hwmon_dir), "%s", DEVICE_DIR); |
314 |
zbx_snprintf(hwmon_dir, sizeof(hwmon_dir), "%s", DEVICE_DIR); |
Lines 312-323
Link Here
|
312 |
|
323 |
|
313 |
zbx_snprintf(devicepath, sizeof(devicepath), "%s/%s/device", DEVICE_DIR, deviceent->d_name); |
324 |
zbx_snprintf(devicepath, sizeof(devicepath), "%s/%s/device", DEVICE_DIR, deviceent->d_name); |
314 |
dev_len = readlink(devicepath, deviced, MAX_STRING_LEN - 1); |
325 |
dev_len = readlink(devicepath, deviced, MAX_STRING_LEN - 1); |
|
|
326 |
zbx_snprintf(devicepath, sizeof(devicepath), "%s/%s", DEVICE_DIR, deviceent->d_name); |
315 |
|
327 |
|
316 |
if (0 > dev_len) |
328 |
if (0 > dev_len) |
317 |
{ |
329 |
{ |
318 |
/* No device link? Treat device as virtual */ |
330 |
/* No device link? Treat device as virtual */ |
319 |
zbx_snprintf(devicepath, sizeof(devicepath), "%s/%s", DEVICE_DIR, deviceent->d_name); |
331 |
err = get_device_info(devicepath, NULL, device_info, &subfolder); |
320 |
err = get_device_info(devicepath, NULL, device_info); |
|
|
321 |
} |
332 |
} |
322 |
else |
333 |
else |
323 |
{ |
334 |
{ |
Lines 331-342
Link Here
|
331 |
} |
342 |
} |
332 |
else |
343 |
else |
333 |
{ |
344 |
{ |
334 |
err = get_device_info(devicepath, device_p, device_info); |
345 |
err = get_device_info(devicepath, device_p, device_info, &subfolder); |
335 |
} |
346 |
} |
336 |
} |
347 |
} |
337 |
|
348 |
|
338 |
if (SUCCEED == err && 0 == strcmp(device_info, device)) |
349 |
if (SUCCEED == err && 0 == strcmp(device_info, device)) |
339 |
{ |
350 |
{ |
|
|
351 |
zbx_snprintf(devicepath, sizeof(devicepath), "%s/%s%s", DEVICE_DIR, deviceent->d_name, |
352 |
subfolder); |
353 |
|
340 |
if (DO_ONE == do_task) |
354 |
if (DO_ONE == do_task) |
341 |
{ |
355 |
{ |
342 |
zbx_snprintf(sensorname, sizeof(sensorname), "%s/%s_input", devicepath, name); |
356 |
zbx_snprintf(sensorname, sizeof(sensorname), "%s/%s_input", devicepath, name); |