]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Merge branch 'master' into devel-3.0
authorNeilBrown <neilb@suse.de>
Thu, 30 Oct 2008 06:02:49 +0000 (17:02 +1100)
committerNeilBrown <neilb@suse.de>
Thu, 30 Oct 2008 06:02:49 +0000 (17:02 +1100)
1  2 
Detail.c
sysfs.c

diff --cc Detail.c
Simple merge
diff --cc sysfs.c
index 58c84e26339e8014027bcea6d722bf87b73b4030,6350242b6db175d0896cd01d9717ee6f63e03fd5..8bcdaa59cbac61f093025f4aea876bf2c7815844
+++ 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);
 -                              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);