]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Create.c
Detail: export MD_UUID from mapfile
[thirdparty/mdadm.git] / Create.c
index a7275d3d564b88367c861adba283868994067625..c96b31950bc95c5c119e2de95906dddd1e726c5c 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -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"
@@ -187,8 +182,12 @@ int Create(struct supertype *st, char *mddev,
                                else
                                        st = NULL;
                        }
-                       if (have_container)
+                       if (have_container) {
                                subdevs = raiddisks;
+                               first_missing = subdevs * 2;
+                               second_missing = subdevs * 2;
+                               insert_point = subdevs * 2;
+                       }
                }
                if (fd >= 0)
                        close(fd);
@@ -257,6 +256,8 @@ int Create(struct supertype *st, char *mddev,
                return 1;
        }
        
+       if (size && chunk)
+               size &= ~(unsigned long long)(chunk - 1);
        newsize = size * 2;
        if (st && ! st->ss->validate_geometry(st, level, layout, raiddisks,
                                              chunk, size*2, NULL, &newsize, verbose>=0))
@@ -404,6 +405,14 @@ int Create(struct supertype *st, char *mddev,
                warn = 1;
        }
 
+       if (st->ss->detail_platform && st->ss->detail_platform(0, 1) != 0) {
+               if (runstop != 1 || verbose >= 0)
+                       fprintf(stderr, Name ": %s unable to enumerate platform support\n"
+                               "    array may not be compatible with hardware/firmware\n",
+                               st->ss->name);
+               warn = 1;
+       }
+
        if (warn) {
                if (runstop!= 1) {
                        if (!ask("Continue creating array? ")) {
@@ -783,7 +792,39 @@ int Create(struct supertype *st, char *mddev,
                            dv == moved_disk && dnum != insert_point) break;
                }
                if (pass == 1) {
+                       struct mdinfo info_new;
+                       struct map_ent *me = NULL;
+
+                       /* check to see if the uuid has changed due to these
+                        * metadata changes, and if so update the member array
+                        * and container uuid.  Note ->write_init_super clears
+                        * the subarray cursor such that ->getinfo_super once
+                        * again returns container info.
+                        */
+                       map_lock(&map);
+                       st->ss->getinfo_super(st, &info_new);
+                       if (st->ss->external && level != LEVEL_CONTAINER &&
+                           !same_uuid(info_new.uuid, info.uuid, 0)) {
+                               map_update(&map, fd2devnum(mdfd),
+                                          info_new.text_version,
+                                          info_new.uuid, chosen_name);
+                               me = map_by_devnum(&map, st->container_dev);
+                       }
+
                        st->ss->write_init_super(st);
+
+                       /* update parent container uuid */
+                       if (me) {
+                               char *path = strdup(me->path);
+
+                               st->ss->getinfo_super(st, &info_new);
+                               map_update(&map, st->container_dev,
+                                          info_new.text_version,
+                                          info_new.uuid, path);
+                               free(path);
+                       }
+                       map_unlock(&map);
+
                        flush_metadata_updates(st);
                }
        }
@@ -796,6 +837,7 @@ int Create(struct supertype *st, char *mddev,
                sysfs_uevent(&info, "change");
                if (verbose >= 0)
                        fprintf(stderr, Name ": container %s prepared.\n", mddev);
+               wait_for(chosen_name, mdfd);
        } else if (runstop == 1 || subdevs >= raiddisks) {
                if (st->ss->external) {
                        switch(level) {
@@ -831,7 +873,7 @@ int Create(struct supertype *st, char *mddev,
                        ping_monitor(devnum2devname(st->container_dev));
                        close(container_fd);
                }
-               wait_for(chosen_name);
+               wait_for(chosen_name, mdfd);
        } else {
                fprintf(stderr, Name ": not starting array - not enough devices.\n");
        }