]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Create.c
Fix spare migration and other problems with --monitor.
[thirdparty/mdadm.git] / Create.c
index ba6a8247444bf350e6d803e339e76ac9191b0293..2a4335a891cf882c7b42ff3367245518aa6887e5 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -34,7 +34,7 @@
 
 int Create(struct supertype *st, char *mddev, int mdfd,
           int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
-          char *name, char *homehost,
+          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)
@@ -87,11 +87,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                        Name ": a RAID level is needed to create an array.\n");
                return 1;
        }
-       if (raiddisks < 1) {
-               fprintf(stderr,
-                       Name ": a number of --raid-devices must be given to create an array\n");
-               return 1;
-       }
        if (raiddisks < 4 && level == 6) {
                fprintf(stderr,
                        Name ": at least 4 raid-devices needed for level 6\n");
@@ -115,6 +110,11 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                fprintf(stderr, Name ": You haven't given enough devices (real or missing) to create this array\n");
                return 1;
        }
+       if (bitmap_file && level <= 0) {
+               fprintf(stderr, Name ": bitmaps not meaningful with level %s\n",
+                       map_num(pers, level)?:"given");
+               return 1;
+       }
 
        /* now set some defaults */
        if (layout == UnSet)
@@ -180,7 +180,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        dnum = 0;
        for (dv=devlist; dv; dv=dv->next, dnum++) {
                char *dname = dv->devname;
-               unsigned long dsize;
                unsigned long long ldsize, freesize;
                int fd;
                if (strcasecmp(dname, "missing")==0) {
@@ -199,22 +198,11 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                        fail=1;
                        continue;
                }
-#ifdef BLKGETSIZE64
-               if (ioctl(fd, BLKGETSIZE64, &ldsize)==0)
-                       ;
-               else
-#endif
-               if (ioctl(fd, BLKGETSIZE, &dsize)) {
-                       fprintf(stderr, Name ": Cannot get size of %s: %s\n",
-                               dname, strerror(errno));
+               if (!get_dev_size(fd, dname, &ldsize)) {
                        fail = 1;
                        close(fd);
                        continue;
                }
-               else {
-                       ldsize = dsize;
-                       ldsize <<= 9;
-               }
                if (st == NULL) {
                        struct createinfo *ci = conf_get_create_info();
                        if (ci)
@@ -363,7 +351,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                 * which is array.size * raid_disks / ncopies;
                 * .. but convert to sectors.
                 */
-               int ncopies = (layout>>8) * (layout & 255);
+               int ncopies = ((layout>>8) & 255) * (layout & 255);
                bitmapsize = (unsigned long long)size * raiddisks / ncopies * 2;
 /*             printf("bms=%llu as=%d rd=%d nc=%d\n", bitmapsize, size, raiddisks, ncopies);*/
        } else
@@ -397,6 +385,13 @@ int Create(struct supertype *st, char *mddev, int mdfd,
 
        if (name == NULL || *name == 0) {
                /* base name on mddev */
+               /*  /dev/md0 -> 0
+                *  /dev/md_d0 -> d0
+                *  /dev/md/1 -> 1
+                *  /dev/md/d1 -> d1
+                *  /dev/md/home -> home
+                *  /dev/mdhome -> home
+                */
                name = strrchr(mddev, '/');
                if (name) {
                        name++;
@@ -404,7 +399,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                            strlen(name) > 4 &&
                            isdigit(name[4]) &&
                            (name-mddev) == 5 /* /dev/ */)
-                               name += 4;
+                               name += 3;
                        else if (strncmp(name, "md", 2)==0 &&
                                 strlen(name) > 2 &&
                                 isdigit(name[2]) &&
@@ -412,7 +407,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                name += 2;
                }
        }
-       if (!st->ss->init_super(st, &super, &array, size, name, homehost))
+       if (!st->ss->init_super(st, &super, &array, size, name, homehost, uuid))
                return 1;
 
        if (bitmap_file && vers < 9003) {
@@ -428,7 +423,8 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                        fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n");
                        return 1;
                }
-               if (!st->ss->add_internal_bitmap(st, super, bitmap_chunk, delay, write_behind,
+               if (!st->ss->add_internal_bitmap(st, super, &bitmap_chunk,
+                                                delay, write_behind,
                                                 bitmapsize, 1, major)) {
                        fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
                        return 1;
@@ -514,6 +510,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                fstat(fd, &stb);
                                disk.major = major(stb.st_rdev);
                                disk.minor = minor(stb.st_rdev);
+                               remove_partitions(fd);
                                close(fd);
                        }
                        switch(pass){