Index: src/libs/zbxsysinfo/linux/sensors.c =================================================================== --- src/libs/zbxsysinfo/linux/sensors.c (revision 55870) +++ src/libs/zbxsysinfo/linux/sensors.c (revision 55871) @@ -29,6 +29,7 @@ #define DEVICE_DIR "/proc/sys/dev/sensors" #else #define DEVICE_DIR "/sys/class/hwmon" +static char *locations[] = {"", "/device", NULL}; #endif #define ATTR_MAX 128 @@ -84,46 +85,54 @@ * * * Function: sysfs_read_attr * * * - * Purpose: read the name attribute of a sensor from sysf * + * Purpose: locate and read the name attribute of a sensor from sysfs * * * - * Parameters: device - [IN] the path to sensor data in sysf * + * Parameters: device - [IN] the path to sensor data in sysfs * + * attribute - [OUT] the sensor name * * * - * Return value: The seonsor name or NULL pointer * + * Return value: Subfolder where the sensor name file was found or NULL * * * - * Comments: The returned string must be freed by caller after it's been used. * + * Comments: attribute string must be freed by caller after it's been used. * * * *********************************************************************************/ -static char *sysfs_read_attr(const char *device) +static const char *sysfs_read_attr(const char *device, char **attribute) { - char path[MAX_STRING_LEN], buf[ATTR_MAX], *p; + char path[MAX_STRING_LEN], buf[ATTR_MAX], *p, **location; FILE *f; - zbx_snprintf(path, MAX_STRING_LEN, "%s/%s", device, "name"); + for (location = locations; NULL != *location; location++) + { + zbx_snprintf(path, MAX_STRING_LEN, "%s%s/name", device, *location); - if (NULL == (f = fopen(path, "r"))) - return NULL; + if (NULL != (f = fopen(path, "r"))) + { + p = fgets(buf, ATTR_MAX, f); + zbx_fclose(f); - p = fgets(buf, ATTR_MAX, f); - zbx_fclose(f); + if (NULL == p) + break; - if (NULL == p) - return NULL; + /* Last byte is a '\n'; chop that off */ + buf[strlen(buf) - 1] = '\0'; - /* Last byte is a '\n'; chop that off */ - buf[strlen(buf) - 1] = '\0'; + *attribute = zbx_strdup(*attribute, buf); + return *location; + } + } - return zbx_strdup(NULL, buf); + return NULL; } -int get_device_info(const char *dev_path, const char *dev_name, char *device_info) +int get_device_info(const char *dev_path, const char *dev_name, char *device_info, const char **name_subfolder) { char bus_path[MAX_STRING_LEN], linkpath[MAX_STRING_LEN], subsys_path[MAX_STRING_LEN]; - char *subsys, *prefix, *bus_attr = NULL; + char *subsys, *prefix = NULL, *bus_attr = NULL; + const char *bus_subfolder; int domain, bus, slot, fn, addr, vendor, product, sub_len, ret = FAIL; short int bus_spi, bus_i2c; /* ignore any device without name attribute */ - if (NULL == (prefix = sysfs_read_attr(dev_path))) + if (NULL == (*name_subfolder = sysfs_read_attr(dev_path, &prefix))) goto out; if (NULL == dev_name) @@ -138,7 +147,7 @@ } /* Find bus type */ - zbx_snprintf(linkpath, MAX_STRING_LEN, "%s/subsystem", dev_path); + zbx_snprintf(linkpath, MAX_STRING_LEN, "%s/device/subsystem", dev_path); sub_len = readlink(linkpath, subsys_path, MAX_STRING_LEN - 1); @@ -145,7 +154,7 @@ if (0 > sub_len && ENOENT == errno) { /* Fallback to "bus" link for kernels <= 2.6.17 */ - zbx_snprintf(linkpath, MAX_STRING_LEN, "%s/bus", dev_path); + zbx_snprintf(linkpath, MAX_STRING_LEN, "%s/device/bus", dev_path); sub_len = readlink(linkpath, subsys_path, MAX_STRING_LEN - 1); } @@ -175,9 +184,10 @@ } else { - zbx_snprintf(bus_path, sizeof(bus_path), "/sys/class/i2c-adapter/i2c-%d/device", bus_i2c); + zbx_snprintf(bus_path, sizeof(bus_path), "/sys/class/i2c-adapter/i2c-%d", bus_i2c); + bus_subfolder = sysfs_read_attr(bus_path, &bus_attr); - if (NULL != (bus_attr = sysfs_read_attr(bus_path))) + if (NULL != bus_subfolder && '\0' != *bus_subfolder) { if (0 != strncmp(bus_attr, "ISA ", 4)) goto out; @@ -298,6 +308,7 @@ struct dirent *sensorent, *deviceent; char hwmon_dir[MAX_STRING_LEN], devicepath[MAX_STRING_LEN], deviced[MAX_STRING_LEN], device_info[MAX_STRING_LEN], regex[MAX_STRING_LEN], *device_p; + const char *subfolder; int err, dev_len; zbx_snprintf(hwmon_dir, sizeof(hwmon_dir), "%s", DEVICE_DIR); @@ -312,12 +323,12 @@ zbx_snprintf(devicepath, sizeof(devicepath), "%s/%s/device", DEVICE_DIR, deviceent->d_name); dev_len = readlink(devicepath, deviced, MAX_STRING_LEN - 1); + zbx_snprintf(devicepath, sizeof(devicepath), "%s/%s", DEVICE_DIR, deviceent->d_name); if (0 > dev_len) { /* No device link? Treat device as virtual */ - zbx_snprintf(devicepath, sizeof(devicepath), "%s/%s", DEVICE_DIR, deviceent->d_name); - err = get_device_info(devicepath, NULL, device_info); + err = get_device_info(devicepath, NULL, device_info, &subfolder); } else { @@ -331,12 +342,15 @@ } else { - err = get_device_info(devicepath, device_p, device_info); + err = get_device_info(devicepath, device_p, device_info, &subfolder); } } if (SUCCEED == err && 0 == strcmp(device_info, device)) { + zbx_snprintf(devicepath, sizeof(devicepath), "%s/%s%s", DEVICE_DIR, deviceent->d_name, + subfolder); + if (DO_ONE == do_task) { zbx_snprintf(sensorname, sizeof(sensorname), "%s/%s_input", devicepath, name);