]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Delay creation of array devices for assemble/build/create
authorNeilBrown <neilb@suse.de>
Mon, 3 Nov 2008 23:35:37 +0000 (10:35 +1100)
committerNeilBrown <neilb@suse.de>
Mon, 3 Nov 2008 23:35:37 +0000 (10:35 +1100)
We will shortly be feeding more information into the process of
creating array devices, so delay the creation.  Still open them
early if the device already exists.

This involves making sure the autof flag is in the right place
so that it can be found at creation time.

Also, Assemble, Build, and Create now always close 'mdfd'.

Signed-off-by: NeilBrown <neilb@suse.de>
Assemble.c
Build.c
Create.c
mdadm.c
mdadm.h
mdassemble.c

index fa534fd263c6de09a5f3900795beba064ad6017e..c371fda2ebccd33a2da6b49f52e3263a28b01dd8 100644 (file)
@@ -50,7 +50,7 @@ static int name_matches(char *found, char *required, char *homehost)
        return 0;
 }
 
-int Assemble(struct supertype *st, char *mddev, int mdfd,
+int Assemble(struct supertype *st, char *mddev,
             mddev_ident_t ident,
             mddev_dev_t devlist, char *backup_file,
             int readonly, int runstop,
@@ -111,8 +111,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
         *    START_ARRAY
         *
         */
+       int mdfd = -1;
        int clean = 0;
-       int must_close = 0;
+       int auto_assem = (mddev == NULL);
        int old_linux = 0;
        int vers = 0; /* Keep gcc quite - it really is initialised */
        struct {
@@ -133,7 +134,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
        int change = 0;
        int inargv = 0;
        int bitmap_done;
-       int start_partial_ok = (runstop >= 0) && (force || devlist==NULL || mdfd < 0);
+       int start_partial_ok = (runstop >= 0) && 
+               (force || devlist==NULL || auto_assem);
        unsigned int num_devs;
        mddev_dev_t tmpdev;
        struct mdinfo info;
@@ -146,21 +148,31 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
        if (get_linux_version() < 2004000)
                old_linux = 1;
 
+       if (mddev != NULL) {
+               /* We need to create the device */
+               mdfd = create_mddev(mddev, 1);
+               if (mdfd < 0)
+                       return 1;
+       }
+
        if (mdfd >= 0) {
                vers = md_get_version(mdfd);
                if (vers <= 0) {
                        fprintf(stderr, Name ": %s appears not to be an md device.\n", mddev);
+                       close(mdfd);
                        return 1;
                }
                if (vers < 9000) {
                        fprintf(stderr, Name ": Assemble requires driver version 0.90.0 or later.\n"
                                "    Upgrade your kernel or try --build\n");
+                       close(mdfd);
                        return 1;
                }
 
                if (ioctl(mdfd, GET_ARRAY_INFO, &info.array)>=0) {
                        fprintf(stderr, Name ": device %s already active - cannot assemble it\n",
                                mddev);
+                       close(mdfd);
                        return 1;
                }
                ioctl(mdfd, STOP_ARRAY, NULL); /* just incase it was started but has no content */
@@ -179,6 +191,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
            ident->devices == NULL) {
                fprintf(stderr, Name ": No identity information available for %s - cannot assemble.\n",
                        mddev ? mddev : "further assembly");
+               if (mdfd >= 0)
+                       close(mdfd);
                return 1;
        }
 
@@ -229,7 +243,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
 #endif
        if (devlist == NULL)
                devlist = conf_get_devs();
-       else if (mdfd >= 0)
+       else if (mddev)
                inargv = 1;
 
  try_again:
@@ -379,6 +393,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                devname);
                        if (st)
                                st->ss->free_super(st);
+                       if (mdfd >= 0)
+                               close(mdfd);
                        return 1;
                }
 
@@ -424,6 +440,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                devname);
                        tst->ss->free_super(tst);
                        st->ss->free_super(st);
+                       if (mdfd >= 0)
+                               close(mdfd);
                        return 1;
                }
 
@@ -479,12 +497,11 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                fprintf(stderr, Name ":   %s needed for %s...\n",
                                        mddev, tmpdev->devname);
                        close(mdfd);
-                       mdfd = -1;
+                       mdfd = -3;
                        st->ss->free_super(st);
                        free(devices);
                        goto try_again;
                }
