[PATCH 2/3] FIX: Block array monitoring if any array is under reshape in container

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When reshape is started in container on single array, all other container
members are blocked from monitoring also. After container reassembly
we have to construct the same situation.
Currently array under reshape is blocked only.

To block whole container during reshape we have 2 cases:
  1. first assembled array is not reshaped and second is under reshape
  2. first assembled array not reshaped and second is not under reshape

This patch addresses first case.
  If current array is under reshape, block it. Second not reshaped array
  will be blocked if container has any blocked array.

Signed-off-by: Adam Kwolek <adam.kwolek@xxxxxxxxx>
---

 Assemble.c |   19 +++++++++++++++++--
 Grow.c     |   28 ++++++++++++++++++++++++++++
 mdadm.h    |    2 ++
 msg.c      |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 msg.h      |    1 +
 5 files changed, 100 insertions(+), 2 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index c6aad20..59ce650 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -1526,8 +1526,23 @@ int assemble_container_content(struct supertype *st, int mdfd,
 		if (sysfs_set_array(content, md_get_version(mdfd)) != 0)
 			return 1;
 
-	if (content->reshape_active)
-		block_subarray(content);
+
+	if (st->ss->external) {
+		if (content->reshape_active) {
+			/* Current array in container is under reshape
+			 * block it from monitoring
+			 */
+			block_subarray(content);
+		} else {
+			/* If any previously assembled array is under reshape
+			 * currently assembled array have to be blocked before
+			 * array activation also.
+			 * Check if any array in container is blocked
+			 * and do the same for this one.
+			 */
+			block_array_if_any_is_blocked(st, content);
+		}
+	}
 
 	if (sra)
 		sysfs_free(sra);
diff --git a/Grow.c b/Grow.c
index 4a25165..3e13c8f 100644
--- a/Grow.c
+++ b/Grow.c
@@ -539,6 +539,34 @@ static int check_idle(struct supertype *st)
 	return is_idle;
 }
 
+/* Block currently assembed array if any array in container
+ * is blocked.
+ * Function has to be used during container assembly
+ * to make sure that all arrays in container are blocked
+ * if one is under reshape.
+ * This restores situation when reshape is started when
+ * all container components are blocked.
+ */
+int block_array_if_any_is_blocked(struct supertype *st, struct mdinfo *content)
+{
+	int container_dev = (st->container_dev != NoMdDev
+			     ? st->container_dev : st->devnum);
+	char buf[1024];
+
+	fmt_devname(buf, container_dev);
+
+	if (check_blocked_monitor(buf) > 0) {
+		if (sysfs_get_str(content, NULL, "metadata_version",
+				  buf, 1024) > 0) {
+			buf[9] = '-';
+			sysfs_set_str(content, NULL, "metadata_version", buf);
+		}
+	}
+
+	return 1;
+}
+
+
 static int freeze_container(struct supertype *st)
 {
 	int container_dev = (st->container_dev != NoMdDev
diff --git a/mdadm.h b/mdadm.h
index 8dd37d9..d0ffd4d 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -477,6 +477,8 @@ extern int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume);
 extern int sysfs_disk_to_scsi_id(int fd, __u32 *id);
 extern int sysfs_unique_holder(int devnum, long rdev);
 extern int sysfs_freeze_array(struct mdinfo *sra);
+extern int block_array_if_any_is_blocked(struct supertype *st,
+					 struct mdinfo *content);
 extern int load_sys(char *path, char *buf);
 extern int reshape_prepare_fdlist(char *devname,
 				  struct mdinfo *sra,
diff --git a/msg.c b/msg.c
index 98d6d13..f903afb 100644
--- a/msg.c
+++ b/msg.c
@@ -424,6 +424,58 @@ int block_monitor(char *container, const int freeze)
 	return rv;
 }
 
+/* Function checks if any container member or container itself
+ * is blocked (mdmon is blocked).
+ * It can occur that during assembly process first array in container
+ * is under reshape, this means that any activated array
+ * has to be blocked also, to keep whole container blocked
+ * Returns:
+ * -1: error
+ *  0: not blocked
+ *  1: something is blocked
+ */
+int check_blocked_monitor(char *container)
+{
+	struct mdstat_ent *ent, *e;
+	struct mdinfo *sra = NULL;
+	int rv = 0;
+
+	if (check_mdmon_version(container))
+		return -1;
+
+	ent = mdstat_read(0, 0);
+	if (!ent) {
+		fprintf(stderr, Name
+			": failed to read /proc/mdstat while checking"
+			" if mdmon is disabled\n");
+		return -1;
+	}
+
+	/* check if any container member is frozen */
+	for (e = ent; e; e = e->next) {
+		if (!is_container_member(e, container))
+			continue;
+		sysfs_free(sra);
+		sra = sysfs_read(-1, e->devnum, GET_VERSION);
+		if (!sra) {
+			fprintf(stderr, Name
+				": failed to read sysfs for subarray%s\n",
+				to_subarray(e, container));
+			break;
+		}
+		/* check frozen state */
+		if (sra->text_version[0] == '-') {
+			rv = 1;
+			break;
+		}
+	 }
+
+	sysfs_free(sra);
+	free_mdstat(ent);
+
+	return rv;
+}
+
 void unblock_monitor(char *container, const int unfreeze)
 {
 	struct mdstat_ent *ent, *e;
diff --git a/msg.h b/msg.h
index c6d037d..fb5815e 100644
--- a/msg.h
+++ b/msg.h
@@ -32,6 +32,7 @@ extern int block_subarray(struct mdinfo *sra);
 extern int unblock_subarray(struct mdinfo *sra, const int unfreeze);
 extern int block_monitor(char *container, const int freeze);
 extern void unblock_monitor(char *container, const int unfreeze);
+extern int check_blocked_monitor(char *container);
 extern int fping_monitor(int sock);
 extern int ping_manager(char *devname);
 

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux