]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Manage.c
Monitor: fix inconsistencies in values for ->percent
[thirdparty/mdadm.git] / Manage.c
index f53fe276e5bcd9f30fd9f14758c9a24fa1fedfd9..95aa2704bcccae60e3d65b1c2ff1da313a1ec89f 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -416,12 +416,15 @@ int Manage_subdevs(char *devname, int fd,
        int lfd = -1;
        int sysfd = -1;
        int count = 0; /* number of actions taken */
+       struct mdinfo info;
+       int frozen = 0;
 
        if (ioctl(fd, GET_ARRAY_INFO, &array)) {
                fprintf(stderr, Name ": cannot get array info for %s\n",
                        devname);
                goto abort;
        }
+       sysfs_init(&info, fd, 0);
 
        /* array.size is only 32 bit and may be truncated.
         * So read from sysfs if possible, and record number of sectors
@@ -445,7 +448,7 @@ int Manage_subdevs(char *devname, int fd,
                char *dnprintable = dv->devname;
                char *add_dev = dv->devname;
                int err;
-               int re_add_failed = 0;
+               int array_failed;
 
                next = dv->next;
                jnext = 0;
@@ -459,7 +462,7 @@ int Manage_subdevs(char *devname, int fd,
                                        dv->devname, dv->disposition);
                                goto abort;
                        }
-                       for (; j < 1024 && remaining_disks > 0; j++) {
+                       for (; j < MAX_DISKS && remaining_disks > 0; j++) {
                                unsigned dev;
                                disc.number = j;
                                if (ioctl(fd, GET_DISK_INFO, &disc))
@@ -492,7 +495,7 @@ int Manage_subdevs(char *devname, int fd,
                                        dv->devname, dv->disposition);
                                goto abort;
                        }
-                       for (; j < 1024 && remaining_disks > 0; j++) {
+                       for (; j < MAX_DISKS && remaining_disks > 0; j++) {
                                int sfd;
                                unsigned dev;
                                disc.number = j;
@@ -629,6 +632,12 @@ int Manage_subdevs(char *devname, int fd,
                                        dv->devname, strerror(errno));
                                goto abort;
                        }
+                       if (!frozen) {
+                               if (sysfs_freeze_array(&info) == 1)
+                                       frozen = 1;
+                               else
+                                       frozen = -1;
+                       }
 
                        st = dup_super(tst);
 
@@ -657,7 +666,7 @@ int Manage_subdevs(char *devname, int fd,
                                                ": %s is larger than %s can "
                                                "effectively use.\n"
                                                "       Add --force is you "
-                                               "really wan to add this device.\n",
+                                               "really want to add this device.\n",
                                                add_dev, devname);
                                        st->ss->free_super(st);
                                        close(tfd);
@@ -842,9 +851,8 @@ int Manage_subdevs(char *devname, int fd,
                                                                continue;
                                                        goto abort;
                                                }
-                                       skip_re_add:
-                                               re_add_failed = 1;
                                        }
+                               skip_re_add:
                                        st->ss->free_super(st);
                                }
                                if (add_dev != dv->devname) {
@@ -866,12 +874,30 @@ int Manage_subdevs(char *devname, int fd,
                                                dv->devname, devname);
                                        goto abort;
                                }
-                               if (re_add_failed) {
-                                       fprintf(stderr, Name ": %s reports being an active member for %s, but a --re-add fails.\n",
-                                               dv->devname, devname);
-                                       fprintf(stderr, Name ": not performing --add as that would convert %s in to a spare.\n",
-                                               dv->devname);
-                                       fprintf(stderr, Name ": To make this a spare, use \"mdadm --zero-superblock %s\" first.\n",     
+                               if (array.active_disks < array.raid_disks) {
+                                       char *avail = calloc(array.raid_disks, 1);
+                                       int d;
+                                       int found = 0;
+
+                                       for (d = 0; d < MAX_DISKS && found < array.active_disks; d++) {
+                                               disc.number = d;
+                                               if (ioctl(fd, GET_DISK_INFO, &disc))
+                                                       continue;
+                                               if (disc.major == 0 && disc.minor == 0)
+                                                       continue;
+                                               if (!(disc.state & (1<<MD_DISK_SYNC)))
+                                                       continue;
+                                               avail[disc.raid_disk] = 1;
+                                               found++;
+                                       }
+                                       array_failed = !enough(array.level, array.raid_disks, 
+                                                              array.layout, 1, avail);
+                               } else
+                                       array_failed = 0;
+                               if (array_failed) {
+                                       fprintf(stderr, Name ": %s has failed so using --add cannot work and might destroy\n",
+                                               devname);
+                                       fprintf(stderr, Name ": data on %s.  You should stop the array and re-assemble it.\n",
                                                dv->devname);
                                        if (tfd >= 0)
                                                close(tfd);
@@ -1166,11 +1192,15 @@ int Manage_subdevs(char *devname, int fd,
                        break;
                }
        }
+       if (frozen > 0)
+               sysfs_set_str(&info, NULL, "sync_action","idle");
        if (test && count == 0)
                return 2;
        return 0;
 
 abort:
+       if (frozen > 0)
+               sysfs_set_str(&info, NULL, "sync_action","idle");
        return 1;
 }