-               must_close = 1;
        }
 
        /* Ok, no bad inconsistancy, we can try updating etc */
@@ -631,7 +648,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                        inargv ? "the list" :
                                           "the\n      DEVICE list in mdadm.conf"
                                        );
-                               if (must_close) close(mdfd);
+                               close(mdfd);
                                return 1;
                        }
                        if (best[i] == -1
@@ -647,7 +664,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        mddev);
                if (st)
                        st->ss->free_super(st);
-               if (must_close) close(mdfd);
+               close(mdfd);
                return 1;
        }
 
@@ -791,21 +808,21 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                if ((fd=dev_open(devices[j].devname, O_RDONLY|O_EXCL))< 0) {
                        fprintf(stderr, Name ": Cannot open %s: %s\n",
                                devices[j].devname, strerror(errno));
-                       if (must_close) close(mdfd);
+                       close(mdfd);
                        return 1;
                }
                if (st->ss->load_super(st,fd, NULL)) {
                        close(fd);
                        fprintf(stderr, Name ": RAID superblock has disappeared from %s\n",
                                devices[j].devname);
-                       if (must_close) close(mdfd);
+                       close(mdfd);
                        return 1;
                }
                close(fd);
        }
        if (st->sb == NULL) {
                fprintf(stderr, Name ": No suitable drives found for %s\n", mddev);
-               if (must_close) close(mdfd);
+               close(mdfd);
                return 1;
        }
        st->ss->getinfo_super(st, &info);
@@ -866,14 +883,14 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                if (fd < 0) {
                        fprintf(stderr, Name ": Could not open %s for write - cannot Assemble array.\n",
                                devices[chosen_drive].devname);
-                       if (must_close) close(mdfd);
+                       close(mdfd);
                        return 1;
                }
                if (st->ss->store_super(st, fd)) {
                        close(fd);
                        fprintf(stderr, Name ": Could not re-write superblock on %s\n",
                                devices[chosen_drive].devname);
-                       if (must_close) close(mdfd);
+                       close(mdfd);
                        return 1;
                }
                close(fd);
@@ -908,7 +925,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                }
                if (err) {
                        fprintf(stderr, Name ": Failed to restore critical section for reshape, sorry.\n");
-                       if (must_close) close(mdfd);
+                       close(mdfd);
                        return err;
                }
        }
@@ -926,13 +943,13 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                if (rv) {
                        fprintf(stderr, Name ": failed to set array info for %s: %s\n",
                                mddev, strerror(errno));
-                       if (must_close) close(mdfd);
+                       close(mdfd);
                        return 1;
                }
                if (ident->bitmap_fd >= 0) {
                        if (ioctl(mdfd, SET_BITMAP_FILE, ident->bitmap_fd) != 0) {
                                fprintf(stderr, Name ": SET_BITMAP_FILE failed.\n");
-                               if (must_close) close(mdfd);
+                               close(mdfd);
                                return 1;
                        }
                } else if (ident->bitmap_file) {
@@ -941,13 +958,13 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        if (bmfd < 0) {
                                fprintf(stderr, Name ": Could not open bitmap file %s\n",
                                        ident->bitmap_file);
-                               if (must_close) close(mdfd);
+                               close(mdfd);
                                return 1;
                        }
                        if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
                                fprintf(stderr, Name ": Failed to set bitmapfile for %s\n", mddev);
                                close(bmfd);
-                               if (must_close) close(mdfd);
+                               close(mdfd);
                                return 1;
                        }
                        close(bmfd);
@@ -998,8 +1015,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                                info.array.raid_disks);
                                fprintf(stderr, "\n");
                        }
-                       if (must_close)
-                               close(mdfd);
+                       close(mdfd);
                        return 0;
                }
 
@@ -1019,9 +1035,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                                fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
                                        fprintf(stderr, ".\n");
                                }
