Example #1
0
int fd_is_raid (int fd)
{
	struct stat st;

	if (!md_major())
		return 0;  /* not a RAID device */
	if (fstat(fd, &st)) {
		perror("fstat()");
		return 0;  /* ugh.. shouldn't happen */
	}
	return (major(st.st_rdev) == md_major());
}
Example #2
0
/*
 * "md" (RAID) devices have per-member "start" offsets.
 * Realistically, we can only support raid1 arrays here,
 * and only then when all members have the same "start" offsets.
 */
static int get_raid1_start_lba (int fd, __u64 *start_lba)
{
	char buf[32];
	unsigned int member, raid_disks;
	__u64 start = 0, offset = 0;

	if (sysfs_get_attr(fd, "md/level",      "%s", buf,         NULL, 0)
	 || sysfs_get_attr(fd, "md/raid_disks", "%u", &raid_disks, NULL, 0))
		return ENODEV;
	if (strcmp(buf, "raid1") || !raid_disks)
		return EINVAL;
	for (member = 0; member < raid_disks; ++member) {
		__u64 member_start, member_offset;
		char member_path[32];
		sprintf(member_path, "md/rd%u/offset", member);
		if (sysfs_get_attr(fd, member_path, "%llu", &member_offset, NULL, 0))
			member_offset = 0;
		sprintf(member_path, "md/rd%u/block/dev", member);
		if (sysfs_get_attr(fd, member_path, "%s", buf, NULL, 0))
			return EINVAL;
		if (md_major() == (unsigned)atoi(buf))  /* disallow recursive RAIDs */
			return EINVAL;
		sprintf(member_path, "md/rd%u/block/start", member);
		if (sysfs_get_attr(fd, member_path, "%llu", &member_start, NULL, 0))
			return ENODEV;
		if (member == 0) {
			start  = member_start;
			offset = member_offset;
		} else if (member_start != start || member_offset != offset)
			return EINVAL;
		/* FIXME?  Should --fibmap should account for member_offset in calculations? */
	}
	*start_lba = start;
	return 0;
}
Example #3
0
static int _is_partitionable(struct device *dev)
{
	int parts = max_partitions(MAJOR(dev->dev));

	/* All MD devices are partitionable via blkext (as of 2.6.28) */
	if (MAJOR(dev->dev) == md_major())
		return 1;

	if ((parts <= 1) || (MINOR(dev->dev) % parts))
		return 0;

	return 1;
}
Example #4
0
File: dev-md.c Project: Jajcus/lvm2
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;
}