From: NeilBrown Date: Thu, 30 Oct 2008 06:02:49 +0000 (+1100) Subject: Merge branch 'master' into devel-3.0 X-Git-Tag: mdadm-3.0-devel2~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9c3220067be02b5ef4da6e51ec91f928572d5223;p=thirdparty%2Fmdadm.git Merge branch 'master' into devel-3.0 --- 9c3220067be02b5ef4da6e51ec91f928572d5223 diff --cc sysfs.c index 58c84e26,6350242b..8bcdaa59 --- a/sysfs.c +++ b/sysfs.c @@@ -84,46 -80,44 +84,69 @@@ void sysfs_init(struct mdinfo *mdi, in if (fd >= 0) { struct stat stb; mdu_version_t vers; - if (fstat(fd, &stb)) return NULL; + if (fstat(fd, &stb)) + return; if (ioctl(fd, RAID_VERSION, &vers) != 0) - return NULL; + return; - if (major(stb.st_rdev)==9) + if (major(stb.st_rdev) == MD_MAJOR) - sprintf(sra->sys_name, "md%d", (int)minor(stb.st_rdev)); + sprintf(mdi->sys_name, "md%d", (int)minor(stb.st_rdev)); - else + else if (major(stb.st_rdev) == get_mdp_major()) - sprintf(sra->sys_name, "md_d%d", + sprintf(mdi->sys_name, "md_d%d", (int)minor(stb.st_rdev)>>MdpMinorShift); + else { + /* must be an extended-minor partition. Look at the + * /sys/dev/block/%d:%d link which must look like + * ../../block/mdXXX/mdXXXpYY + */ + char path[30]; + char link[200]; + char *cp; + int n; + sprintf(path, "/sys/dev/block/%d:%d", major(stb.st_rdev), + minor(stb.st_rdev)); + n = readlink(path, link, sizeof(link)-1); + if (n <= 0) - return NULL; ++ return; + link[n] = 0; + cp = strrchr(link, '/'); + if (cp) *cp = 0; + cp = strchr(link, '/'); + if (cp && strncmp(cp, "/md", 3) == 0) - strcpy(sra->sys_name, cp+1); ++ strcpy(mdi->sys_name, cp+1); + else - return NULL; ++ return; + } } else { if (devnum >= 0) - sprintf(sra->sys_name, "md%d", devnum); + sprintf(mdi->sys_name, "md%d", devnum); else - sprintf(sra->sys_name, "md_d%d", + sprintf(mdi->sys_name, "md_d%d", -1-devnum); } +} + +struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options) +{ + /* Longest possible name in sysfs, mounted at /sys, is + * /sys/block/md_dXXX/md/dev-XXXXX/block/dev + * /sys/block/md_dXXX/md/metadata_version + * which is about 41 characters. 50 should do for now + */ + char fname[50]; + char buf[1024]; + char *base; + char *dbase; + struct mdinfo *sra; + struct mdinfo *dev; + DIR *dir = NULL; + struct dirent *de; + + sra = malloc(sizeof(*sra)); + if (sra == NULL) + return sra; + memset(sra, 0, sizeof(*sra)); + sysfs_init(sra, fd, devnum); + sprintf(fname, "/sys/block/%s/md/", sra->sys_name); base = fname + strlen(fname);