-                               if (must_close) {
+                               close(mdfd);
+                               if (auto_assem) {
                                        int usecs = 1;
-                                       close(mdfd);
                                        /* There is a nasty race with 'mdadm --monitor'.
                                         * If it opens this device before we close it,
                                         * it gets an incomplete open on which IO
@@ -1063,10 +1079,9 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                        "start the array while not clean "
                                        "- consider --force.\n");
 
-                       if (must_close) {
+                       if (auto_assem)
                                ioctl(mdfd, STOP_ARRAY, NULL);
-                               close(mdfd);
-                       }
+                       close(mdfd);
                        return 1;
                }
                if (runstop == -1) {
@@ -1075,7 +1090,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        if (okcnt != info.array.raid_disks)
                                fprintf(stderr, " (out of %d)", info.array.raid_disks);
                        fprintf(stderr, ", but not started.\n");
-                       if (must_close) close(mdfd);
+                       close(mdfd);
                        return 0;
                }
                if (verbose >= -1) {
@@ -1100,10 +1115,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                fprintf(stderr, " (use --run to insist).\n");
                        }
                }
-               if (must_close) {
+               if (auto_assem)
                        ioctl(mdfd, STOP_ARRAY, NULL);
-                       close(mdfd);
-               }
                return 1;
        } else {
                /* The "chosen_drive" is a good choice, and if necessary, the superblock has
@@ -1119,6 +1132,6 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                }
 
        }
-       if (must_close) close(mdfd);
+       close(mdfd);
        return 0;
 }
diff --git a/Build.c b/Build.c
index 1e213ce438e7729bbc5272223de619b7369a626c..1e751d1312fcf631e69f1ae0dae7bb5f5a2fcfe9 100644 (file)
--- a/Build.c
+++ b/Build.c
 #define START_MD               _IO (MD_MAJOR, 2)
 #define STOP_MD                _IO (MD_MAJOR, 3)
 
-int Build(char *mddev, int mdfd, int chunk, int level, int layout,
-         int raiddisks,
-         mddev_dev_t devlist, int assume_clean,
-         char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int verbose)
+int Build(char *mddev, int chunk, int level, int layout,
+         int raiddisks, mddev_dev_t devlist, int assume_clean,
+         char *bitmap_file, int bitmap_chunk, int write_behind,
+         int delay, int verbose, int autof)
 {
        /* Build a linear or raid0 arrays without superblocks
         * We cannot really do any checks, we just do it.
@@ -59,6 +59,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
        int bitmap_fd;
        unsigned long long size = ~0ULL;
        unsigned long long bitmapsize;
+       int mdfd;
 
        /* scan all devices, make sure they really are block devices */
        for (dv = devlist; dv; dv=dv->next) {
@@ -112,6 +113,10 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                        break;
                }
 
+       /* We need to create the device */
+       mdfd = create_mddev(mddev, autof);
+       if (mdfd < 0)
+               return 1;
 
        vers = md_get_version(mdfd);
 
@@ -140,17 +145,17 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                if (ioctl(mdfd, SET_ARRAY_INFO, &array)) {
                        fprintf(stderr, Name ": SET_ARRAY_INFO failed for %s: %s\n",
                                mddev, strerror(errno));
-                       return 1;
+                       goto abort;
                }
        } else if (bitmap_file) {
                fprintf(stderr, Name ": bitmaps not supported with this kernel\n");
-               return 1;
+               goto abort;
        }
 
        if (bitmap_file && level <= 0) {
                fprintf(stderr, Name ": bitmaps not meaningful with level %s\n",
                        map_num(pers, level)?:"given");
-               return 1;
+               goto abort;
        }
        /* now add the devices */
        for ((i=0), (dv = devlist) ; dv ; i++, dv=dv->next) {
@@ -211,7 +216,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                                if (bitmap_chunk == UnSet) {
                                        fprintf(stderr, Name ": %s cannot be openned.",
                                                bitmap_file);
-                                       return 1;
+                                       goto abort;
                                }
 #endif
                                if (vers < 9003) {
@@ -224,20 +229,20 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
                                bitmapsize = size>>9; /* FIXME wrong for RAID10 */
                                if (CreateBitmap(bitmap_file, 1, NULL, bitmap_chunk,
                                                 delay, write_behind, bitmapsize, major)) {
-                                       return 1;
+                                       goto abort;
                                }
                                bitmap_fd = open(bitmap_file, O_RDWR);
                                if (bitmap_fd < 0) {
                                        fprintf(stderr, Name ": %s cannot be openned.",
                                                bitmap_file);
-                                       return 1;
+                                       goto abort;
                                }
                        }
                        if (bitmap_fd >= 0) {
                                if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
                                        fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n",
                                                mddev, strerror(errno));
-                                       return 1;
+                                       goto abort;
                                }
                        }
                }
