]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Manage.c
tests: adjust sizes for new defaults
[thirdparty/mdadm.git] / Manage.c
index 594adeffc352fa23bc4d342880bd83ffd9f8a878..f848d8b10b4ce536fcafcadf08126ced919ef105 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -140,7 +140,7 @@ static void remove_devices(int devnum, char *path)
                strcpy(path2, path);
                pe = path2 + strlen(path2);
        } else
-               path = NULL;
+               path2 = path = NULL;
        
        for (part = 0; part < 16; part++) {
                if (part) {
@@ -161,6 +161,7 @@ static void remove_devices(int devnum, char *path)
                                unlink(path2);
                }
        }
+       free(path2);
 }
        
 
@@ -235,11 +236,32 @@ int Manage_runstop(char *devname, int fd, int runstop, int quiet)
                           mdi->array.major_version == -1 &&
                           mdi->array.minor_version == -2 &&
                           !is_subarray(mdi->text_version)) {
+                       struct mdstat_ent *mds, *m;
                        /* container, possibly mdmon-managed.
                         * Make sure mdmon isn't opening it, which
                         * would interfere with the 'stop'
                         */
                        ping_monitor(mdi->sys_name);
+
+                       /* now check that there are no existing arrays
+                        * which are members of this array
+                        */
+                       mds = mdstat_read(0, 0);
+                       for (m=mds; m; m=m->next)
+                               if (m->metadata_version &&
+                                   strncmp(m->metadata_version, "external:", 9)==0 &&
+                                   is_subarray(m->metadata_version+9) &&
+                                   devname2devnum(m->metadata_version+10) == devnum) {
+                                       if (!quiet)
+                                               fprintf(stderr, Name
+                                                       ": Cannot stop container %s: "
+                                                       "member %s still active\n",
+                                                       devname, m->dev);
+                                       free_mdstat(mds);
+                                       if (mdi)
+                                               sysfs_free(mdi);
+                                       return 1;
+                               }
                }
 
                if (fd >= 0 && ioctl(fd, STOP_ARRAY, NULL)) {
@@ -305,24 +327,6 @@ int Manage_resize(char *devname, int fd, long long size, int raid_disks)
        return 0;
 }
 
-int Manage_reconfig(char *devname, int fd, int layout)
-{
-       mdu_array_info_t info;
-       if (ioctl(fd, GET_ARRAY_INFO, &info) != 0) {
-               fprintf(stderr, Name ": Cannot get array information for %s: %s\n",
-                       devname, strerror(errno));
-               return 1;
-       }
-       info.layout = layout;
-       printf("layout set to %d\n", info.layout);
-       if (ioctl(fd, SET_ARRAY_INFO, &info) != 0) {
-               fprintf(stderr, Name ": Cannot set layout for %s: %s\n",
-                       devname, strerror(errno));
-               return 1;
-       }
-       return 0;
-}
-
 int Manage_subdevs(char *devname, int fd,
                   mddev_dev_t devlist, int verbose)
 {
@@ -441,10 +445,22 @@ int Manage_subdevs(char *devname, int fd,
                } else {
                        j = 0;
 
-                       if (stat(dv->devname, &stb)) {
-                               fprintf(stderr, Name ": cannot find %s: %s\n",
-                                       dv->devname, strerror(errno));
-                               return 1;
+                       tfd = dev_open(dv->devname, O_RDONLY);
+                       if (tfd < 0 && dv->disposition == 'r' &&
+                           lstat(dv->devname, &stb) == 0)
+                               /* Be happy, the lstat worked, that is
+                                * enough for --remove
+                                */
+                               ;
+                       else {
+                               if (tfd < 0 || fstat(tfd, &stb) != 0) {
+                                       fprintf(stderr, Name ": cannot find %s: %s\n",
+                                               dv->devname, strerror(errno));
+                                       if (tfd >= 0)
+                                               close(tfd);
+                                       return 1;
+                               }
+                               close(tfd);
                        }
                        if ((stb.st_mode & S_IFMT) != S_IFBLK) {
                                fprintf(stderr, Name ": %s is not a "
@@ -467,7 +483,7 @@ int Manage_subdevs(char *devname, int fd,
                                return 1;
                        }
                        /* Make sure it isn't in use (in 2.6 or later) */
-                       tfd = open(dv->devname, O_RDONLY|O_EXCL|O_DIRECT);
+                       tfd = dev_open(dv->devname, O_RDONLY|O_EXCL|O_DIRECT);
                        if (tfd < 0) {
                                fprintf(stderr, Name ": Cannot open %s: %s\n",
                                        dv->devname, strerror(errno));
@@ -578,7 +594,10 @@ int Manage_subdevs(char *devname, int fd,
                                                        disc.state |= 1 << MD_DISK_WRITEMOSTLY;
                                                if (dv->writemostly == 2)
                                                        disc.state &= ~(1 << MD_DISK_WRITEMOSTLY);
-                                               if (ioctl(fd, ADD_NEW_DISK, &disc) == 0) {
+                                               /* don't even try if disk is marked as faulty */
+                                               errno = 0;
+                                               if ((disc.state & 1) == 0 &&
+                                                   ioctl(fd, ADD_NEW_DISK, &disc) == 0) {
                                                        if (verbose >= 0)
                                                                fprintf(stderr, Name ": re-added %s\n", dv->devname);
                                                        continue;
@@ -591,6 +610,12 @@ int Manage_subdevs(char *devname, int fd,
                                                /* fall back on normal-add */
                                        }
                                }
+                               if (dv->re_add) {
+                                       fprintf(stderr, Name
+                                               ": --re-add for %s to %s is not possible\n",
+                                               dv->devname, devname);
+                                       return 1;
+                               }
                        } else {
                                /* non-persistent. Must ensure that new drive
                                 * is at least array.size big.
@@ -623,7 +648,7 @@ int Manage_subdevs(char *devname, int fd,
                                int dfd;
                                if (dv->writemostly == 1)
                                        disc.state |= 1 << MD_DISK_WRITEMOSTLY;
-                               dfd = open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
+                               dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
                                if (tst->ss->add_to_super(tst, &disc, dfd,
                                                          dv->devname)) {
                                        close(dfd);
@@ -663,6 +688,7 @@ int Manage_subdevs(char *devname, int fd,
                                                disc.state |= (1<<MD_DISK_SYNC);
                                                break;
                                        }
+                               free(used);
                        }
                        if (dv->writemostly == 1)
                                disc.state |= (1 << MD_DISK_WRITEMOSTLY);
@@ -702,6 +728,7 @@ int Manage_subdevs(char *devname, int fd,
                                tst->ss->getinfo_super(tst, &new_mdi);
                                new_mdi.disk.major = disc.major;
                                new_mdi.disk.minor = disc.minor;
+                               new_mdi.recovery_start = 0;
                                if (sysfs_add_disk(sra, &new_mdi, 0) != 0) {
                                        fprintf(stderr, Name ": add new device to external metadata"
                                                " failed for %s\n", dv->devname);