]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Create.c
allow add_to_super to return errors
[thirdparty/mdadm.git] / Create.c
index ab4406e1c0d803b8066ad316aae5876f1b7dea49..424be12c5ce958270c44ebb14aa8cc892b12d616 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -79,6 +79,8 @@ int Create(struct supertype *st, char *mddev,
        struct mdinfo info, *infos;
        int did_default = 0;
        unsigned long safe_mode_delay = 0;
+       char chosen_name[1024];
+       struct map_ent *map = NULL;
 
        int major_num = BITMAP_MAJOR_HI;
 
@@ -311,7 +313,7 @@ int Create(struct supertype *st, char *mddev,
                }
 
                if (size && freesize < size) {
-                       fprintf(stderr, Name ": %s is smaller that given size."
+                       fprintf(stderr, Name ": %s is smaller than given size."
                                " %lluK < %lluK + metadata\n",
                                dname, freesize, size);
                        fail = 1;
@@ -387,7 +389,8 @@ int Create(struct supertype *st, char *mddev,
         * as missing, so that a reconstruct happens (faster than re-parity)
         * FIX: Can we do this for raid6 as well?
         */
-       if (assume_clean==0 && force == 0 && first_missing >= raiddisks) {
+       if (st->ss->external == 0 &&
+           assume_clean==0 && force == 0 && first_missing >= raiddisks) {
                switch ( level ) {
                case 4:
                case 5:
@@ -421,9 +424,11 @@ int Create(struct supertype *st, char *mddev,
        }
 
        /* We need to create the device */
-       mdfd = create_mddev(mddev, name, autof, LOCAL, NULL);
+       map_lock(&map);
+       mdfd = create_mddev(mddev, name, autof, LOCAL, chosen_name);
        if (mdfd < 0)
                return 1;
+       mddev = chosen_name;
 
        vers = md_get_version(mdfd);
        if (vers < 9000) {
@@ -439,6 +444,7 @@ int Create(struct supertype *st, char *mddev,
                        goto abort;
                }
        }
+
        /* Ok, lets try some ioctls */
 
        info.array.level = level;
@@ -559,6 +565,10 @@ int Create(struct supertype *st, char *mddev,
                                " %s metadata\n", info.text_version);
        }
 
+       map_update(&map, fd2devnum(mdfd), info.text_version,
+                  info.uuid, chosen_name);
+       map_unlock(&map);
+
        if (bitmap_file && vers < 9003) {
                major_num = BITMAP_MAJOR_HOSTENDIAN;
 #ifdef __BIG_ENDIAN
@@ -695,8 +705,12 @@ int Create(struct supertype *st, char *mddev,
                                inf->disk.minor = minor(stb.st_rdev);
 
                                remove_partitions(fd);
-                               st->ss->add_to_super(st, &inf->disk,
-                                                    fd, dv->devname);
+                               if (st->ss->add_to_super(st, &inf->disk,
+                                                        fd, dv->devname)) {
+                                       fprintf(stderr, Name ": failed to add %s\n",
+                                               dv->devname);
+                                       goto abort;
+                               }
                                st->ss->getinfo_super(st, inf);
                                safe_mode_delay = inf->safe_mode_delay;
 
@@ -730,11 +744,12 @@ int Create(struct supertype *st, char *mddev,
        free(infos);
        st->ss->free_super(st);
 
-       /* param is not actually used */
-       if (level == LEVEL_CONTAINER)
-               /* No need to start */
+       if (level == LEVEL_CONTAINER) {
+               /* No need to start.  But we should signal udev to
+                * create links */
+               sysfs_uevent(&info, "change");
                ;
-       else if (runstop == 1 || subdevs >= raiddisks) {
+       else if (runstop == 1 || subdevs >= raiddisks) {
                if (st->ss->external) {
                        switch(level) {
                        case LEVEL_LINEAR:
@@ -751,6 +766,7 @@ int Create(struct supertype *st, char *mddev,
                        }
                        sysfs_set_safemode(&info, safe_mode_delay);
                } else {
+                       /* param is not actually used */
                        mdu_param_t param;
                        if (ioctl(mdfd, RUN_ARRAY, &param)) {
                                fprintf(stderr, Name ": RUN_ARRAY failed: %s\n",
@@ -768,6 +784,7 @@ int Create(struct supertype *st, char *mddev,
                        ping_monitor(devnum2devname(st->container_dev));
                        close(container_fd);
                }
+               wait_for(chosen_name);
        } else {
                fprintf(stderr, Name ": not starting array - not enough devices.\n");
        }