@@ -265,6 +270,7 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
        if (verbose >= 0)
                fprintf(stderr, Name ": array %s built and started.\n",
                        mddev);
+       close(mdfd);
        return 0;
 
  abort:
@@ -272,5 +278,6 @@ int Build(char *mddev, int mdfd, int chunk, int level, int layout,
            ioctl(mdfd, STOP_ARRAY, 0);
        else
            ioctl(mdfd, STOP_MD, 0);
+       close(mdfd);
        return 1;
 }
index 8bcdc3bfc9de7e8067b9320102c24aa971e26bf1..87cfebf9d56818b32ce33cc34e24e47944272e58 100644 (file)
--- a/Create.c
+++ b/Create.c
 #include       "md_p.h"
 #include       <ctype.h>
 
-int Create(struct supertype *st, char *mddev, int mdfd,
+int Create(struct supertype *st, char *mddev,
           int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
           char *name, char *homehost, int *uuid,
           int subdevs, mddev_dev_t devlist,
           int runstop, int verbose, int force, int assume_clean,
-          char *bitmap_file, int bitmap_chunk, int write_behind, int delay)
+          char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int autof)
 {
        /*
         * Create a new raid array.
@@ -55,6 +55,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
         * if runstop==run, or raiddisks disks were used,
         * RUN_ARRAY
         */
+       int mdfd;
        unsigned long long minsize=0, maxsize=0;
        char *mindisc = NULL;
        char *maxdisc = NULL;
@@ -83,20 +84,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
 
        memset(&info, 0, sizeof(info));
 
-       vers = md_get_version(mdfd);
-       if (vers < 9000) {
-               fprintf(stderr, Name ": Create requires md driver version 0.90.0 or later\n");
-               return 1;
-       } else {
-               mdu_array_info_t inf;
-               memset(&inf, 0, sizeof(inf));
-               ioctl(mdfd, GET_ARRAY_INFO, &inf);
-               if (inf.working_disks != 0) {
-                       fprintf(stderr, Name ": another array by this name"
-                               " is already running.\n");
-                       return 1;
-               }
-       }
        if (level == UnSet) {
                /* "ddf" and "imsm" metadata only supports one level - should possibly
                 * push this into metadata handler??
@@ -433,6 +420,25 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                return 1;
        }
 
+       /* We need to create the device */
+       mdfd = create_mddev(mddev, autof);
+       if (mdfd < 0)
+               return 1;
+
+       vers = md_get_version(mdfd);
+       if (vers < 9000) {
+               fprintf(stderr, Name ": Create requires md driver version 0.90.0 or later\n");
+               goto abort;
+       } else {
+               mdu_array_info_t inf;
+               memset(&inf, 0, sizeof(inf));
+               ioctl(mdfd, GET_ARRAY_INFO, &inf);
+               if (inf.working_disks != 0) {
+                       fprintf(stderr, Name ": another array by this name"
+                               " is already running.\n");
+                       goto abort;
+               }
+       }
        /* Ok, lets try some ioctls */
 
        info.array.level = level;
@@ -524,7 +530,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                }
        }
        if (!st->ss->init_super(st, &info.array, size, name, homehost, uuid))
-               return 1;
+               goto abort;
 
        total_slots = info.array.nr_disks;
        sysfs_init(&info, mdfd, 0);
@@ -563,13 +569,13 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        if (bitmap_file && strcmp(bitmap_file, "internal")==0) {
                if ((vers%100) < 2) {
                        fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n");
-                       return 1;
+                       goto abort;
                }
                if (!st->ss->add_internal_bitmap(st, &bitmap_chunk,
                                                 delay, write_behind,
                                                 bitmapsize, 1, major_num)) {
                        fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
-                       return 1;
+                       goto abort;
                }
                bitmap_file = NULL;
        }
@@ -596,7 +602,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                if (container_fd < 0) {
                        fprintf(stderr, Name ": Cannot get exclusive "
                                "open on container - weird.\n");
-                       return 1;
+                       goto abort;
                }
                if (mdmon_running(st->container_dev)) {
                        if (verbose)
@@ -611,7 +617,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        if (rv) {
                fprintf(stderr, Name ": failed to set array info for %s: %s\n",
                        mddev, strerror(errno));
-               return 1;
+               goto abort;
        }
 
        if (bitmap_file) {
@@ -622,18 +628,18 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                 delay, write_behind,
                                 bitmapsize,
                                 major_num)) {
-                       return 1;
+                       goto abort;
                }
                bitmap_fd = open(bitmap_file, O_RDWR);
                if (bitmap_fd < 0) {
                        fprintf(stderr, Name ": weird: %s cannot be openned\n",
                                bitmap_file);
-                       return 1;
+                       goto abort;
                }
                if (ioctl(mdfd, SET_BITMAP_FILE, bitmap_fd) < 0) {
                        fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n",
                                mddev, strerror(errno));
