]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - msg.c
Grow: failing the set the per-device size is not an error.
[thirdparty/mdadm.git] / msg.c
diff --git a/msg.c b/msg.c
index 7bd85f8154477a6d009ab2bcd9fec9833fa11ab6..44aad1f60f75a18860eef2d96fcb6c361a57341a 100644 (file)
--- a/msg.c
+++ b/msg.c
@@ -207,9 +207,28 @@ int fping_monitor(int sfd)
 int ping_monitor(char *devname)
 {
        int sfd = connect_monitor(devname);
-       int err = fping_monitor(sfd);
+       int err;
+
+       if (sfd >= 0) {
+               err = fping_monitor(sfd);
+               close(sfd);
+       } else
+               err = -1;
+
+       return err;
+}
+
+/* ping monitor using device number */
+int ping_monitor_by_id(int devnum)
+{
+       int err = -1;
+       char *container = devnum2devname(devnum);
+
+       if (container) {
+               err = ping_monitor(container);
+               free(container);
+       }
 
-       close(sfd);
        return err;
 }
 
@@ -235,7 +254,7 @@ static char *ping_monitor_version(char *devname)
        return msg.buf;
 }
 
-static int unblock_subarray(struct mdinfo *sra, const int unfreeze)
+int unblock_subarray(struct mdinfo *sra, const int unfreeze)
 {
        char buf[64];
        int rc = 0;
@@ -255,6 +274,52 @@ static int unblock_subarray(struct mdinfo *sra, const int unfreeze)
        return rc;
 }
 
+int block_subarray(struct mdinfo *sra)
+{
+       char buf[64];
+       int rc = 0;
+
+       sprintf(buf, "external:%s\n", sra->text_version);
+       buf[9] = '-';
+       if (sysfs_set_str(sra, NULL, "metadata_version", buf))
+               rc = -1;
+
+       return rc;
+}
+
+/* check mdmon version if it supports
+ * array blocking mechanism
+ */
+int check_mdmon_version(char *container)
+{
+       char *version = NULL;
+       int devnum = devname2devnum(container);
+
+       if (!mdmon_running(devnum)) {
+               /* if mdmon is not active we assume that any instance that is
+                * later started will match the current mdadm version, if this
+                * assumption is violated we may inadvertantly rebuild an array
+                * that was meant for reshape, or start rebuild on a spare that
+                * was to be moved to another container
+                */
+               /* pass */;
+       } else {
+               int ver;
+
+               version = ping_monitor_version(container);
+               ver = version ? mdadm_version(version) : -1;
+               free(version);
+               if (ver < 3002000) {
+                       fprintf(stderr, Name
+                               ": mdmon instance for %s cannot be disabled\n",
+                               container);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 /**
  * block_monitor - prevent mdmon spare assignment
  * @container - container to block
@@ -276,34 +341,13 @@ static int unblock_subarray(struct mdinfo *sra, const int unfreeze)
  */
 int block_monitor(char *container, const int freeze)
 {
-       int devnum = devname2devnum(container);
        struct mdstat_ent *ent, *e, *e2;
        struct mdinfo *sra = NULL;
-       char *version = NULL;
        char buf[64];
        int rv = 0;
 
-       if (!mdmon_running(devnum)) {
-               /* if mdmon is not active we assume that any instance that is
-                * later started will match the current mdadm version, if this
-                * assumption is violated we may inadvertantly rebuild an array
-                * that was meant for reshape, or start rebuild on a spare that
-                * was to be moved to another container
-                */
-               /* pass */;
-       } else {
-               int ver;
-
-               version = ping_monitor_version(container);
-               ver = version ? mdadm_version(version) : -1;
-               free(version);
-               if (ver < 3002000) {
-                       fprintf(stderr, Name
-                               ": mdmon instance for %s cannot be disabled\n",
-                               container);
-                       return -1;
-               }
-       }
+       if (check_mdmon_version(container))
+               return -1;
 
        ent = mdstat_read(0, 0);
        if (!ent) {
@@ -334,9 +378,7 @@ int block_monitor(char *container, const int freeze)
                 * takeover in reshape case and spare reassignment in the
                 * auto-rebuild case)
                 */
-               sprintf(buf, "external:%s\n", sra->text_version);
-               buf[9] = '-';
-               if (sysfs_set_str(sra, NULL, "metadata_version", buf))
+               if (block_subarray(sra))
                        break;
                ping_monitor(container);
 
@@ -383,7 +425,6 @@ int block_monitor(char *container, const int freeze)
 
        sysfs_free(sra);
        free_mdstat(ent);
-       free(container);
 
        return rv;
 }
@@ -407,6 +448,8 @@ void unblock_monitor(char *container, const int unfreeze)
                        continue;
                sysfs_free(sra);
                sra = sysfs_read(-1, e->devnum, GET_VERSION|GET_LEVEL);
+               if (!sra)
+                       continue;
                if (sra->array.level > 0)
                        to_ping++;
                if (unblock_subarray(sra, unfreeze))
@@ -444,3 +487,13 @@ int ping_manager(char *devname)
        close(sfd);
        return err;
 }
+
+/* using takeover operation for grow purposes, mdadm has to be sure
+ * that mdmon processes all updates, and if necessary it will be closed
+ * at takeover to raid0 operation
+  */
+void flush_mdmon(char *container)
+{
+       ping_manager(container);
+       ping_monitor(container);
+}