]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Manage.c
Add new mode: --incremental
[thirdparty/mdadm.git] / Manage.c
index aea21e65945118505b30d4c82fc68275d78e1103..91934822cf83c923dabeafa5d9559911d184f3ef 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -72,6 +72,8 @@ int Manage_ro(char *devname, int fd, int readonly)
        return 0;                       
 }
 
+#ifndef MDASSEMBLE
+
 int Manage_runstop(char *devname, int fd, int runstop, int quiet)
 {
        /* Run or stop the array. array must already be configured
@@ -104,7 +106,11 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
                                devname, strerror(errno));
                        return 1;
                }
+               if (quiet <= 0)
+                       fprintf(stderr, Name ": started %s\n", devname);
        } else if (runstop < 0){
+               struct map_ent *map = NULL;
+               struct stat stb;
                if (ioctl(fd, STOP_ARRAY, NULL)) {
                        if (quiet==0)
                                fprintf(stderr, Name ": fail to stop array %s: %s\n",
@@ -113,6 +119,16 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
                }
                if (quiet <= 0)
                        fprintf(stderr, Name ": stopped %s\n", devname);
+               if (fstat(fd, &stb) == 0) {
+                       int devnum;
+                       if (major(stb.st_rdev) == MD_MAJOR)
+                               devnum = minor(stb.st_rdev);
+                       else
+                               devnum = -1-(minor(stb.st_rdev)>>6);
+                       map_delete(&map, devnum);
+                       map_write(map);
+                       map_free(map);
+               }
        }
        return 0;
 }
@@ -184,6 +200,8 @@ int Manage_subdevs(char *devname, int fd,
                return 1;
        }
        for (dv = devlist ; dv; dv=dv->next) {
+               unsigned long long ldsize;
+
                if (stat(dv->devname, &stb)) {
                        fprintf(stderr, Name ": cannot find %s: %s\n",
                                dv->devname, strerror(errno));
@@ -200,7 +218,7 @@ int Manage_subdevs(char *devname, int fd,
                                dv->devname, dv->disposition);
                        return 1;
                case 'a':
-                       /* add the device - hot or cold */
+                       /* add the device */
                        st = super_by_version(array.major_version,
                                              array.minor_version);
                        if (!st) {
@@ -219,6 +237,10 @@ int Manage_subdevs(char *devname, int fd,
                        if (array.not_persistent==0)
                                st->ss->load_super(st, tfd, &osuper, NULL);
                        /* will use osuper later */
+                       if (!get_dev_size(tfd, dv->devname, &ldsize)) {
+                               close(tfd);
+                               return 1;
+                       }
                        close(tfd);
 
                        if (array.major_version == 0 &&
@@ -238,6 +260,14 @@ int Manage_subdevs(char *devname, int fd,
 
                        if (array.not_persistent == 0) {
 
+                               /* Make sure device is large enough */
+                               if (st->ss->avail_size(st, ldsize/512) <
+                                   array.size) {
+                                       fprintf(stderr, Name ": %s not large enough to join array\n",
+                                               dv->devname);
+                                       return 1;
+                               }
+
                                /* need to find a sample superblock to copy, and
                                 * a spare slot to use 
                                 */
@@ -301,6 +331,15 @@ int Manage_subdevs(char *devname, int fd,
                                                /* fall back on normal-add */
                                        }
                                }
+                       } else {
+                               /* non-persistent. Must ensure that new drive
+                                * is at least array.size big.
+                                */
+                               if (ldsize/512 < array.size) {
+                                       fprintf(stderr, Name ": %s not large enough to join array\n",
+                                               dv->devname);
+                                       return 1;
+                               }
                        }
                        /* in 2.6.17 and earlier, version-1 superblocks won't
                         * use the number we write, but will choose a free number.
@@ -394,3 +433,4 @@ int Manage_subdevs(char *devname, int fd,
        return 0;
        
 }
+#endif