-                       return 1;
+                       goto abort;
                }
        }
 
@@ -681,7 +687,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                        fprintf(stderr, Name ": failed to open %s "
                                                "after earlier success - aborting\n",
                                                dv->devname);
-                                       return 1;
+                                       goto abort;
                                }
                                fstat(fd, &stb);
                                inf->disk.major = major(stb.st_rdev);
@@ -709,7 +715,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                                "failed: %s\n",
                                                dv->devname, strerror(errno));
                                        st->ss->free_super(st);
-                                       return 1;
+                                       goto abort;
                                }
                                break;
                        }
@@ -749,7 +755,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
                                        strerror(errno));
                                Manage_runstop(mddev, mdfd, -1, 0);
-                               return 1;
+                               goto abort;
                        }
                }
                if (verbose >= 0)
@@ -764,5 +770,11 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        } else {
                fprintf(stderr, Name ": not starting array - not enough devices.\n");
        }
+       close(mdfd);
        return 0;
+
+ abort:
+       if (mdfd >= 0)
+               close(mdfd);
+       return 1;
 }
diff --git a/mdadm.c b/mdadm.c
index c25f0078dad9568c4248817d06a2af8585ba7f85..f3086a92a8483484c7c02100c8cf537e7d9ecf7b 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -942,17 +942,36 @@ int main(int argc, char *argv[])
                        fprintf(stderr, Name ": --super-minor=dev is incompatible with --auto\n");
                        exit(2);
                }
-               if (mode == MANAGE || mode == GROW)
+               if (mode == MANAGE || mode == GROW) {
                        mdfd = open_mddev(devlist->devname, 1);
-               else
-                       mdfd = create_mddev(devlist->devname, autof);
-               if (mdfd < 0)
+                       if (mdfd < 0)
+                               exit(1);
+               } else
+                       /* non-existent device is OK */
+                       mdfd = open_mddev(devlist->devname, 0);
+               if (mdfd == -2) {
+                       fprintf(stderr, Name ": device %s exists but is not an "
+                               "md array.\n", devlist->devname);
                        exit(1);
+               }
                if ((int)ident.super_minor == -2) {
                        struct stat stb;
+                       if (mdfd < 0) {
+                               fprintf(stderr, Name ": --super-minor=dev given, and "
+                                       "listed device %s doesn't exist.\n",
+                                       devlist->devname);
+                               exit(1);
+                       }
                        fstat(mdfd, &stb);
                        ident.super_minor = minor(stb.st_rdev);
                }
+               if (mdfd >= 0 && mode != MANAGE && mode != GROW) {
+                       /* We don't really want this open yet, we just might
+                        * have wanted to check some things
+                        */
+                       close(mdfd);
+                       mdfd = -1;
+               }
        }
 
        if (raiddisks) {
@@ -985,6 +1004,8 @@ int main(int argc, char *argv[])
                }
        }
 
+       ident.autof = autof;
+
        rv = 0;
        switch(mode) {
        case MANAGE:
@@ -1008,15 +1029,17 @@ int main(int argc, char *argv[])
                                fprintf(stderr, Name ": %s not identified in config file.\n",
                                        devlist->devname);
                                rv |= 1;
-                               close(mdfd);
+                               if (mdfd >= 0)
+                                       close(mdfd);
                        } else {
-                               rv |= Assemble(ss, devlist->devname, mdfd, array_ident,
-                                                      NULL, backup_file,
-                                                      readonly, runstop, update, homehost, verbose-quiet, force);
-                               close(mdfd);
+                               if (array_ident->autof == 0)
+                                       array_ident->autof = autof;
+                               rv |= Assemble(ss, devlist->devname, array_ident,
+                                              NULL, backup_file,
+                                              readonly, runstop, update, homehost, verbose-quiet, force);
                        }
                } else if (!scan)
