]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - util.c
Assemble: allow members of containers to be assembled and auto-assembled.
[thirdparty/mdadm.git] / util.c
diff --git a/util.c b/util.c
index 379403d0546fb8eb8e5ae3103e0d80b132fbed0c..1736d70791c8ce5d145f6c01516384f4c19adb30 100644 (file)
--- a/util.c
+++ b/util.c
@@ -432,7 +432,7 @@ int is_standard(char *dev, int *nump)
        if (strncmp(d, "/d",2)==0)
                d += 2, type=1; /* /dev/md/dN{pM} */
        else if (strncmp(d, "/md_d", 5)==0)
-               d += 5, type=1; /* /dev/md_dNpM */
+               d += 5, type=1; /* /dev/md_dN{pM} */
        else if (strncmp(d, "/md", 3)==0)
                d += 3, type=-1; /* /dev/mdN */
        else if (d-dev > 3 && strncmp(d-2, "md/", 3)==0)
@@ -828,6 +828,20 @@ int open_dev_excl(int devnum)
        return -1;
 }
 
+int same_dev(char *one, char *two)
+{
+       struct stat st1, st2;
+       if (stat(one, &st1) != 0)
+               return 0;
+       if (stat(two, &st2) != 0)
+               return 0;
+       if ((st1.st_mode & S_IFMT) != S_IFBLK)
+               return 0;
+       if ((st2.st_mode & S_IFMT) != S_IFBLK)
+               return 0;
+       return st1.st_rdev == st2.st_rdev;
+}
+
 struct superswitch *superlist[] = { &super0, &super1, &super_ddf, &super_imsm, NULL };
 
 #if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
@@ -1116,13 +1130,34 @@ int devname2devnum(char *name)
 
 int stat2devnum(struct stat *st)
 {
+       char path[30];
+       char link[200];
+       char *cp;
+       int n;
+
        if ((S_IFMT & st->st_mode) == S_IFBLK) {
                if (major(st->st_rdev) == MD_MAJOR)
                        return minor(st->st_rdev);
-               else
-                       return -1- (minor(st->st_rdev)>>6);
+               else if (major(st->st_rdev) == get_mdp_major())
+                       return -1- (minor(st->st_rdev)>>MdpMinorShift);
+
+               /* must be an extended-minor partition. Look at the
+                * /sys/dev/block/%d:%d link which must look like
+                * ../../block/mdXXX/mdXXXpYY
+                */
+               sprintf(path, "/sys/dev/block/%d:%d", major(st->st_rdev),
+                       minor(st->st_rdev));
+               n = readlink(path, link, sizeof(link)-1);
+               if (n <= 0)
+                       return NoMdDev;
+               link[n] = 0;
+               cp = strrchr(link, '/');
+               if (cp) *cp = 0;
+               cp = strchr(link, '/');
+               if (cp && strncmp(cp, "/md", 3) == 0)
+                       return devname2devnum(cp+1);
        }
-       return -1;
+       return NoMdDev;
 
 }
 
@@ -1131,7 +1166,7 @@ int fd2devnum(int fd)
        struct stat stb;
        if (fstat(fd, &stb) == 0)
                return stat2devnum(&stb);
-       return -1;
+       return NoMdDev;
 }
 
 int mdmon_running(int devnum)
@@ -1188,7 +1223,7 @@ int start_mdmon(int devnum)
                NULL
        };
 
-       if (env_no_mdmon())
+       if (check_env("MDADM_NO_MDMON"))
                return 0;
 
        len = readlink("/proc/self/exe", pathbuf, sizeof(pathbuf));
@@ -1227,9 +1262,9 @@ int start_mdmon(int devnum)
        return 0;
 }
 
-int env_no_mdmon(void)
+int check_env(char *name)
 {
-       char *val = getenv("MDADM_NO_MDMON");
+       char *val = getenv(name);
 
        if (val && atoi(val) == 1)
                return 1;