]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Assemble.c
Teach sysfs_add_disk() callers to use ->recovery_start versus 'insync' parameter
[thirdparty/mdadm.git] / Assemble.c
index 3bde9cea9279def7acb6da31baf0ed26336e0c63..560e2fe288e0ab2954adf91164fda232b8954228 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * mdadm - manage Linux "md" devices aka RAID arrays.
  *
- * Copyright (C) 2001-2006 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2001-2009 Neil Brown <neilb@suse.de>
  *
  *
  *    This program is free software; you can redistribute it and/or modify
  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *    Author: Neil Brown
- *    Email: <neilb@cse.unsw.edu.au>
- *    Paper: Neil Brown
- *           School of Computer Science and Engineering
- *           The University of New South Wales
- *           Sydney, 2052
- *           Australia
+ *    Email: <neilb@suse.de>
  */
 
 #include       "mdadm.h"
@@ -188,6 +183,8 @@ int Assemble(struct supertype *st, char *mddev,
        if (!devlist &&
            ident->uuid_set == 0 &&
            ident->super_minor < 0 &&
+           ident->name[0] == 0 &&
+           (ident->container == NULL || ident->member == NULL) &&
            ident->devices == NULL) {
                fprintf(stderr, Name ": No identity information available for %s - cannot assemble.\n",
                        mddev ? mddev : "further assembly");
@@ -318,11 +315,16 @@ int Assemble(struct supertype *st, char *mddev,
                        }
                        /* It is worth looking inside this container.
                         */
+                       if (verbose > 0)
+                               fprintf(stderr, Name ": looking in container %s\n",
+                                       devname);
                next_member:
                        if (tmpdev->content)
                                content = tmpdev->content;
                        else
                                content = tst->ss->container_content(tst);
+                       if (!content)
+                               goto loop; /* empty container */
 
                        tmpdev->content = content->next;
                        if (tmpdev->content == NULL)
@@ -406,6 +408,9 @@ int Assemble(struct supertype *st, char *mddev,
                                        fprintf(stderr, Name ": member %s in %s is already assembled\n",
                                                content->text_version,
                                                devname);
+                       skip:
+                               if (tmpdev->content)
+                                       goto next_member;
                                tst->ss->free_super(tst);
                                tst = NULL;
                                content = NULL;
@@ -413,6 +418,21 @@ int Assemble(struct supertype *st, char *mddev,
                                        goto loop;
                                return 1;
                        }
+                       if (ident->member && ident->member[0]) {
+                               char *s = strchr(content->text_version+1, '/');
+                               if (s == NULL) {
+                                       fprintf(stderr, Name ": badly formatted version: %s\n",
+                                               content->text_version);
+                                       goto skip;
+                               }
+                               if (strcmp(ident->member, s+1) != 0) {
+                                       if (report_missmatch)
+                                               fprintf(stderr,
+                                                       Name ": skipping wrong member %s\n",
+                                                       content->text_version);
+                                       goto skip;
+                               }
+                       }
                        st = tst; tst = NULL;
                        if (!auto_assem && tmpdev->next != NULL) {
                                fprintf(stderr, Name ": %s is a container, but is not "
@@ -421,6 +441,9 @@ int Assemble(struct supertype *st, char *mddev,
                                st->ss->free_super(st);
                                return 1;
                        }
+                       if (verbose > 0)
+                               fprintf(stderr, Name ": found match on member %s in %s\n",
+                                       content->text_version, devname);
                        break;
                }
                if (st == NULL)
@@ -566,6 +589,7 @@ int Assemble(struct supertype *st, char *mddev,
 #endif
        /* Ok, no bad inconsistancy, we can try updating etc */
        bitmap_done = 0;
+       content->update_private = NULL;
        for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
                char *devname = tmpdev->devname;
                struct stat stb;
@@ -659,7 +683,7 @@ int Assemble(struct supertype *st, char *mddev,
                            > devices[most_recent].i.events)
                                most_recent = devcnt;
                }
-               if (content->array.level == -4)
+               if (content->array.level == LEVEL_MULTIPATH)
                        /* with multipath, the raid_disk from the superblock is meaningless */
                        i = devcnt;
                else
@@ -718,6 +742,8 @@ int Assemble(struct supertype *st, char *mddev,
                }
                devcnt++;
        }
+       free(content->update_private);
+       content->update_private = NULL;
 
        if (devcnt == 0) {
                fprintf(stderr, Name ": no devices found for %s\n",
@@ -750,8 +776,8 @@ int Assemble(struct supertype *st, char *mddev,
                /* note: we ignore error flags in multipath arrays
                 * as they don't make sense
                 */
-               if (content->array.level != -4)
-                       if (!(devices[j].i.disk.state & (1<<MD_DISK_SYNC))) {
+               if (content->array.level != LEVEL_MULTIPATH)
+                       if (!(devices[j].i.disk.state & (1<<MD_DISK_ACTIVE))) {
                                if (!(devices[j].i.disk.state
                                      & (1<<MD_DISK_FAULTY)))
                                        sparecnt++;
@@ -964,6 +990,10 @@ int Assemble(struct supertype *st, char *mddev,
        if (content->reshape_active) {
                int err = 0;
                int *fdlist = malloc(sizeof(int)* bestcnt);
+               if (verbose > 0)
+                       fprintf(stderr, Name ":%s has an active reshape - checking "
+                               "if critical section needs to be restored\n",
+                               chosen_name);
                for (i=0; i<bestcnt; i++) {
                        int j = best[i];
                        if (j >= 0) {
@@ -978,7 +1008,7 @@ int Assemble(struct supertype *st, char *mddev,
                                fdlist[i] = -1;
                }
                if (!err)
-                       err = Grow_restart(st, content, fdlist, bestcnt, backup_file);
+                       err = Grow_restart(st, content, fdlist, bestcnt, backup_file, verbose > 0);
                while (i>0) {
                        i--;
                        if (fdlist[i]>=0) close(fdlist[i]);
@@ -1101,10 +1131,12 @@ int Assemble(struct supertype *st, char *mddev,
                         * it read-only and let the grow code make it writable.
                         */
                        int rv;
+#ifndef MDASSEMBLE
                        if (content->reshape_active &&
                            content->delta_disks <= 0)
                                rv = Grow_continue(mdfd, st, content, backup_file);
                        else
+#endif
                                rv = ioctl(mdfd, RUN_ARRAY, NULL);
                        if (rv == 0) {
                                if (verbose >= 0) {
@@ -1254,7 +1286,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
                sysfs_free(sra);
 
        for (dev = content->devs; dev; dev = dev->next)
-               if (sysfs_add_disk(content, dev, 1) == 0)
+               if (sysfs_add_disk(content, dev) == 0)
                        working++;
                else if (errno == EEXIST)
                        preexist++;