-                       rv = Assemble(ss, devlist->devname, mdfd, &ident,
+                       rv = Assemble(ss, devlist->devname, &ident,
                                      devlist->next, backup_file,
                                      readonly, runstop, update, homehost, verbose-quiet, force);
                else if (devs_found>0) {
@@ -1036,16 +1059,11 @@ int main(int argc, char *argv[])
                                        rv |= 1;
                                        continue;
                                }
-                               mdfd = create_mddev(dv->devname,
-                                                 array_ident->autof ?array_ident->autof : autof);
-                               if (mdfd < 0) {
-                                       rv |= 1;
-                                       continue;
-                               }
-                               rv |= Assemble(ss, dv->devname, mdfd, array_ident,
+                               if (array_ident->autof == 0)
+                                       array_ident->autof = autof;
+                               rv |= Assemble(ss, dv->devname, array_ident,
                                               NULL, backup_file,
                                               readonly, runstop, update, homehost, verbose-quiet, force);
-                               close(mdfd);
                        }
                } else {
                        mddev_ident_t array_list =  conf_get_ident(NULL);
@@ -1064,28 +1082,28 @@ int main(int argc, char *argv[])
                                exit(1);
                        }
                        for (; array_list; array_list = array_list->next) {
-                               mdu_array_info_t array;
-                               mdfd = create_mddev(array_list->devname,
-                                                 array_list->autof ? array_list->autof : autof);
-                               if (mdfd < 0) {
-                                       rv |= 1;
-                                       continue;
-                               }
-                               if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0)
-                                       /* already assembled, skip */
-                                       cnt++;
-                               else {
-                                       rv |= Assemble(ss, array_list->devname, mdfd,
-                                                      array_list,
-                                                      NULL, NULL,
-                                                      readonly, runstop, NULL, homehost, verbose-quiet, force);
-                                       if (rv == 0) cnt++;
+                               mdfd = open_mddev(array_list->devname, 0);
+                               if (mdfd >= 0) {
+                                       mdu_array_info_t array;
+                                       /* skip if already assembled */
+                                       if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0) {
+                                               cnt++;
+                                               close(mdfd);
+                                               continue;
+                                       }
                                }
