]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Reorganise Assemble code somewhat.
authorNeil Brown <neilb@suse.de>
Tue, 23 May 2006 06:12:40 +0000 (06:12 +0000)
committerNeil Brown <neilb@suse.de>
Tue, 23 May 2006 06:12:40 +0000 (06:12 +0000)
We make sure all devices can are consistent before doing any --update
This saves us from updating some but not all of an array, and then
aborting.

It also means we can backtrack on out decisions, which we might want to
do later.

Signed-off-by: Neil Brown <neilb@suse.de>
Assemble.c
mdadm.h

index d35aa5a008199d3c34d043a4847b11952b8fa1b7..ecee624a9132b8d1985c29cef77e0e890d61e982 100644 (file)
@@ -193,15 +193,18 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
            fprintf(stderr, Name ": looking for devices for %s\n",
                    mddev);
 
-       while ( devlist) {
-               char *devname;
+       /* first walk the list of devices to find a consistent set
+        * that match the criterea, if that is possible.
+        * We flag the one we like with 'used'.
+        */
+       for (tmpdev = devlist;
+            tmpdev;
+            tmpdev = tmpdev->next) {
+               char *devname = tmpdev->devname;
                int dfd;
                struct stat stb;
                struct supertype *tst = st;
 
-               devname = devlist->devname;
-               devlist = devlist->next;
-
                if (ident->devices &&
                    !match_oneof(ident->devices, devname)) {
                        if ((inargv && verbose>=0) || verbose > 0)
@@ -296,12 +299,19 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        return 1;
                }
 
+               tmpdev->used = 1;
+       }
+
+       /* Ok, no bad inconsistancy, we can try updating etc */
+       for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used) {
+               char *devname = tmpdev->devname;
+               struct stat stb;
                /* looks like a good enough match to update the super block if needed */
                if (update) {
+                       int dfd;
                        /* prepare useful information in info structures */
                        struct stat stb2;
                        fstat(mdfd, &stb2);
-                       info.array.md_minor = minor(stb2.st_rdev);
 
                        if (strcmp(update, "uuid")==0 &&
                            !ident->uuid_set) {
@@ -315,8 +325,20 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                }
                                if (rfd >= 0) close(rfd);
                        }
+                       dfd = dev_open(devname, O_RDWR|O_EXCL);
+
+                       if (super) {
+                               free(super);
+                               super = NULL;
+                       }
+
+                       st->ss->load_super(st, dfd, &super, NULL);
+                       st->ss->getinfo_super(&info, super);
+
                        memcpy(info.uuid, ident->uuid, 16);
                        strcpy(info.name, ident->name);
+                       info.array.md_minor = minor(stb2.st_rdev);
+
                        st->ss->update_super(&info, super, update, devname, verbose,
                                             ident->uuid_set, homehost);
                        if (strcmp(update, "uuid")==0 &&
@@ -324,7 +346,6 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                ident->uuid_set = 1;
                                memcpy(ident->uuid, info.uuid, 16);
                        }
-                       dfd = dev_open(devname, O_RDWR|O_EXCL);
                        if (dfd < 0)
                                fprintf(stderr, Name ": Cannot open %s for superblock update\n",
                                        devname);
@@ -339,6 +360,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                bitmap_update_uuid(ident->bitmap_fd, info.uuid);
                }
 
+               stat(devname, &stb);
+
                if (verbose > 0)
                        fprintf(stderr, Name ": %s is identified as a member of %s, slot %d.\n",
                                devname, mddev, info.disk.raid_disk);
diff --git a/mdadm.h b/mdadm.h
index ecaacd4df6fdc28036825da11cdfff90528a4f6a..94e470856de4219b1d024689098b8c6d5a593403 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -182,6 +182,7 @@ typedef struct mddev_dev_s {
                                 */
        char writemostly;
        char re_add;
+       char used;              /* set when used */
        struct mddev_dev_s *next;
 } *mddev_dev_t;