]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - sysfs.c
Merge branch 'master' into scratch-3.0
[thirdparty/mdadm.git] / sysfs.c
diff --git a/sysfs.c b/sysfs.c
index 23d2f18d87d172fd3e9b5ce8ece71dec71733ae1..8bcdaa59cbac61f093025f4aea876bf2c7815844 100644 (file)
--- a/sysfs.c
+++ b/sysfs.c
@@ -61,8 +61,12 @@ int sysfs_open(int devnum, char *devname, char *attr)
 {
        char fname[50];
        int fd;
+       char *mdname = devnum2devname(devnum);
 
-       sprintf(fname, "/sys/block/%s/md/", devnum2devname(devnum));
+       if (!mdname)
+               return -1;
+
+       sprintf(fname, "/sys/block/%s/md/", mdname);
        if (devname) {
                strcat(fname, devname);
                strcat(fname, "/");
@@ -71,6 +75,7 @@ int sysfs_open(int devnum, char *devname, char *attr)
        fd = open(fname, O_RDWR);
        if (fd < 0 && errno == EACCES)
                fd = open(fname, O_RDONLY);
+       free(mdname);
        return fd;
 }
 
@@ -83,11 +88,34 @@ void sysfs_init(struct mdinfo *mdi, int fd, int devnum)
                        return;
                if (ioctl(fd, RAID_VERSION, &vers) != 0)
                        return;
-               if (major(stb.st_rdev)==9)
+               if (major(stb.st_rdev) == MD_MAJOR)
                        sprintf(mdi->sys_name, "md%d", (int)minor(stb.st_rdev));
-               else
+               else if (major(stb.st_rdev) == get_mdp_major())
                        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;
+                       link[n] = 0;
+                       cp = strrchr(link, '/');
+                       if (cp) *cp = 0;
+                       cp = strchr(link, '/');
+                       if (cp && strncmp(cp, "/md", 3) == 0)
+                               strcpy(mdi->sys_name, cp+1);
+                       else
+                               return;
+               }
        } else {
                if (devnum >= 0)
                        sprintf(mdi->sys_name, "md%d", devnum);
@@ -358,7 +386,7 @@ unsigned long long get_component_size(int fd)
        char fname[50];
        int n;
        if (fstat(fd, &stb)) return 0;
-       if (major(stb.st_rdev) == 9)
+       if (major(stb.st_rdev) != get_mdp_major())
                sprintf(fname, "/sys/block/md%d/md/component_size",
                        (int)minor(stb.st_rdev));
        else