]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - Monitor.c
imsm: Remove --dump/--restore implementation
[thirdparty/mdadm.git] / Monitor.c
index 725f47db564e87f4afb4c3cd5cb0f5469034239a..b527165b803acc2eb3a9d84132f44a39f64aeba1 100644 (file)
--- a/Monitor.c
+++ b/Monitor.c
@@ -465,6 +465,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
        int last_disk;
        int new_array = 0;
        int retval;
+       int is_container = 0;
+       unsigned long redundancy_only_flags = 0;
 
        if (test)
                alert("TestMessage", dev, NULL, ainfo);
@@ -475,18 +477,39 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
        if (fd < 0)
                goto disappeared;
 
-       if (!md_array_active(fd))
+       if (st->devnm[0] == 0)
+               strcpy(st->devnm, fd2devnm(fd));
+
+       for (mse2 = mdstat; mse2; mse2 = mse2->next)
+               if (strcmp(mse2->devnm, st->devnm) == 0) {
+                       mse2->devnm[0] = 0; /* flag it as "used" */
+                       mse = mse2;
+               }
+
+       if (!mse) {
+               /* duplicated array in statelist
+                * or re-created after reading mdstat
+                */
+               st->err++;
+               goto out;
+       }
+
+       if (mse->level == NULL)
+               is_container = 1;
+
+       if (!is_container && !md_array_active(fd))
                goto disappeared;
 
        fcntl(fd, F_SETFD, FD_CLOEXEC);
        if (md_get_array_info(fd, &array) < 0)
                goto disappeared;
 
-       if (st->devnm[0] == 0)
-               strcpy(st->devnm, fd2devnm(fd));
+       if (!is_container && map_name(pers, mse->level) > 0)
+               redundancy_only_flags |= GET_MISMATCH;
+
+       sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEVS |
+                       GET_STATE | redundancy_only_flags);
 
-       sra = sysfs_read(-1, st->devnm, GET_LEVEL | GET_DISKS | GET_DEGRADED |
-                        GET_MISMATCH | GET_DEVS | GET_STATE);
        if (!sra)
                goto disappeared;
 
@@ -500,19 +523,6 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
                goto out;
        }
 
-       for (mse2 = mdstat; mse2; mse2 = mse2->next)
-               if (strcmp(mse2->devnm, st->devnm) == 0) {
-                       mse2->devnm[0] = 0; /* flag it as "used" */
-                       mse = mse2;
-               }
-
-       if (!mse) {
-               /* duplicated array in statelist
-                * or re-created after reading mdstat*/
-               st->err++;
-               close(fd);
-               goto out;
-       }
        /* this array is in /proc/mdstat */
        if (array.utime == 0)
                /* external arrays don't update utime, so
@@ -547,7 +557,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
                alert("RebuildStarted", dev, NULL, ainfo);
        if (st->percent >= 0 && mse->percent >= 0 &&
            (mse->percent / increments) > (st->percent / increments)) {
-               char percentalert[15];
+               char percentalert[18];
                /*
                 * "RebuildNN" (10 chars) or "RebuildStarted" (15 chars)
                 */
@@ -653,7 +663,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
  out:
        if (sra)
                sysfs_free(sra);
-       if (fd > 0)
+       if (fd >= 0)
                close(fd);
        return retval;
 
@@ -982,12 +992,21 @@ static void link_containers_with_subarrays(struct state *list)
 int Wait(char *dev)
 {
        char devnm[32];
+       dev_t rdev;
+       char *tmp;
        int rv = 1;
        int frozen_remaining = 3;
 
-       if (!stat_is_blkdev(dev, NULL))
+       if (!stat_is_blkdev(dev, &rdev))
                return 2;
-       strcpy(devnm, dev);
+
+       tmp = devid2devnm(rdev);
+       if (!tmp) {
+               pr_err("Cannot get md device name.\n");
+               return 2;
+       }
+
+       strcpy(devnm, tmp);
 
        while(1) {
                struct mdstat_ent *ms = mdstat_read(1, 0);
@@ -1036,10 +1055,13 @@ int Wait(char *dev)
        }
 }
 
+/* The state "broken" is used only for RAID0/LINEAR - it's the same as
+ * "clean", but used in case the array has one or more members missing.
+ */
 static char *clean_states[] = {
-       "clear", "inactive", "readonly", "read-auto", "clean", NULL };
+       "clear", "inactive", "readonly", "read-auto", "clean", "broken", NULL };
 
-int WaitClean(char *dev, int sock, int verbose)
+int WaitClean(char *dev, int verbose)
 {
        int fd;
        struct mdinfo *mdi;
@@ -1097,7 +1119,8 @@ int WaitClean(char *dev, int sock, int verbose)
                        rv = read(state_fd, buf, sizeof(buf));
                        if (rv < 0)
                                break;
-                       if (sysfs_match_word(buf, clean_states) <= 4)
+                       if (sysfs_match_word(buf, clean_states) <
+                           (int)ARRAY_SIZE(clean_states) - 1)
                                break;
                        rv = sysfs_wait(state_fd, &delay);
                        if (rv < 0 && errno != EINTR)
@@ -1106,15 +1129,16 @@ int WaitClean(char *dev, int sock, int verbose)
                }
                if (rv < 0)
                        rv = 1;
-               else if (fping_monitor(sock) == 0 ||
-                        ping_monitor(mdi->text_version) == 0) {
+               else if (ping_monitor(mdi->text_version) == 0) {
                        /* we need to ping to close the window between array
                         * state transitioning to clean and the metadata being
                         * marked clean
                         */
                        rv = 0;
-               } else
+               } else {
                        rv = 1;
+                       pr_err("Error connecting monitor with %s\n", dev);
+               }
                if (rv && verbose)
                        pr_err("Error waiting for %s to be clean\n", dev);