]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Grow.c
ddf: set vcnum correctly when creating a new virtual device in conflist
[thirdparty/mdadm.git] / Grow.c
diff --git a/Grow.c b/Grow.c
index 37674b850e9cd71fcbd5507b60d8a18bd794be46..087b4efeb195b494e1f8d922323242b38e103676 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -210,10 +210,10 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
 
        if (vers < 9003) {
                major = BITMAP_MAJOR_HOSTENDIAN;
-#ifdef __BIG_ENDIAN
-               fprintf(stderr, Name ": Warning - bitmaps created on this kernel are not portable\n"
-                       "  between different architectured.  Consider upgrading the Linux kernel.\n");
-#endif
+               fprintf(stderr, Name ": Warning - bitmaps created on this kernel"
+                       " are not portable\n"
+                       "  between different architectures.  Consider upgrading"
+                       " the Linux kernel.\n");
        }
 
        if (ioctl(fd, GET_BITMAP_FILE, &bmf) != 0) {
@@ -327,6 +327,10 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
                }
                array.state |= (1<<MD_SB_BITMAP_PRESENT);
                if (ioctl(fd, SET_ARRAY_INFO, &array)!= 0) {
+                       if (errno == EBUSY)
+                               fprintf(stderr, Name
+                                       ": Cannot add bitmap while array is"
+                                       " resyncing or reshaping etc.\n");
                        fprintf(stderr, Name ": failed to set internal bitmap.\n");
                        return 1;
                }
@@ -373,8 +377,13 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
                        return 1;
                }
                if (ioctl(fd, SET_BITMAP_FILE, bitmap_fd) < 0) {
+                       int err = errno;
+                       if (errno == EBUSY)
+                               fprintf(stderr, Name
+                                       ": Cannot add bitmap while array is"
+                                       " resyncing or reshaping etc.\n");
                        fprintf(stderr, Name ": Cannot set bitmap file for %s: %s\n",
-                               devname, strerror(errno));
+                               devname, strerror(err));
                        return 1;
                }
        }
@@ -831,6 +840,13 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                 */
                st = super_by_fd(fd);
 
+               if (raid_disks > st->max_devs) {
+                       fprintf(stderr, Name ": Cannot increase raid-disks on "
+                               "this array beyond %d\n", st->max_devs);
+                       rv = 1;
+                       break;
+               }
+
                /*
                 * There are three possibilities.
                 * 1/ The array will shrink.
@@ -979,7 +995,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                        rv = 1;
                        break;
                }
-               nrdisks = array.nr_disks + sra->array.spare_disks;
+               nrdisks = array.raid_disks + sra->array.spare_disks;
                /* Now we need to open all these devices so we can read/write.
                 */
                fdlist = malloc((1+nrdisks) * sizeof(int));
@@ -1044,6 +1060,8 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                } else {
                        /* need to check backup file is large enough */
                        char buf[512];
+                       struct stat stb;
+                       unsigned int dev;
                        fdlist[d] = open(backup_file, O_RDWR|O_CREAT|O_EXCL,
                                     S_IRUSR | S_IWUSR);
                        offsets[d] = 8 * 512;
@@ -1053,8 +1071,24 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                                rv = 1;
                                break;
                        }
+                       /* Guard against backup file being on array device.
+                        * If array is partitioned or if LVM etc is in the
+                        * way this will not notice, but it is better than
+                        * nothing.
+                        */
+                       fstat(fdlist[d], &stb);
+                       dev = stb.st_dev;
+                       fstat(fd, &stb);
+                       if (stb.st_rdev == dev) {
+                               fprintf(stderr, Name ": backup file must NOT be"
+                                       " on the array being reshaped.\n");
+                               rv = 1;
+                               close(fdlist[d]);
+                               break;
+                       }
+
                        memset(buf, 0, 512);
-                       for (i=0; i < (signed)blocks + 1 ; i++) {
+                       for (i=0; i < (signed)blocks + 8 ; i++) {
                                if (write(fdlist[d], buf, 512) != 512) {
                                        fprintf(stderr, Name ": %s: cannot create backup file %s: %s\n",
                                                devname, backup_file, strerror(errno));
@@ -1293,7 +1327,8 @@ int grow_backup(struct mdinfo *sra,
                odata--;
        sysfs_set_num(sra, NULL, "suspend_hi", (offset + stripes * (chunk/512)) * odata);
        /* Check that array hasn't become degraded, else we might backup the wrong data */
-       sysfs_get_ll(sra, NULL, "degraded", &ll);
+       if (sysfs_get_ll(sra, NULL, "degraded", &ll) < 0)
+               return -1; /* FIXME this error is ignored */
        new_degraded = (int)ll;
        if (new_degraded != *degraded) {
                /* check each device to ensure it is still working */