static int _md_sysfs_attribute_snprintf(char *path, size_t size, const char *sysfs_dir, struct device *blkdev, const char *attribute) { struct stat info; dev_t dev = blkdev->dev; int ret = -1; if (!sysfs_dir || !*sysfs_dir) return ret; if (MAJOR(dev) == blkext_major()) { /* lookup parent MD device from blkext partition */ if (!get_primary_dev(sysfs_dir, blkdev, &dev)) return ret; } if (MAJOR(dev) != 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(const struct device *dev) { dev_t primary_dev; if (MAJOR(dev->dev) == _md_major) return 1; if (MAJOR(dev->dev) == _drbd_major) return 1; if (MAJOR(dev->dev) == _emcpower_major) return 1; if ((MAJOR(dev->dev) == _blkext_major) && (get_primary_dev(sysfs_dir_path(), dev, &primary_dev)) && (MAJOR(primary_dev) == _md_major)) return 1; return 0; }
static unsigned long _dev_topology_attribute(const char *attribute, const char *sysfs_dir, struct device *dev) { const char *sysfs_fmt_str = "%s/dev/block/%d:%d/%s"; char path[PATH_MAX+1], buffer[64]; FILE *fp; struct stat info; dev_t uninitialized_var(primary); unsigned long result = 0UL; if (!attribute || !*attribute) return_0; if (!sysfs_dir || !*sysfs_dir) return_0; if (dm_snprintf(path, PATH_MAX, sysfs_fmt_str, sysfs_dir, (int)MAJOR(dev->dev), (int)MINOR(dev->dev), attribute) < 0) { log_error("dm_snprintf %s failed", attribute); return 0; } /* * 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_error("stat", path); return 0; } if (!get_primary_dev(sysfs_dir, dev, &primary)) return 0; /* get attribute from partition's primary device */ if (dm_snprintf(path, PATH_MAX, sysfs_fmt_str, sysfs_dir, (int)MAJOR(primary), (int)MINOR(primary), attribute) < 0) { log_error("primary dm_snprintf %s failed", attribute); return 0; } if (stat(path, &info) == -1) { if (errno != ENOENT) log_sys_error("stat", path); return 0; } } if (!(fp = fopen(path, "r"))) { log_sys_error("fopen", path); return 0; } if (!fgets(buffer, sizeof(buffer), fp)) { log_sys_error("fgets", path); goto out; } if (sscanf(buffer, "%lu", &result) != 1) { log_error("sysfs file %s not in expected format: %s", path, buffer); goto out; } log_very_verbose("Device %s %s is %lu bytes.", dev_name(dev), attribute, result); out: if (fclose(fp)) log_sys_error("fclose", path); return result >> SECTOR_SHIFT; }