]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Incremental.c
IMSM - allow assembling any imsm array even without OROM.
[thirdparty/mdadm.git] / Incremental.c
index 8e101d7035ecf329edf17369da0b95b501bb7a53..bc23a885d5e404358646eb2f4a5b0c8d35b40336 100644 (file)
@@ -116,7 +116,7 @@ int Incremental(char *devname, struct context *c,
                                devname);
                return rv;
        }
-       dfd = dev_open(devname, O_RDONLY|O_EXCL);
+       dfd = dev_open(devname, O_RDONLY);
        if (dfd < 0) {
                if (c->verbose >= 0)
                        pr_err("cannot open %s: %s.\n",
@@ -127,6 +127,8 @@ int Incremental(char *devname, struct context *c,
        if (must_be_container(dfd)) {
                if (!st)
                        st = super_by_fd(dfd, NULL);
+               if (st)
+                       st->ignore_hw_compat = 1;
                if (st && st->ss->load_container)
                        rv = st->ss->load_container(st, dfd, NULL);
 
@@ -185,6 +187,7 @@ int Incremental(char *devname, struct context *c,
                               st, c->verbose);
                goto out;
        }
+       st->ignore_hw_compat = 1;
        if (st->ss->compare_super == NULL ||
            st->ss->load_super(st, dfd, NULL)) {
                if (c->verbose >= 0)
@@ -270,6 +273,22 @@ int Incremental(char *devname, struct context *c,
        if (map_lock(&map))
                pr_err("failed to get exclusive lock on "
                        "mapfile\n");
+       /* Now check we can get O_EXCL.  If not, probably "mdadm -A" has
+        * taken over
+        */
+       dfd = dev_open(devname, O_RDONLY|O_EXCL);
+       if (dfd < 0) {
+               if (c->verbose >= 0)
+                       pr_err("cannot reopen %s: %s.\n",
+                               devname, strerror(errno));
+               goto out_unlock;
+       }
+       /* Cannot hold it open while we add the device to the array,
+        * so we must release the O_EXCL and depend on the map_lock()
+        */
+       close(dfd);
+       dfd = -1;
+
        mp = map_by_uuid(&map, info.uuid);
        if (mp)
                mdfd = open_dev(mp->devnum);
@@ -494,6 +513,14 @@ int Incremental(char *devname, struct context *c,
        if (c->runstop > 0 || active_disks >= info.array.working_disks) {
                struct mdinfo *dsk;
                /* Let's try to start it */
+
+               if (info.reshape_active && !(info.reshape_active & RESHAPE_NO_BACKUP)) {
+                       fprintf(stderr, Name
+                               ": %s: This array is being reshaped and cannot be started\n"
+                               "      by --incremental.  Please use --assemble\n",
+                               chosen_name);
+                       goto out;
+               }
                if (match && match->bitmap_file) {
                        int bmfd = open(match->bitmap_file, O_RDWR);
                        if (bmfd < 0) {
@@ -617,6 +644,7 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
        /* count how many devices in sra think they are active */
        struct mdinfo *d;
        int cnt = 0;
+       int replcnt = 0;
        __u64 max_events = 0;
        char *avail = NULL;
        int *best = NULL;
@@ -692,7 +720,8 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
                                best[info.disk.raid_disk] = devnum;
                                st->ss->getinfo_super(st, bestinfo, NULL);
                        }
-               }
+               } else if (info.disk.state & (1<<MD_DISK_REPLACEMENT))
+                       replcnt++;
                st->ss->free_super(st);
        }
        if (!avail)
@@ -719,7 +748,7 @@ static int count_active(struct supertype *st, struct mdinfo *sra,
        }
        free(best);
        free(devmap);
-       return cnt;
+       return cnt + replcnt;
 }
 
 /* test if container has degraded member(s) */
@@ -1285,6 +1314,9 @@ int IncrementalScan(int verbose)
                                               me->path, strerror(errno));
                        }
                }
+               /* FIXME check for reshape_active and consider not
+                * starting array.
+                */
                sra = sysfs_read(mdfd, 0, 0);
                if (sra) {
                        if (sysfs_set_str(sra, NULL,