static int _md_sysfs_attribute_snprintf(char *path, size_t size, struct dev_types *dt, struct device *blkdev, const char *attribute) { const char *sysfs_dir = dm_sysfs_dir(); struct stat info; dev_t dev = blkdev->dev; int ret = -1; if (!sysfs_dir || !*sysfs_dir) return ret; if (MAJOR(dev) == dt->blkext_major) { /* lookup parent MD device from blkext partition */ if (!dev_get_primary_dev(dt, blkdev, &dev)) return ret; } if (MAJOR(dev) != dt->md_major) return ret; ret = dm_snprintf(path, size, "%s/dev/block/%d:%d/md/%s", sysfs_dir, (int)MAJOR(dev), (int)MINOR(dev), attribute); if (ret < 0) { log_error("dm_snprintf md %s failed", attribute); return ret; } if (stat(path, &info) == -1) { if (errno != ENOENT) { log_sys_error("stat", path); return ret; } /* old sysfs structure */ ret = dm_snprintf(path, size, "%s/block/md%d/md/%s", sysfs_dir, (int)MINOR(dev), attribute); if (ret < 0) { log_error("dm_snprintf old md %s failed", attribute); return ret; } } return ret; }
int dev_subsystem_part_major(struct dev_types *dt, struct device *dev) { dev_t primary_dev; if (MAJOR(dev->dev) == dt->device_mapper_major) return 1; if (MAJOR(dev->dev) == dt->drbd_major) return 1; if (MAJOR(dev->dev) == dt->emcpower_major) return 1; if (MAJOR(dev->dev) == dt->power2_major) return 1; if ((MAJOR(dev->dev) == dt->blkext_major) && dev_get_primary_dev(dt, dev, &primary_dev) && (MAJOR(primary_dev) == dt->md_major)) return 1; return 0; }
static unsigned long _dev_topology_attribute(struct dev_types *dt, const char *attribute, struct device *dev, unsigned long default_value) { const char *sysfs_dir = dm_sysfs_dir(); char path[PATH_MAX], buffer[64]; FILE *fp; struct stat info; dev_t uninitialized_var(primary); unsigned long result = default_value; unsigned long value = 0UL; if (!attribute || !*attribute) goto_out; if (!sysfs_dir || !*sysfs_dir) goto_out; if (!_snprintf_attr(path, sizeof(path), sysfs_dir, attribute, dev->dev)) goto_out; /* * check if the desired sysfs attribute exists * - if not: either the kernel doesn't have topology support * or the device could be a partition */ if (stat(path, &info) == -1) { if (errno != ENOENT) { log_sys_debug("stat", path); goto out; } if (!dev_get_primary_dev(dt, dev, &primary)) goto out; /* get attribute from partition's primary device */ if (!_snprintf_attr(path, sizeof(path), sysfs_dir, attribute, primary)) goto_out; if (stat(path, &info) == -1) { if (errno != ENOENT) log_sys_debug("stat", path); goto out; } } if (!(fp = fopen(path, "r"))) { log_sys_debug("fopen", path); goto out; } if (!fgets(buffer, sizeof(buffer), fp)) { log_sys_debug("fgets", path); goto out_close; } if (sscanf(buffer, "%lu", &value) != 1) { log_warn("sysfs file %s not in expected format: %s", path, buffer); goto out_close; } log_very_verbose("Device %s: %s is %lu%s.", dev_name(dev), attribute, result, default_value ? "" : " bytes"); result = value >> SECTOR_SHIFT; out_close: if (fclose(fp)) log_sys_debug("fclose", path); out: return result; }