-                               close(mdfd);
+                               if (array_list->autof == 0)
+                                       array_list->autof = autof;
+                               
+                               rv |= Assemble(ss, array_list->devname,
+                                              array_list,
+                                              NULL, NULL,
+                                              readonly, runstop, NULL, homehost, verbose-quiet, force);
+                               if (rv == 0) cnt++;
                        }
                        if (homehost) {
                                /* Maybe we can auto-assemble something.
-                                * Repeatedly call Assemble in auto-assmble mode
+                                * Repeatedly call Assemble in auto-assemble mode
                                 * until it fails
                                 */
                                int rv2;
@@ -1095,7 +1113,7 @@ int main(int argc, char *argv[])
                                        mddev_dev_t devlist = conf_get_devs();
                                        acnt = 0;
                                        do {
-                                               rv2 = Assemble(ss, NULL, -1,
+                                               rv2 = Assemble(ss, NULL,
                                                               &ident,
                                                               devlist, NULL,
                                                               readonly, runstop, NULL, homehost, verbose-quiet, force);
@@ -1116,7 +1134,7 @@ int main(int argc, char *argv[])
                                        do {
                                                acnt = 0;
                                                do {
-                                                       rv2 = Assemble(ss, NULL, -1,
+                                                       rv2 = Assemble(ss, NULL,
                                                                       &ident,
                                                                       NULL, NULL,
                                                                       readonly, runstop, "homehost", homehost, verbose-quiet, force);
@@ -1159,9 +1177,10 @@ int main(int argc, char *argv[])
                                break;
                        }
                }
-               rv = Build(devlist->devname, mdfd, chunk, level, layout,
+               rv = Build(devlist->devname, chunk, level, layout,
                           raiddisks, devlist->next, assume_clean,
-                          bitmap_file, bitmap_chunk, write_behind, delay, verbose-quiet);
+                          bitmap_file, bitmap_chunk, write_behind,
+                          delay, verbose-quiet, autof);
                break;
        case CREATE:
                if (delay == 0) delay = DEFAULT_BITMAP_DELAY;
@@ -1176,11 +1195,11 @@ int main(int argc, char *argv[])
                        break;
                }
 
-               rv = Create(ss, devlist->devname, mdfd, chunk, level, layout, size<0 ? 0 : size,
+               rv = Create(ss, devlist->devname, chunk, level, layout, size<0 ? 0 : size,
                            raiddisks, sparedisks, ident.name, homehost,
                            ident.uuid_set ? ident.uuid : NULL,
                            devs_found-1, devlist->next, runstop, verbose-quiet, force, assume_clean,
-                           bitmap_file, bitmap_chunk, write_behind, delay);
+                           bitmap_file, bitmap_chunk, write_behind, delay, autof);
                break;
        case MISC:
                if (devmode == 'E') {
diff --git a/mdadm.h b/mdadm.h
index 7b7e233b8cbb8d0cf26930b807c6828572e33529..f6f2c1d16a65c32be6afde7890bde6f1c76e938b 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -692,25 +692,25 @@ extern int Grow_restart(struct supertype *st, struct mdinfo *info,
                        int *fdlist, int cnt, char *backup_file);
 
 
-extern int Assemble(struct supertype *st, char *mddev, int mdfd,
+extern int Assemble(struct supertype *st, char *mddev,
                    mddev_ident_t ident,
                    mddev_dev_t devlist, char *backup_file,
                    int readonly, int runstop,
                    char *update, char *homehost,
                    int verbose, int force);
 
-extern int Build(char *mddev, int mdfd, int chunk, int level, int layout,
-                int raiddisks,
-                mddev_dev_t devlist, int assume_clean,
-                char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int verbose);
+extern int Build(char *mddev, int chunk, int level, int layout,
+                int raiddisks, mddev_dev_t devlist, int assume_clean,
+                char *bitmap_file, int bitmap_chunk, int write_behind,
+                int delay, int verbose, int autof);
 
 
-extern int Create(struct supertype *st, char *mddev, int mdfd,
+extern int Create(struct supertype *st, char *mddev,
                  int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
                  char *name, char *homehost, int *uuid,
                  int subdevs, mddev_dev_t devlist,
                  int runstop, int verbose, int force, int assume_clean,
-                 char *bitmap_file, int bitmap_chunk, int write_behind, int delay);
+                 char *bitmap_file, int bitmap_chunk, int write_behind, int delay, int autof);
 
 extern int Detail(char *dev, int brief, int export, int test, char *homehost);
 extern int Query(char *dev);
index 66d82131e1c65d3020333fa3a0d67b30e57bf680..1e3f104121246d5ef62f2abd7fe583b74453d947 100644 (file)
@@ -55,7 +55,7 @@ mapping_t pers[] = {
 
 #ifndef MDASSEMBLE_AUTO
 /* from mdopen.c */
-int create_mddev(char *dev, int autof/*unused */)
+int open_mddev(char *dev, int report_errors/*unused*/)
 {
        int mdfd = open(dev, O_RDWR);
        if (mdfd < 0)
@@ -69,6 +69,10 @@ int create_mddev(char *dev, int autof/*unused */)
        }
        return mdfd;
 }
+int create_mddev(char *dev, int autof/*unused*/)
+{
+       return open_mddev(dev, 0);
+}
 #endif
 
 int rv;
@@ -86,19 +90,16 @@ int main(int argc, char *argv[]) {
        } else
                for (; array_list; array_list = array_list->next) {
                        mdu_array_info_t array;
-                       mdfd = create_mddev(array_list->devname, array_list->autof);
-                       if (mdfd < 0) {
-                               rv |= 1;
-                               continue;
-                       }
-                       if (ioctl(mdfd, GET_ARRAY_INFO, &array) < 0) {
-                               rv |= Assemble(array_list->st, array_list->devname, mdfd,
-                                          array_list, NULL, NULL,
-                                          readonly, runstop, NULL, NULL, verbose, force);
-                       } else {
+                       mdfd = open_mddev(array_list->devname, 0);
+                       if (mdfd >= 0 && ioctl(mdfd, GET_ARRAY_INFO, &array) == 0) {
                                rv |= Manage_ro(array_list->devname, mdfd, -1); /* make it readwrite */
+                               continue;
                        }
-                       close(mdfd);
+                       if (mdfd >= 0)
+                               close(mdfd);
+                       rv |= Assemble(array_list->st, array_list->devname,
+                                      array_list, NULL, NULL,
+                                      readonly, runstop, NULL, NULL, verbose, force);
                }
        return rv;
 }