]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Assemble.c
Clarify when update=super-minor happens automatcially
[thirdparty/mdadm.git] / Assemble.c
index 75da9a50dc641b7cab0492b2e5d88675d877451b..3c00c9116cbd19d5f9f8b29e0aac8b40b1c022a1 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include       "mdadm.h"
+#include       <ctype.h>
 
 static int name_matches(char *found, char *required, char *homehost)
 {
@@ -50,7 +51,7 @@ static int name_matches(char *found, char *required, char *homehost)
 }
 
 int Assemble(struct supertype *st, char *mddev, int mdfd,
-            mddev_ident_t ident, char *conffile,
+            mddev_ident_t ident,
             mddev_dev_t devlist, char *backup_file,
             int readonly, int runstop,
             char *update, char *homehost,
@@ -112,7 +113,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
         */
        int must_close = 0;
        int old_linux = 0;
-       int vers;
+       int vers = 0; /* Keep gcc quite - it really is initialised */
        void *first_super = NULL, *super = NULL;
        struct {
                char *devname;
@@ -180,7 +181,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                return 1;
        }
        if (devlist == NULL)
-               devlist = conf_get_devs(conffile);
+               devlist = conf_get_devs();
        else if (mdfd >= 0)
                inargv = 1;
 
@@ -376,7 +377,11 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                st->ss->getinfo_super(&info, first_super);
                c = strchr(info.name, ':');
                if (c) c++; else c= info.name;
-               asprintf(&mddev, "/dev/md/%s", c);
+               if (isdigit(*c) && ((ident->autof & 7)==4 || (ident->autof&7)==6))
+                       /* /dev/md/d0 style for partitionable */
+                       asprintf(&mddev, "/dev/md/d%s", c);
+               else
+                       asprintf(&mddev, "/dev/md/%s", c);
                mdfd = open_mddev(mddev, ident->autof);
                if (mdfd < 0)
                        return mdfd;
@@ -446,7 +451,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
 
                        if (strcmp(update, "uuid")==0 &&
                            ident->bitmap_fd)
-                               bitmap_update_uuid(ident->bitmap_fd, info.uuid);
+                               if (bitmap_update_uuid(ident->bitmap_fd, info.uuid) != 0)
+                                       fprintf(stderr, Name ": Could not update uuid on %s.\n",
+                                               devname);
                } else
 #endif
                {
@@ -492,6 +499,10 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        if (nextspare < info.array.raid_disks)
                                nextspare = info.array.raid_disks;
                        i = nextspare++;
+               } else {
+                       if (i >= info.array.raid_disks &&
+                           i >= nextspare)
+                               nextspare = i+1;
                }
                if (i < 10000) {
                        if (i >= bestcnt) {
@@ -507,6 +518,25 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                best = newbest;
                                bestcnt = newbestcnt;
                        }
+                       if (best[i] >=0 &&
+                           devices[best[i]].events == devices[devcnt].events &&
+                           devices[best[i]].minor != devices[devcnt].minor &&
+                           st->ss->major == 0 &&
+                           info.array.level != -4) {
+                               /* two different devices with identical superblock.
+                                * Could be a mis-detection caused by overlapping
+                                * partitions.  fail-safe.
+                                */
+                               fprintf(stderr, Name ": WARNING %s and %s appear"
+                                       " to have very similar superblocks.\n"
+                                       "      If they are really different, "
+                                       "please --zero the superblock on one\n"
+                                       "      If they are the same, please remove "
+                                       "one from the list.\n",
+                                       devices[best[i]].devname, devname);
+                               if (must_close) close(mdfd);
+                               return 1;
+                       }
                        if (best[i] == -1
                            || devices[best[i]].events < devices[devcnt].events)
                                best[i] = devcnt;