]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Incremental.c
util: make env checking more generic
[thirdparty/mdadm.git] / Incremental.c
index 869ae8396802f81a729e3678d60de55362f38b03..08960a5f5fde3664197b7b65d96603eace4a6f59 100644 (file)
@@ -91,8 +91,6 @@ int Incremental(char *devname, int verbose, int runstop,
 
        struct createinfo *ci = conf_get_create_info();
 
-       if (autof == 0)
-               autof = ci->autof;
 
        /* 1/ Check if device is permitted by mdadm.conf */
 
@@ -216,15 +214,18 @@ int Incremental(char *devname, int verbose, int runstop,
                match = array_list;
        }
 
-       /* 3a/ if not, check for homehost match.  If no match, reject. */
+       /* 3a/ if not, check for homehost match.  If no match, continue
+        * but don't trust the 'name' in the array. Thus a 'random' minor
+        * number will be assigned, and the device name will be based
+        * on that. */
        if (!match) {
                if (homehost == NULL ||
                       st->ss->match_home(st, homehost) != 1)
                        uuid_for_name = 1;
        }
        /* 4/ Determine device number. */
-       /* - If in mdadm.conf with std name, use that */
-       /* - UUID in /var/run/mdadm.map  use that */
+       /* - If in mdadm.conf with std name, get number from name. */
+       /* - UUID in /var/run/mdadm.map  get number from mapping */
        /* - If name is suggestive, use that. unless in use with */
        /*           different uuid. */
        /* - Choose a free, high number. */
@@ -233,7 +234,7 @@ int Incremental(char *devname, int verbose, int runstop,
        mp = map_by_uuid(&map, info.uuid);
 
        if (uuid_for_name && ! mp) {
-               name_to_use = fname_from_uuid(st, &info, nbuf);
+               name_to_use = fname_from_uuid(st, &info, nbuf, '-');
                if (verbose >= 0)
                        fprintf(stderr, Name
                ": not found in mdadm.conf and not identified by homehost"
@@ -241,9 +242,19 @@ int Incremental(char *devname, int verbose, int runstop,
        } else
                name_to_use = info.name;
 
-       if (match && is_standard(match->devname, &devnum))
-               /* We have devnum now */;
-       else if (mp != NULL)
+       /* There are three possible sources for 'autof':  command line,
+        * ARRAY line in mdadm.conf, or CREATE line in mdadm.conf.
+        * ARRAY takes precedence, then command line, then
+        * CREATE.
+        */
+       if (match && match->autof)
+               autof = match->autof;
+       if (autof == 0)
+               autof = ci->autof;
+
+       if (match && (rv = is_standard(match->devname, &devnum))) {
+               devnum = (rv > 0) ? (-1-devnum) : devnum;
+       } else if (mp != NULL)
                devnum = mp->devnum;
        else {
                /* Have to guess a bit. */
@@ -300,7 +311,7 @@ int Incremental(char *devname, int verbose, int runstop,
                        devnum = use_partitions ? (-1-devnum) : devnum;
        }
 
-       mdfd = open_mddev_devnum(match ? match->devname : mp ? mp->path : NULL,
+       mdfd = create_mddev_devnum(match ? match->devname : mp ? mp->path : NULL,
                                 devnum,
                                 name_to_use,
                                 chosen_name, autof >> 3);
@@ -490,7 +501,8 @@ int Incremental(char *devname, int verbose, int runstop,
                        close(bmfd);
                }
                sra = sysfs_read(mdfd, devnum, 0);
-               if (sra == NULL || active_disks >= info.array.working_disks)
+               if ((sra == NULL || active_disks >= info.array.working_disks)
+                   && uuid_for_name == 0)
                        rv = ioctl(mdfd, RUN_ARRAY, NULL);
                else
                        rv = sysfs_set_str(sra, NULL,
@@ -587,12 +599,18 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
                if (ok != 0)
                        continue;
                st->ss->getinfo_super(st, &info);
+               if (!avail) {
+                       avail = malloc(info.array.raid_disks);
+                       if (!avail) {
+                               fprintf(stderr, Name ": out of memory.\n");
+                               exit(1);
+                       }
+                       memset(avail, 0, info.array.raid_disks);
+                       *availp = avail;
+               }
+
                if (info.disk.state & (1<<MD_DISK_SYNC))
                {
-                       if (avail == NULL) {
-                               avail = malloc(info.array.raid_disks);
-                               memset(avail, 0, info.array.raid_disks);
-                       }
                        if (cnt == 0) {
                                cnt++;
                                max_events = info.events;
@@ -696,7 +714,7 @@ int IncrementalScan(int verbose)
                mdu_array_info_t array;
                mdu_bitmap_file_t bmf;
                struct mdinfo *sra;
-               int mdfd = open_mddev_devnum(me->path, me->devnum,
+               int mdfd = create_mddev_devnum(me->path, me->devnum,
                                             NULL, path, 0);
                if (mdfd < 0)
                        continue;
@@ -753,19 +771,6 @@ int IncrementalScan(int verbose)
        return rv;
 }
 
-static char *container2devname(char *devname)
-{
-       int fd = open(devname, O_RDONLY);
-       char *mdname = NULL;
-
-       if (fd >= 0) {
-               mdname = devnum2devname(fd2devnum(fd));
-               close(fd);
-       }
-
-       return mdname;
-}
-
 int Incremental_container(struct supertype *st, char *devname, int verbose,
                          int runstop, int autof)
 {
@@ -775,15 +780,9 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
 
        struct mdinfo *list = st->ss->container_content(st);
        struct mdinfo *ra;
-       char *mdname = container2devname(devname);
-
-       if (!mdname) {
-               fprintf(stderr, Name": failed to determine device name\n");
-               return 2;
-       }
 
        for (ra = list ; ra ; ra = ra->next) {
-               struct mdinfo *dev;
+               struct mdinfo *dev, *sra;
                int devnum = -1;
                int mdfd;
                char chosen_name[1024];
@@ -793,6 +792,7 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
                struct map_ent *mp, *map = NULL;
                char nbuf[64];
                char *name_to_use;
+               struct mddev_ident_s *match = NULL;
 
                if ((autof&7) == 3 || (autof&7) == 5)
                        usepart = 0;
@@ -804,12 +804,59 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
                    ! *name_to_use ||
                    (*devname != '/' || strncmp("UUID-", strrchr(devname,'/')+1,5) == 0)
                        )
-                       name_to_use = fname_from_uuid(st, ra, nbuf);
+                       name_to_use = fname_from_uuid(st, ra, nbuf, '-');
                    
-               if (mp)
+               if (!mp) {
+
+                       /* Check in mdadm.conf for devices == devname and
+                        * member == ra->text_version after second slash.
+                        */
+                       char *sub = strchr(ra->text_version+1, '/');
+                       struct mddev_ident_s *array_list;
+                       if (sub) {
+                               sub++;
+                               array_list = conf_get_ident(NULL);
+                       } else
+                               array_list = NULL;
+                       for(; array_list ; array_list = array_list->next) {
+                               int fd;
+                               char *dn;
+                               if (array_list->member == NULL ||
+                                   array_list->container == NULL)
+                                       continue;
+                               if (strcmp(array_list->member, sub) != 0)
+                                       continue;
+                               if (array_list->uuid_set &&
+                                   !same_uuid(ra->uuid, array_list->uuid, st->ss->swapuuid))
+                                       continue;
+                               fd = open(array_list->container, O_RDONLY);
+                               if (fd < 0)
+                                       continue;
+                               dn = devnum2devname(fd2devnum(fd));
+                               close(fd);
+                               if (strncmp(dn, ra->text_version+1,
+                                           strlen(dn)) != 0 ||
+                                   ra->text_version[strlen(dn)+1] != '/') {
+                                       free(dn);
+                                       continue;
+                               }
+                               free(dn);
+                               /* we have a match */
+                               match = array_list;
+                               if (verbose>0)
+                                       fprintf(stderr, Name ": match found for member %s\n",
+                                               array_list->member);
+                               break;
+                       }
+               }
+
+               if (match && is_standard(match->devname, &devnum))
+                       /* we have devnum now */;
+               else if (mp)
                        devnum = mp->devnum;
+               else if (is_standard(name_to_use, &devnum))
+                       /* have devnum */;
                else {
-
                        n = name_to_use;
                        if (*n == 'd')
                                n++;
@@ -851,7 +898,8 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
                        else
                                devnum = find_free_devnum(usepart);
                }
-               mdfd = open_mddev_devnum(mp ? mp->path : NULL, devnum, name_to_use,
+               mdfd = create_mddev_devnum(mp ? mp->path : match ? match->devname : NULL,
+                                        devnum, name_to_use,
                                         chosen_name, autof>>3);
 
                if (mdfd < 0) {
@@ -860,8 +908,16 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
                        return 2;
                }
 
+
                sysfs_init(ra, mdfd, 0);
-               sysfs_set_array(ra, md_get_version(mdfd));
+
+               sra = sysfs_read(mdfd, 0, GET_VERSION);
+               if (sra == NULL || strcmp(sra->text_version, ra->text_version) != 0)
+                       if (sysfs_set_array(ra, md_get_version(mdfd)) != 0)
+                               return 1;
+               if (sra)
+                       sysfs_free(sra);
+
                for (dev = ra->devs; dev; dev = dev->next)
                        if (sysfs_add_disk(ra, dev) == 0)
                                working++;