]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Create.c
imsm: fixup examine_brief to be more descriptive in the container only case
[thirdparty/mdadm.git] / Create.c
index 422b46df1e371ae8480423edd0f791ab309fad87..8a73799c4448c727308228dc51c34049093ebe65 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"
 #include       "md_p.h"
 #include       <ctype.h>
 
+static int default_layout(struct supertype *st, int level, int verbose)
+{
+       int layout = UnSet;
+
+       if (st && st->ss->default_layout)
+               layout = st->ss->default_layout(level);
+
+       if (layout == UnSet)
+               switch(level) {
+               default: /* no layout */
+                       layout = 0;
+                       break;
+               case 10:
+                       layout = 0x102; /* near=2, far=1 */
+                       if (verbose > 0)
+                               fprintf(stderr,
+                                       Name ": layout defaults to n1\n");
+                       break;
+               case 5:
+               case 6:
+                       layout = map_name(r5layout, "default");
+                       if (verbose > 0)
+                               fprintf(stderr,
+                                       Name ": layout defaults to %s\n", map_num(r5layout, layout));
+                       break;
+               case LEVEL_FAULTY:
+                       layout = map_name(faultylayout, "default");
+
+                       if (verbose > 0)
+                               fprintf(stderr,
+                                       Name ": layout defaults to %s\n", map_num(faultylayout, layout));
+                       break;
+               }
+
+       return layout;
+}
+
+
 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,
@@ -78,6 +111,7 @@ int Create(struct supertype *st, char *mddev,
        unsigned long long bitmapsize;
        struct mdinfo info, *infos;
        int did_default = 0;
+       int do_default_layout = 0;
        unsigned long safe_mode_delay = 0;
        char chosen_name[1024];
        struct map_ent *map = NULL;
@@ -148,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);
@@ -175,32 +213,12 @@ int Create(struct supertype *st, char *mddev,
        }
 
        /* now set some defaults */
-       if (layout == UnSet)
-               switch(level) {
-               default: /* no layout */
-                       layout = 0;
-                       break;
-               case 10:
-                       layout = 0x102; /* near=2, far=1 */
-                       if (verbose > 0)
-                               fprintf(stderr,
-                                       Name ": layout defaults to n1\n");
-                       break;
-               case 5:
-               case 6:
-                       layout = map_name(r5layout, "default");
-                       if (verbose > 0)
-                               fprintf(stderr,
-                                       Name ": layout defaults to %s\n", map_num(r5layout, layout));
-                       break;
-               case LEVEL_FAULTY:
-                       layout = map_name(faultylayout, "default");
 
-                       if (verbose > 0)
-                               fprintf(stderr,
-                                       Name ": layout defaults to %s\n", map_num(faultylayout, layout));
-                       break;
-               }
+
+       if (layout == UnSet) {
+               do_default_layout = 1;
+               layout = default_layout(st, level, verbose);
+       }
 
        if (level == 10)
                /* check layout fits in array*/
@@ -238,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))
@@ -280,6 +300,8 @@ int Create(struct supertype *st, char *mddev,
                        char *name = "default";
                        for(i=0; !st && superlist[i]; i++) {
                                st = superlist[i]->match_metadata_desc(name);
+                               if (do_default_layout)
+                                       layout = default_layout(st, level, verbose);
                                if (st && !st->ss->validate_geometry
                                                (st, level, layout, raiddisks,
                                                 chunk, size*2, dname, &freesize,
@@ -297,6 +319,8 @@ int Create(struct supertype *st, char *mddev,
                            st->minor_version != 90)
                                did_default = 1;
                } else {
+                       if (do_default_layout)
+                               layout = default_layout(st, level, verbose);
                        if (!st->ss->validate_geometry(st, level, layout,
                                                       raiddisks,
                                                       chunk, size*2, dname,
@@ -381,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? ")) {
@@ -773,6 +805,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) {
@@ -808,7 +841,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");
        }