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);
- return NULL;
+ 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)
- strcpy(sra->sys_name, cp+1);
++ return;
+ link[n] = 0;
+ cp = strrchr(link, '/');
+ if (cp) *cp = 0;
+ cp = strchr(link, '/');
+ if (cp && strncmp(cp, "/md", 3) == 0)
- return NULL;
++ strcpy(mdi->sys_name, cp+1);
+ else
++ 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);